使用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";
}
};