JavaScript寫貪吃蛇
分析:
遊戲中有三個物件:地圖(map), 食物(food), 蛇(snake)
地圖很簡單就是一個div盒子,給樣式即可,蛇,和食物都是屬於地圖中的元素,相對於地圖不斷改變自己的座標值,不要忘了給地圖定位
食物
1,食物的建構函式, 屬性===width,height,backgroundColor,left,top,
2,方法======init()初始化方法, 食物的位置在map中是隨機的,要給 left,top設定隨機值,設定完成後將食物div 追加到map中
值得注意的是:要定義一個數組來儲存食物,寫一個私有函式通過遍歷這個陣列,找到食物div,並將它們從map中移除,同時清空陣列,方便在此使用
蛇
1,蛇的建構函式
屬性====蛇是由一連串的div組成,這些div又分別是物件,它們有width,height,backgroundColor,left,top direction(蛇前進的方向) 將這些小div的樣式放在json資料中,並將json儲存在一個數組snakeBody中,在初始化蛇時,遍歷陣列,獲得小div的樣式json資料包,將這些樣式分別給div,這些div組成一條初始的蛇;
2,方法====init()初始化,遍歷snakeBody陣列,獲得樣式的json資料包,將樣式值給新建立的div,將div追加到map中,小蛇建立成功,
值得注意的是:初始化之前要刪除之前map內的小蛇,跟食物類似,事先建立一個數組,儲存小蛇body的div,寫一個移除小蛇私有函式,遍歷該陣列,找到所有div,將它們從map中移除,並清空陣列,方便下次使用
===move() 讓蛇動起來的方法:除了蛇頭(蛇頭通過改變left,top的值來移動),剩下的組成蛇身體的每個小div的位置等於前面一個div的位置,這樣蛇就移動了. 下面我們來解決蛇頭怎麼動的問題: 蛇頭要根據方向東,通過switch case 語句,判斷對應的方向該往哪裡動一格.
移動的同時要考慮蛇吃到食物,通過判斷食物的位置和蛇頭的座標相同來確定蛇吃到食物,這時向snakBody的樣式json資料的陣列中,新增一個樣式json資料包,讓資料包中的屬性和蛇尾的div的樣式屬性相同即可,然後初始化snake,初始化食物;
遊戲物件:
將前面封裝的物件新增到遊戲物件中
1,建構函式 屬性===food物件,snake物件,map物件
2,方法=====初始化init(); 這個方法主要完成四件事: 初始化food, 初始化snake, 讓蛇動起來, 開啟鍵盤監聽
===讓蛇動起來:要新增定時器,定時器中不斷呼叫snake物件的move方法,和init()方法,這樣蛇就動起來了,什麼時候停止? 蛇撞牆了,什麼是撞牆了? 蛇頭越界, 蛇頭座標小於最小值,或則大於最大值,這時清除定時器,彈出對話方塊,告訴使用者遊戲結束.
===開啟鍵盤監聽:使用者要操作,,改變蛇的移動方向,監聽上下左右鍵,來改變snake物件中direction屬性的值,從而改變蛇的移動方向
所有物件寫完,例項化 物件,呼叫初始化函式,遊戲開始................
程式碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>貪吃蛇</title>
<style>
.map {
width: 800px;
height: 800px;
background-color: #ccc;
margin: 0 auto;
position: relative;
}
</style>
</head>
<body>
<div class="map">
</div>
<script>
//自呼叫====================================================================================== 食物
(function (window) {
var element = [];
function Food(width, height, color, left, top) {
this.width = width || 20;
this.height = height || 20;
this.color = color || 'green';
this.left = left || 0;
this.top = top || 0;
}
//新增初始化方法
Food.prototype.init = function (map) {
console.log('初始化食物');
//初始化,清除陣列中的元素,私有函式,方法外定義
remove();
//建立小盒子元素
var div = document.createElement('div');
//獲得隨機左右值
this.left = Math.floor(Math.random() * map.offsetWidth / this.width) * this.width;
this.top = Math.floor(Math.random() * map.offsetHeight / this.height) * this.height;
//為div新增樣式
div.style.position = 'absolute';
div.style.width = this.width + 'px';
div.style.height = this.height + 'px';
div.style.left = this.left + 'px';
div.style.top = this.top + 'px';
div.style.backgroundColor = this.color;
//追加到地圖中
map.appendChild(div);
//存入陣列中
element.push(div);
};
//清除陣列中的元素,以及map中的小方塊
function remove() {
for (var i = 0; i < element.length; i++) {
var ele = element[i];
//刪除map中的食物
ele.parentElement.removeChild(ele);
//刪除陣列中的元素
element.splice(i, 1);
}
}
//將變數暴露到window中
window.Food = Food;
})(window);
//自呼叫====================================================================================== 小蛇
(function (window) {
var element = [];//陣列儲存蛇
//自定義蛇的建構函式
function Snake(width, height, direction) {
this.width = width || 20;
this.height = height || 20;
this.direction = direction || 'right';
//蛇身體
this.snakeBody = [
{x: 3, y: 2, color: 'red'},
{x: 2, y: 2, color: 'orange'},
{x: 1, y: 2, color: 'orange'}
];
}
//讓小蛇初始化
Snake.prototype.init = function (map) {
console.log('初始化小蛇');
//remove() 移除之前的蛇
remove();
//遍歷陣列為蛇身體的的每一個部分新增樣式
for (var i = 0; i < this.snakeBody.length; i++) {
var div = document.createElement('div');
div.style.width = this.width + 'px';
div.style.height = this.height + 'px';
div.style.left = this.snakeBody[i].x*this.width + 'px';
div.style.top = this.snakeBody[i].y*this.height + 'px';
div.style.backgroundColor = this.snakeBody[i].color;
div.style.position = 'absolute';
//追加到map中
map.appendChild(div);
//新增到陣列中
element.push(div);
}
};
//讓小蛇移動
Snake.prototype.move = function(food,map){
//從蛇尾開始遍歷
var i = this.snakeBody.length - 1;
for (;i>0;i--){
this.snakeBody[i].x = this.snakeBody[i-1].x;
this.snakeBody[i].y = this.snakeBody[i-1].y;
}
//蛇頭運動
switch(this.direction){
case 'top':
this.snakeBody[0].y -= 1;break;
case 'bottom':
this.snakeBody[0].y += 1; break;
case 'left':
this.snakeBody[0].x -= 1; break;
case 'right':
this.snakeBody[0].x += 1;
break;
}
//蛇吃食物,當蛇頭和食物重合時,即蛇吃到食物
//獲得蛇頭座標
var headX = this.snakeBody[0].x*this.width;
// console.log(headX);
var headY = this.snakeBody[0].y*this.height;
// console.log(headY);
if(headX == food.left && headY == food.top){
//向snakeBody陣列中追加一個物件,這個物件的位置和最後一個位置的樣式相同
//獲取身體的最後一個div
console.log("食用");
var last = this.snakeBody[this.snakeBody.length - 1];
this.snakeBody.push({
x:last.x,
y:last.y,
color:last.color
});
//初始化食物
food.init(map);
}
// this.init(map);
};
//私有函式,刪除蛇
function remove() {
var i = element.length - 1;
for (; i >= 0; i--) {
var ele = element[i];
ele.parentElement.removeChild(ele);
element.splice(i, 1);
}
}
//暴露區域性變數
window.Snake = Snake;
})(window);
//自呼叫====================================================================================== 遊戲
(function(window){
//建立遊戲物件
var that = null;
function Game(map){
this.food = new Food(20,20,'black');
this.snake = new Snake();
this.map = map;
that = this;
}
//新增方法初始化遊戲
Game.prototype.init = function(){
this.food.init(this.map);
this.snake.init(this.map);
//小蛇跑起來
this.runSnake(this.food,this.map);
//監聽鍵盤
this.keyDown();
};
//新增runSnake方法
Game.prototype.runSnake = function(food,map){//這裡的food,map是形參 不用this,內部有效
console.log('runSnake呼叫');
var timeId = setInterval(function(){
this.snake.move(food,map);
this.snake.init(map);
//判斷蛇頭撞牆,遊戲結束
var headX = this.snake.snakeBody[0].x*this.snake.width;
var headY = this.snake.snakeBody[0].y*this.snake.height;
var maxX = map.offsetWidth;
var maxY = map.offsetHeight;
if(headX < 0 || headX > maxX){
alert('遊戲結束');
clearInterval(timeId);
}
if(headY < 0 || headY > maxY){
alert('遊戲結束');
clearInterval(timeId);
}
}.bind(that),200)
};
//新增鍵盤監聽
Game.prototype.keyDown = function(){
console.log('keyDown呼叫');
document.addEventListener('keydown',function(e){
switch(e.keyCode){
case 37: this.snake.direction = 'left';break;
case 38: this.snake.direction = 'top';break;
case 39: this.snake.direction = 'right';break;
case 40: this.snake.direction = 'bottom';break;
}
}.bind(that),false)
};
window.Game = Game;
})(window);
//建立遊戲物件
var gm =new Game(document.querySelector('.map'));
//初始化遊戲
gm.init();
//test
// var food = new Food();
// var map = document.querySelector('.map');
// food.init(map); //測試通過
//
// var snake = new Snake(20,20,'right');
// snake.init(map);
// snake.move(food,map);
// setInterval(function(){snake.move(food,map)},100);//定時器內的函式必須是匿名函式
</script>
</body>
</html>