分析:
游戏中有三个对象:地图(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>