做一个简单的贪吃蛇游戏
2024-12-21
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>做一个简单的贪吃蛇游戏</title>
<style>
body {
text-align: center;
font-family: helvetica;
}
canvas {
border: 2px solid rgb(151, 149, 149);
}
</style>
</head>
<body>
<canvas id="stage" height="400" width="520"></canvas>
<script>
/**
* Namespace
*/
var Game = Game || {};
var Keyboard = Keyboard || {};
var Component = Component || {};
/**
* Keyboard Map
*/
Keyboard.Keymap = {
37: 'left',
38: 'up',
39: 'right',
40: 'down',
};
/**
* Keyboard Events
*/
Keyboard.ControllerEvents = function () {
// Setts
var self = this;
this.pressKey = null;
this.keymap = Keyboard.Keymap;
// Keydown Event
document.onkeydown = function (event) {
self.pressKey = event.which;
};
// Get Key
this.getKey = function () {
return this.keymap[this.pressKey];
};
};
/**
* Game Component Stage
*/
Component.Stage = function (canvas, conf) {
// Sets
this.keyEvent = new Keyboard.ControllerEvents();
this.width = canvas.width;
this.height = canvas.height;
this.length = [];
this.food = {};
this.score = 0;
this.direction = 'right';
this.conf = {
cw: 10,
size: 5,
fps: 1000,
};
// Merge Conf
if (typeof conf == 'object') {
for (var key in conf) {
if (conf.hasOwnProperty(key)) {
this.conf[key] = conf[key];
}
}
}
};
/**
* Game Component Snake
*/
Component.Snake = function (canvas, conf) {
// Game Stage
this.stage = new Component.Stage(canvas, conf);
// Init Snake
this.initSnake = function () {
// Itaration in Snake Conf Size
for (var i = 0; i < this.stage.conf.size; i++) {
// Add Snake Cells
this.stage.length.push({ x: i, y: 0 });
}
};
// Call init Snake
this.initSnake();
// Init Food
this.initFood = function () {
// Add food on stage
this.stage.food = {
x: Math.round(
(Math.random() * (this.stage.width - this.stage.conf.cw)) /
this.stage.conf.cw
),
y: Math.round(
(Math.random() * (this.stage.height - this.stage.conf.cw)) /
this.stage.conf.cw
),
};
};
// Init Food
this.initFood();
// Restart Stage
this.restart = function () {
this.stage.length = [];
this.stage.food = {};
this.stage.score = 0;
this.stage.direction = 'right';
this.stage.keyEvent.pressKey = null;
this.initSnake();
this.initFood();
};
};
/**
* Game Draw
*/
Game.Draw = function (context, snake) {
// Draw Stage
this.drawStage = function () {
// Check Keypress And Set Stage direction
var keyPress = snake.stage.keyEvent.getKey();
if (typeof keyPress != 'undefined') {
snake.stage.direction = keyPress;
}
// Draw White Stage
context.fillStyle = 'white';
context.fillRect(0, 0, snake.stage.width, snake.stage.height);
// Snake Position
var nx = snake.stage.length[0].x;
var ny = snake.stage.length[0].y;
// Add position by stage direction
switch (snake.stage.direction) {
case 'right':
nx++;
break;
case 'left':
nx--;
break;
case 'up':
ny--;
break;
case 'down':
ny++;
break;
}
// Check Collision
if (this.collision(nx, ny) == true) {
snake.restart();
return;
}
// Logic of Snake food
if (nx == snake.stage.food.x && ny == snake.stage.food.y) {
var tail = { x: nx, y: ny };
snake.stage.score++;
snake.initFood();
} else {
var tail = snake.stage.length.pop();
tail.x = nx;
tail.y = ny;
}
snake.stage.length.unshift(tail);
// Draw Snake
for (var i = 0; i < snake.stage.length.length; i++) {
var cell = snake.stage.length[i];
this.drawCell(cell.x, cell.y);
}
// Draw Food
this.drawCell(snake.stage.food.x, snake.stage.food.y);
// Draw Score
context.fillText(
'Score: ' + snake.stage.score,
5,
snake.stage.height - 5
);
};
// Draw Cell
this.drawCell = function (x, y) {
context.fillStyle = 'rgb(170, 170, 170)';
context.beginPath();
context.arc(
x * snake.stage.conf.cw + 6,
y * snake.stage.conf.cw + 6,
4,
0,
2 * Math.PI,
false
);
context.fill();
};
// Check Collision with walls
this.collision = function (nx, ny) {
if (
nx == -1 ||
nx == snake.stage.width / snake.stage.conf.cw ||
ny == -1 ||
ny == snake.stage.height / snake.stage.conf.cw
) {
return true;
}
return false;
};
};
/**
* Game Snake
*/
Game.Snake = function (elementId, conf) {
// Sets
var canvas = document.getElementById(elementId);
var context = canvas.getContext('2d');
var snake = new Component.Snake(canvas, conf);
var gameDraw = new Game.Draw(context, snake);
// Game Interval
setInterval(function () {
gameDraw.drawStage();
}, snake.stage.conf.fps);
};
/**
* Window Load
*/
window.onload = function () {
var snake = new Game.Snake('stage', { fps: 100, size: 4 });
};
</script>
</body>
</html>

