typora-copy-images-to: media
贪吃蛇
从贪吃蛇的游戏中,不难看出,整个游戏分3个对象组成,分别是地图、食物、蛇
工具类函数:
// 设置样式的函数
function setStyle(ele,styleObj){
for(var attr in styleObj){
ele.style[attr] = styleObj[attr];
}
}
// 随机数函数
function getRandom(a,b){
var max = a;
var min = b;
if(a<b){
max = b;
min = a;
}
return Math.floor(Math.random()*(max-min))+min;
}
地图:
// 地图对象
function Map(){
this.map = document.createElement("div");
setStyle(this.map,{
width:'800px',
height:'500px',
border:'10px solid #000',
backgroundColor:'#ccc',
position:'relative'
});
document.body.appendChild(this.map);
}
var map = new Map();
地图显示效果:
地图显示 |
食物:
// 食物对象
function Food(){
this.food = document.createElement("div");
var foodLeft = Math.floor(getRandom(0,map.map.clientWidth-10)/10)*10;
var foodTop = Math.floor(getRandom(0,map.map.clientHeight-10)/10)*10;
setStyle(this.food,{
width:'10px',
height:'10px',
backgroundColor:'#0f0',
position:'absolute',
left:foodLeft + 'px',
top:foodTop + 'px',
});
map.map.appendChild(this.food);
}
var food = new Food();
食物显示效果:
食物显示 |
蛇:
// 蛇
function Snake(){
// 蛇的属性:身体、移动方向
this.body = [
{
x:0,
y:0,
},
{
x:10,
y:0
},
{
x:20,
y:0
}
];
this.direction = 'right';
// 调用方法
// 显示身体
this.showBody();
// 改变方向
this.changeDirection();
}
蛇的方法:显示身体、改变方向、根据方向移动身体、吃食物、死亡
// 显示身体
Snake.prototype.showBody = function(){
// 判断是否有蛇在显示,如果有就先删除再显示,如果没有就直接显示
var snakes = document.querySelectorAll('.snake');
if(snakes.length){
for(var i=0;i<snakes.length;i++){
map.map.removeChild(snakes[i]);
}
}
for(var i=0;i<this.body.length;i++){
var div = document.createElement("div");
div.className = 'snake';
setStyle(div,{
width:'10px',
height:'10px',
background:'#00f',
position:'absolute',
left:this.body[i].x + 'px',
top:this.body[i].y + 'px',
});
if(i==this.body.length-1){
div.style.borderRadius = '50%';
div.style.backgroundColor = '#f00';
}
map.map.appendChild(div);
}
}
// 改变移动方向
Snake.prototype.changeDirection = function(){
window.onkeypress = e=>{
var e = e || window.event;
var keycode = e.keyCode || e.which;
var key = String.fromCharCode(keycode);
switch(key.toLowerCase()){
case 'w':
this.direction = 'up';
break;
case 's':
this.direction = 'down';
break;
case 'a':
this.direction = 'left';
break;
case 'd':
this.direction = 'right';
}
}
}
// 根据方向移动身体
Snake.prototype.moveBody = function(){
// 处理蛇的身体
for(var i=0;i<this.body.length-1;i++){
this.body[i].x = this.body[i+1].x
this.body[i].y = this.body[i+1].y
}
// 根据方向设置蛇头
switch(this.direction){
case 'up':
this.body[this.body.length-1].y -= 10
break;
case 'down':
this.body[this.body.length-1].y += 10
break;
case 'left':
this.body[this.body.length-1].x -= 10
break;
case 'right':
this.body[this.body.length-1].x += 10
}
// 重新显示身体
this.showBody()
// 移动过程中吃食物
this.eatFood()
// 移动过程中可能死亡
this.die()
}
// 吃食物
Snake.prototype.eatFood = function(){
if(this.body[this.body.length-1].x === food.food.offsetLeft && this.body[this.body.length-1].y === food.food.offsetTop){
map.map.removeChild(food.food);
food = new Food();
var newBody = Object.assign({},this.body[0]);
this.body.unshift(newBody);
}
}
// 死亡
Snake.prototype.die = function(){
// 将蛇头定义起来
var head = this.body[this.body.length-1];
// 撞墙
if(head.x<0 || head.y<0 || head.x>map.map.clientWidth-10 || head.y>map.map.clientHeight-10){
alert("GAME OVER!!!");
clearInterval(this.timerId)
}
// 撞身体
for(var i=0;i<this.body.length-1;i++){
if(head.x === this.body[i].x && head.y === this.body[i].y){
alert("GAME OVER!!!");
clearInterval(this.timerId)
}
}
}
// 初始化方法 - 开始游戏
Snake.prototype.init = function(){
// 不停的根据方向移动身体
this.timerId = setInterval(()=>{
this.moveBody()
},200);
}
调用:
var snake = new Snake();
snake.init()
游戏效果:
游戏效果 |
处理死亡后的超出:
修改移动方法
// 根据方向移动身体
Snake.prototype.moveBody = function(){
// 在蛇的身体未移动之前,先将身体深克隆一份
var oldBody = JSON.parse(JSON.stringify(this.body));
// 处理蛇的身体
for(var i=0;i<this.body.length-1;i++){
this.body[i].x = this.body[i+1].x
this.body[i].y = this.body[i+1].y
}
// 根据方向设置蛇头
switch(this.direction){
case 'up':
this.body[this.body.length-1].y -= 10
break;
case 'down':
this.body[this.body.length-1].y += 10
break;
case 'left':
this.body[this.body.length-1].x -= 10
break;
case 'right':
this.body[this.body.length-1].x += 10
}
// 移动过程中可能死亡 - 先判断死亡再显示新的身体
this.die(oldBody) // 将死亡之前的身体传入死亡方法
// 重新显示身体
this.showBody()
// 移动过程中吃食物
this.eatFood()
}
修改死亡方法:
// 死亡
Snake.prototype.die = function(oldBody){ // 接收蛇死亡之前的身体
// 将蛇头定义起来
var head = this.body[this.body.length-1];
// 撞墙
if(head.x<0 || head.y<0 || head.x>map.map.clientWidth-10 || head.y>map.map.clientHeight-10){
this.body = oldBody // 将蛇的身体退回到死亡之前
alert("GAME OVER!!!");
clearInterval(this.timerId)
}
// 撞身体
for(var i=0;i<this.body.length-1;i++){
if(head.x === this.body[i].x && head.y === this.body[i].y){
this.body = oldBody // 将蛇的身体退回到死亡之前
alert("GAME OVER!!!");
clearInterval(this.timerId)
}
}
}