使用Js面向对象的思想设计了一个贪吃蛇游戏,算是对Js面向对象的总结吧.
地图设计
地图绘制直接使用js绘制div区域,然后填充背景即可.
/**
* 游戏地图
* @constructor
*/
function Map(width, height) {
this.width = width;
this.height = height;
this.showMap = function () {
// 创建地图元素
var map = document.createElement('div');
map.style.width = width;
map.style.height = height;
map.style.backgroundColor = 'pink';
map.style.backgroundImage = 'url(./bg.jpg)';
document.body.appendChild(map);
}
}
食物设计
食物的出现用Js产生的随机数决定,这里代码比较简单,就不考虑生成到蛇身的情况了.
/**
* 贪吃蛇食物
* @constructor
*/
function Food() {
var size = 20;
// 初始食物坐标
this.x = 0;
this.y = 0;
// 食物信息
this.piece = null;
this.showFood = function () {
if (this.piece == null) {
this.piece = document.createElement('div');
this.piece.style.width = this.piece.style.height = size + 'px';
this.piece.style.backgroundColor = 'green';
this.piece.style.position = 'absolute';
document.body.appendChild(this.piece);
}
// Math.floor()对浮点数进行向下取整
this.x = Math.floor(Math.random() * 40);
this.y = Math.floor(Math.random() * 20);
log('food x: ' + this.x);
log('food y: ' + this.y);
this.piece.style.left = this.x * size + 'px';
this.piece.style.top = this.y * size + 'px';
}
}
蛇的设计
蛇由多个dom节点一起绘制,这里我们使用数组进行表示,如果蛇吃了食物,这个数组的长度会增加.
/**
* 蛇
* @constructor
*/
function Snake() {
var size = 20; // 大小
// 蛇的身体
this.snakeBody = [
[0, 1, 'green', null],
[1, 1, 'green', null],
[2, 1, 'green', null],
[3, 1, 'red', null]
];
this.redirect = 'right';
this.showSnake = function () {
for (var i = 0; i < this.snakeBody.length; i++) {
// 追加节点
if (this.snakeBody[i][3] === null) {
this.snakeBody[i][3] = document.createElement('div');
this.snakeBody[i][3].style.width = this.snakeBody[i][3].style.height = size + 'px';
this.snakeBody[i][3].style.backgroundColor = this.snakeBody[i][2];
this.snakeBody[i][3].style.position = 'absolute';
document.body.appendChild(this.snakeBody[i][3]);
}
this.snakeBody[i][3].style.left = this.snakeBody[i][0] * size + 'px';
this.snakeBody[i][3].style.top = this.snakeBody[i][1] * size + 'px';
}
};
// 移动小蛇
this.move = function () {
moveBody.call(this);
moveHead.call(this);
var snakeX = this.snakeBody[this.snakeBody.length - 1][0];
var snakeY = this.snakeBody[this.snakeBody.length - 1][1];
log('#move ' + food.x + ' ' + food.y);
if (snakeX == food.x && snakeY == food.y) {
var block = [this.snakeBody[0][0], this.snakeBody[0][1], 'green', null];
this.snakeBody.unshift(block);
food.showFood();
}
if (snakeX < 0 || snakeX > 39 || snakeY < 0 || snakeY > 19) {
alert("Game Over");
clearInterval(time);
return false;
}
for (var k = 0; k < this.snakeBody.length - 1; k++) {// 遍历非蛇头蛇节坐标
if (snakeX == this.snakeBody[k][0] && snakeY == this.snakeBody[k][1]) {
alert('Game over, kill you by yourself');
clearInterval(time);
return false;
}
}
this.showSnake();
};
/**
* 移动蛇身
*/
function moveBody() {
// 蛇身部分向上个坐标移动.
for (var n = 0; n < this.snakeBody.length - 1; n++) {
this.snakeBody[n][0] = this.snakeBody[n + 1][0];
this.snakeBody[n][1] = this.snakeBody[n + 1][1];
}
}
/**
* 移动蛇头
*/
function moveHead() {
// 蛇头部分单独处理
var headIndex = this.snakeBody.length - 1;
switch (this.redirect) {
case 'right':
this.snakeBody[headIndex][0] += 1;
break;
case 'left':
this.snakeBody[headIndex][0] -= 1;
break;
case 'down':
this.snakeBody[headIndex][1] += 1;
break;
case 'up':
this.snakeBody[headIndex][1] -= 1;
break;
default:
throw new TypeError();
}
}
}
代码调用
先绘制地图,然后绘制食物和蛇,随后使用定时器不断让蛇进行移动,移动的同时,不断进行检查位置是否合法,如果位置已经超出边界或者处于蛇身,那么宣告游戏结束.
// 绘制地图
map = new Map('800px', '400px');
map.showMap();
// 创建食物
food = new Food();
food.showFood();
snake = new Snake();
snake.showSnake();
snake.move();
time = setInterval("snake.move()", 200);
document.onkeydown = function (evt) {
var num = evt.keyCode;
if (num == 40) {
snake.redirect = "down";
}
if (num == 38) {
snake.redirect = "up";
}
if (num == 37) {
snake.redirect = "left";
}
if (num == 39) {
snake.redirect = "right";
}
};