程序设计分为:html&css部分和kjs部分:
- 在html中设置两个div,一个作为项目的背景,另一个记录得分
- 定义一些初始的参数,比如蛇的长度,大小,食物的大小,蛇的位置,初始得分
- 构造启动函数,创建食物和蛇,设置定时器,让蛇动起来
- 定义逻辑结构,触碰边界弹出游戏结束,清除蛇和食物,触屏身体游戏结束,吃到食物长度加1
设置背景
<div class="score">
//记录得分
<span>0</span>
</div>
<div class="background" style="width:600px,height:600px ">
</div>
可以给2个div标签设置一个边框,背景图片,来美化。
定义初始值
init()
//用this就可以直接将值传入本函数中的所有函数中,相当于向函数中加入参数,只是为了简便
function init() {
//背景
this.backX=$('.background').width();
this.backY=$('.background').height();
//食物
this.foodW = 20;//食物宽
this.foodH = 20;//食物高
this.foodX = 0;//初始横坐标
this.foodY = 0;//初始纵坐标
this.snake = [[4,1,'head'],[3,1,'body'],[2,1,'body']]//初始蛇
this.direct = 'right' //蛇的初始方向
//逻辑结构
this.left = false;
this.up = true;
this.down = true;
this.right = false;
this.score = 0;//初始分数
startGame() //开始游戏函数可以不放在这里,可以在div中创建一个开始框,绑定点击事件
}
构造函数
启动函数里分为蛇函数,食物函数,定时器
function startGame() {
food();
snakeCreate();
this.obj = setInterval(move,200);
}
食物函数
function food() {
var $food=$('<div>')
//Math.floor()向下取最大整数,例如Math.floor(4.5)返回4,Math.random()随机生成一个0到1之间的数。
this.foodX=Math.floor(Math.random()*this.backX/20);//随机创造食物的横坐标
this.foodY=Math.floor(Math.random()*this.backY/20);//随机创造食物的纵坐标
//给食物添加css属性,进行定位,添加宽高
$food.css('width',this.foodW+'px');
$food.css('height',this.foodH+'px');
$food.css('position','absolute');
$food.css('left',this.foodX*20 + 'px');
$food.css('top',this.foodY*20 + 'px');
$food.css('background-color','red');
$food.addClass('food')
$('.background').append($food)
}
蛇函数
function snakeCreate() {
//蛇函数通过数组来进行拼接,构造3个div框,依次拼接在一起,数组里套数组,分别代表蛇的横纵坐标
for (var i = this.snake.length - 1; i >= 0; i--) {
var $snake = $('<div>');
$snake.css({'background-color':'blue','position':'absolute','width':'20px','height':'20px','left':this.snake[i][0]*20+'px','top':this.snake[i][1]*20+'px'})
$snake.addClass('snake')
$('.background').append($snake)
if(this.snake[i][2] == 'head'){
$snake.addClass('snakeHead')
}
}
逻辑函数
如何让蛇动起来,只要依次将蛇数组中的每一个前面的横纵坐标赋值给后一个,再加上定时器,就可以实现蛇的运动。判断逻辑也写在move函数中,全部通过蛇头来进行判断,当蛇头的横纵坐标和边框以及食物的横纵坐标进行比较,创建循环,让蛇头每次都和蛇身体的横纵坐标对比,如果蛇头碰到身体也结束。当然也要在函数中增加监听键盘事件,当按下键盘的上下左右键时,要做出对应的操作。吃到食物后的增加蛇身体逻辑也值得考究。
每次想要创造蛇身体时,就必须清除上一次的蛇的身体,所以在构造蛇函数时,给蛇加上类名,方便jquery选择器选到蛇进行清除。
function move() {
for (var i = this.snake.length - 1; i > 0; i--) {
this.snake[i][0] = this.snake[i-1][0];
this.snake[i][1] = this.snake[i-1][1];
}
switch(this.direct){
case 'right':
this.snake[0][0] += 1;
break;
case 'left':
this.snake[0][0] -= 1;
break;
case 'up':
this.snake[0][1] -= 1;
break;
case 'down':
this.snake[0][1] += 1;
break;
default:
break;
}
//绑定键盘事件
//keyCode 37 = Left
// keyCode 38 = Up
// keyCode 39 = Right
// keyCode 40 = Down
document.onkeydown = function(event){
var keycode = event.keyCode;
direction(keycode)
}
$('.snake').remove()
snakeCreate()
if(this.snake[0][0] < 0 || this.snake[0][1] < 0 || this.snake[0][0] >= this.backX/20 || this.snake[0][1] >= this.backY/20){
alert('gameover')
clearInterval(this.obj)
$('.snake').remove()
$('.food').remove()
}if(this.snake[0][0] == this.foodX && this.snake[0][1] == this.foodY){
$('.food').remove()
food()
appendBody()
$('.snake').remove()
snakeCreate()
this.score += 1;
$('.score').find('span').text(this.score)
}
for(var j = 1; j < this.snake.length; j++){
if(this.snake[0][0] == this.snake[j][0] && this.snake[0][1] == this.snake[j][1]){
alert('gameover')
clearInterval(this.obj)
$('.snake').remove()
$('.food').remove()
}
}
}
判断蛇的方向的函数我们单独拿出来写,当按下左方向键时,我们要让下次事件不再接收左右的按键,只接受上下,通过初始设置来实现这个操作。
unction direction(keycode){
switch(keycode){
case 37:
if(this.left){
this.direct = 'left'
this.left = false;
this.up = true;
this.down = true;
this.right = false;
};
break;
case 38:
if(this.up){
this.direct = 'up'
this.left = true;
this.up = false;
this.down = false;
this.right = true;
};
break;
case 39:
if(this.right){
this.direct = 'right'
this.left = false;
this.up = true;
this.down = true;
this.right = false;
};
break;
case 40:
if(this.up){
this.direct = 'down'
this.left = true;
this.up = false;
this.down = false;
this.right = true;
};
break;
default:break;
}
}
吃到食物的增加逻辑确实值得深思,不同的情况要考虑周全,这里只做了简单的一些逻辑判断,根据蛇头的方向,来进行简单添加下一个蛇身体。
unction appendBody(){
var i = this.snake.length
switch (this.direct){
case 'right':
if(this.snake[i-1][0] >= 1 && this.snake[i-1][0]-1 != this.snake[i-2][0]){
this.snake.push([this.snake[i-1][0]-1,this.snake[i-1][1],'body']);
}else{
this.snake.push([this.snake[i-1][0],this.snake[i-1][1]+1,'body'])
};
break;
case 'left':
if(this.snake[i-1][0] <= this.backX/20-1 && this.snake[i-1][0]+1 != this.snake[i-2][0]){
this.snake.push([this.snake[i-1][0]+1,this.snake[i-1][1],'body']);
}else{
this.snake.push([this.snake[i-1][0],this.snake[i-1][1]+1,'body'])
};
break;
case 'up':
if(this.snake[i-1][1] <= this.backY/20-1 && this.snake[i-1][1]+1 != this.snake[i-2][1]){
this.snake.push([this.snake[i-1][0],this.snake[i-1][1]+1,'body']);
}else{
this.snake.push([this.snake[i-1][0]-1,this.snake[i-1][1],'body']);
};
break;
case 'down':
if(this.snake[i-1][1] >= 1 && this.snake[i-1][1]-1 != this.snake[i-2][1]){
this.snake.push([this.snake[i-1][0],this.snake[i-1][1]-1,'body']);
}else{
this.snake.push([this.snake[i-1][0]-1,this.snake[i-1][1],'body']);
};
break;
default:break;
}
}
这样一个简单的贪吃蛇就完成了。当然可以在里面添加图片,按钮使得画面更生动。