面向对象编程
贪食蛇总共分为三个部分:
- 食物
- 蛇
- 游戏
一、食物
1、封装食物对象
- 将食物的特征全部封装起来,食物的初始坐标,宽高以及颜色
function Food(opt){
//设置默认值
opt = opt || {};
opt.x = opt.x || 0;
opt.y = opt.y || 0;
opt.width = opt.width || 20;
opt.height = opt.height || 20;
opt.color = opt.color || "green";
//设置属性
this.x = opt.x;
this.y = opt.y;
this.width = opt.width;
this.height = opt.height;
this.color = opt.color;
this.init();
}
2、添加食物初始化方法
- 将食物生成到页面上
Food.prototype.init = function(){
var element = document.createElement("div");
this.element = element;
//设置元素
element.style.width = this.width + "px";
element.style.height = this.height + "px";
element.style.backgroundColor = this.color;
element.style.position = "absolute";
};
3、添加食物随机位置的方法
- 旧的食物被吃掉的同时又会重新生成新的食物
//设置随机数
function random(n,m){
return Math.floor(Math.random()*(m-n+1)+n);
}
Food.prototype.render = function(map){
this.x = random(0,map.clientWidth/this.width-1)*this.width;
this.y = random(0,map.clientHeight/this.height-1)*this.height;
this.element.style.left = this.x + "px";
this.element.style.top = this.y + "px";
map.appendChild(this.element);
};
4、设置食物消失的方法
- 蛇头吃到食物,食物就会消失
Food.prototype.remove = function(){
var father = this.element.parentNode;
father.removeChild(this.element);
};
二、蛇
1、创建蛇对象
- 将蛇头和蛇身的特征全部封装起来,蛇头的宽高、初始方向颜色,蛇身的宽高颜色
function Snake(opt){
//设置默认值
opt = opt || {};
opt.width = opt.width || 20;
opt.height = opt.height || 20;
opt.direction = opt.direction || Direction.RIGHT;
//设置属性
this.width = opt.width;
this.height = opt.height;
this.direction = opt.direction;
this.body = [
{x:60,y:20,color:"red"},
{x:40,y:20,color:"green"},
{x:20,y:20,color:"green"}
];
}
2、添加蛇初始化的方法
Snake.prototype.init = function(map){
//创建元素
this.elements = [];
for(var i=0;i< this.body.length;i++){
var element = document.createElement("div");
map.appendChild(element);
this.elements.push(element);
//设置元素
element.style.width = this.width + "px";
element.style.height = this.height + "px";
element.style.backgroundColor = this.body[i].color;
element.style.position = "absolute";
element.style.left = this.body[i].x + "px";
element.style.top = this.body[i].y + "px";
}
}
3、添加一个蛇移动的方法
var Direction = Object.create({},{
"TOP": {
value: 0,
writable: false,
enumerable: false,
configurable: false
},
"RIGHT": {
value: 1,
writable: false,
enumerable: false,
configurable: false
},
"BOTTOM": {
value: 2,
writable: false,
enumerable: false,
configurable: false
}, "LEFT": {
value: 3,
writable: false,
enumerable: false,
configurable: false
}
});
Snake.prototype.move = function(){
//蛇身体移动位置
for(var i=this.body.length-1;i>0;i--){
this.body[i].x = this.body[i-1].x ;
this.body[i].y = this.body[i-1].y ;
//设置回元素上
this.elements[i].style.left = this.body[i].x + "px";
this.elements[i].style.top = this.body[i].y + "px";
}
//蛇头移动位置
switch (this.direction){
case Direction.TOP:
this.body[0].y -= this.height;
break;
case Direction.RIGHT:
this.body[0].x += this.width;
break;
case Direction.BOTTOM:
this.body[0].y += this.height;
break;
case Direction.LEFT:
this.body[0].x -= this.width;
break;
}
//设置蛇头对应的元素
this.elements[0].style.left = this.body[0].x + "px";
this.elements[0].style.top = this.body[0].y + "px";
};
4、设置一个蛇尾加长的方法
- 蛇每次吃到食物蛇尾就会增加一节
Snake.prototype.growth = function(){
//蛇尾加一节
var last = this.body[this.body.length-1];
var newLast = {
x:last.x,
y:last.y,
color:last.color
};
this.body.push(newLast);
//设置最后一节对应的元素
var element = document.createElement("div");
map.appendChild(element);
this.elements.push(element);
//设置元素
element.style.width = this.width + "px";
element.style.height = this.height + "px";
element.style.backgroundColor = newLast.color;
element.style.position = "absolute";
element.style.left = newLast.x + "px";
element.style.top = newLast.y + "px";
};
三、创建游戏
1、添加一个开始游戏的方法
Game.prototype.start = function(){
//设置一个定时器
this.timer = setInterval(function(){
this.snake.move();
//判断蛇的移动范围
var head = this.snake.body[0];
var maxX = this.map.clientWidth - this.food.width;
var maxY = this.map.clientHeight - this.food.height;
if(head.x<0 || head.x> maxX || head.y<0 || head.y>maxY){
alert("Game Over!");
clearInterval(this.timer);
}
//处理蛇吃食物的情况,蛇头的坐标与食物坐标一致
if(head.x == this.food.x && head.y == this.food.y){
//1.食物消失
this.food.remove();
//2.生成新的食物
this.food = new Food();
this.food.render(this.map);
//3.蛇尾加长
this.snake.growth(this.map);
}
}.bind(this),100)
};
2、创建键盘操控游戏事件
- 利用上下左右键来操控蛇的方向
Game.prototype.keyCode = function(){
//注册键盘按下事件
document.addEventListener("keydown",function(e){
switch (e.keyCode){
case 37:
this.snake.direction = window.Direction.LEFT;
break;
case 38:
this.snake.direction = window.Direction.TOP;
break;
case 39:
this.snake.direction = window.Direction.RIGHT;
break;
case 40:
this.snake.direction = window.Direction.BOTTOM;
break;
}
}.bind(this),false)
};
四、完整代码
1、HTML代码
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
.map {
width: 800px;
height: 600px;
background-color: #000;
margin: 0 auto;
position: relative;
}
#begin{
position: fixed;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div class="map"></div>
<input type="button" value="开始游戏" id="begin"/>
<--引入封装好的js代码-->
<script src="Game.js"></script>
<script>
var map = document.querySelector(".map");
var btn = document.querySelector("#begin");
var game = new Game(map);
btn.onclick = function(){
game.start();
}
</script>
</body>
</html>
2、封装好的js代码
- 利用沙箱模式,保护代码不被污染
;(function(window,document){
function random(n,m){
return Math.floor(Math.random()*(m-n+1)+n);
}
function Food(opt){
opt = opt || {};
opt.x = opt.x || 0;
opt.y = opt.y || 0;
opt.width = opt.width || 20;
opt.height = opt.height || 20;
opt.color = opt.color || "green";
this.x = opt.x;
this.y = opt.y;
this.width = opt.width;
this.height = opt.height;
this.color = opt.color;
this.init();
}
Food.prototype.init = function(){
var element = document.createElement("div");
this.element = element;
element.style.width = this.width + "px";
element.style.height = this.height + "px";
element.style.backgroundColor = this.color;
element.style.position = "absolute";
};
Food.prototype.render = function(map){
this.x = random(0,map.clientWidth/this.width-1)*this.width;
this.y = random(0,map.clientHeight/this.height-1)*this.height;
this.element.style.left = this.x + "px";
this.element.style.top = this.y + "px";
map.appendChild(this.element);
};
window.Food = Food;
})(window,document);
(function(window,document){
var Direction = Object.create({},{
"TOP": {
value: 0,
writable: false,
enumerable: false,
configurable: false
},
"RIGHT": {
value: 1,
writable: false,
enumerable: false,
configurable: false
},
"BOTTOM": {
value: 2,
writable: false,
enumerable: false,
configurable: false
}, "LEFT": {
value: 3,
writable: false,
enumerable: false,
configurable: false
}
});
function Snake(opt){
opt = opt || {};
opt.width = opt.width || 20;
opt.height = opt.height || 20;
opt.direction = opt.direction || Direction.RIGHT;
this.width = opt.width;
this.height = opt.height;
this.direction = opt.direction;
this.body = [
{x:60,y:20,color:"red"},
{x:40,y:20,color:"green"},
{x:20,y:20,color:"green"}
];
}
Snake.prototype.init = function(map){
this.elements = [];
for(var i=0;i< this.body.length;i++){
var element = document.createElement("div");
map.appendChild(element);
this.elements.push(element);
element.style.width = this.width + "px";
element.style.height = this.height + "px";
element.style.backgroundColor = this.body[i].color;
element.style.position = "absolute";
element.style.left = this.body[i].x + "px";
element.style.top = this.body[i].y + "px";
}
};
Snake.prototype.move = function(){
for(var i=this.body.length-1;i>0;i--){
this.body[i].x = this.body[i-1].x ;
this.body[i].y = this.body[i-1].y ;
this.elements[i].style.left = this.body[i].x + "px";
this.elements[i].style.top = this.body[i].y + "px";
}
switch (this.direction){
case Direction.TOP:
this.body[0].y -= this.height;
break;
case Direction.RIGHT:
this.body[0].x += this.width;
break;
case Direction.BOTTOM:
this.body[0].y += this.height;
break;
case Direction.LEFT:
this.body[0].x -= this.width;
break;
}
this.elements[0].style.left = this.body[0].x + "px";
this.elements[0].style.top = this.body[0].y + "px";
};
Snake.prototype.growth = function(){
var last = this.body[this.body.length-1];
var newLast = {
x:last.x,
y:last.y,
color:last.color
};
this.body.push(newLast);
var element = document.createElement("div");
map.appendChild(element);
this.elements.push(element);
element.style.width = this.width + "px";
element.style.height = this.height + "px";
element.style.backgroundColor = newLast.color;
element.style.position = "absolute";
element.style.left = newLast.x + "px";
element.style.top = newLast.y + "px";
};
window.Snake = Snake;
window.Direction = Direction;
})(window,document);
(function(window,document){
function Game(map){
this.map = map;
this.food = new Food();
this.food.render(this.map);
this.snake = new Snake();
this.snake.init(this.map);
this.keyCode();
}
Game.prototype.start = function(){
this.timer = setInterval(function(){
this.snake.move();
var head = this.snake.body[0];
var maxX = this.map.clientWidth - this.food.width;
var maxY = this.map.clientHeight - this.food.height;
if(head.x<0 || head.x> maxX || head.y<0 || head.y>maxY){
alert("Game Over!");
clearInterval(this.timer);
}
if(head.x == this.food.x && head.y == this.food.y){
this.food.remove();
this.food = new Food();
this.food.render(this.map);
this.snake.growth(this.map);
}
}.bind(this),100)
};
Game.prototype.keyCode = function(){
document.addEventListener("keydown",function(e){
switch (e.keyCode){
case 37:
this.snake.direction = window.Direction.LEFT;
break;
case 38:
this.snake.direction = window.Direction.TOP;
break;
case 39:
this.snake.direction = window.Direction.RIGHT;
break;
case 40:
this.snake.direction = window.Direction.BOTTOM;
break;
}
}.bind(this),false)
};
window.Game = Game;
})(window,document);