今天想把一个小游戏分享给大家,那就是贪吃蛇
我想应该没有人会未曾玩过吧
其实我这个人也很懒写教程,但本着人人为我,我为人人的精神和自己
以前学javascript的路途如此艰辛和看了这么多人用javascript写游戏
却没有人认真的写过一个教程,都是把代码拿上来就算,这样让初学者看的
很辛苦和教程一点意思都没有
所以本教程确定先不放源码上来,先把思路给大家
先上图吧

大家可以看到玩这个游戏不外符有三样东西,一个是蛇,食物,同地图
就这样简单
好了,我们再分析一下游戏有什么规则,其实自己以前都没想这么多
但实现起来才发觉这个东西挺重要的
1,蛇不能碰自己,也就是蛇的头不能和自己的身体接触,还有不能碰墙
不然就game over
2,,蛇在运动的时候如果方向是向左的话就不能向右,如果是向下的话就不能
向上运动,其他两种情况一样
3蛇身越长的时候,运动的速度就越快
好了,就这么多了,应该就没有了
分析了这些,就可以进一步的思考代码应该怎么写
1,地图生成
2,蛇身和食物的构造
3,运动函数的构造
4,控制 上下左右和加速(长按就是加速)
根据上图,大家就很容易想到地图可以用表格生成对不对
但还有一个每一个表格应该都有他的坐标
下面贴出代码
var table = $('<table></table>');
var tr = '<tr></tr>';
var td = '<td style="width:40px;height:40px;background:white"></td>';
for (var i = 0;i<8 ;i++ )
{
var tr_obj = $(tr);
for(var j=0; j<20;j++){
tr_obj.append($(td).attr('id',i+'_'+j));
}
table.append(tr_obj);
}
$(body).append(table);
上面用了一下简单的jquery 写法 上面生成了一个 长20 高8 的表格table
和为每个td分配了Id 值为自身的坐标,张来用来索引
地图生成以后,我们再考虑一下蛇身和食物的构造
如果能看出上图的话就很容易想到蛇身和食物单位都是td
但他们的颜色都不一样,我们需要用一个数组来记录蛇身
内容就是td的坐标 如果大家再仔细想的话,就可以能会
发现一个问题,就是蛇吃完食物的时候,系统都会分配一个
新的食物出现,但食物一定不会出现在蛇身上面
那就是在判断分配食物出现的位置之前,先确定一下位置的x,y是否在蛇身
好简单的 用inArray()来判断,下面贴出代码
var food_random = function(){
var x =parseInt( Math.random()*19);
var y =parseInt( Math.random()*8);
var tem =['#',y,'_', x].join('');
if($.inArray(tem, snake_body)>-1){
food_random();
}else{
draw($(tem),'yellow');
food_loaction = tem;
}
}
上面的代码用了就是这个判断,随机的生成x,y 位置再和蛇身比较,如果存在的
则递归的再来一次,递归的效率有点差,不知道大家有没有深入研究一下
递归是怎样实现的,如果不幸运的话,栈会撑爆的
好了,下一步到就运动函数的构造了
其实如果读者仔细的话看一下上面的图片就可以知道
蛇的运动其实可以用背景色变化来模拟,就好似动画一样
一个动作就要画1000多张图,然后翻起来,人物就好像真的
动了,哈哈,又如赛车一样,你觉得快只是他不动地车道往后拉一样
回到蛇运动这里,我们可以这样构造
向那个方向的话,都是它的蛇身最后一格往前面放
如果不明看一下上面的规则
代码就是蛇身 一个简单的数组操作
举一个例子就是蛇向右运动
var moveRight = function() {
if(current_location.x==19){
$(document).unbind('keydown'); //游戏结束
return false;
}else{
current_location.x++; //记录蛇头的位置
var tem = ['#',current_location.y,'_', current_location.x].join('');
if($.inArray(tem, snake_body)>-1){ //自己撞自己啊
$(document).unbind('keydown'); //游戏结束
return false;
}
snake_body.push(tem);
if(food_loaction==tem){
//你知道为什么这里要这样做吗
tem = ['#',current_location.y,'_', ++current_location.x].join('');
snake_body.push(tem);
food_random();
}
draw($(snake_body.shift()),'white')
draw($(tem),'yellow');
return true;
}
}
代码分析,首先就是用一个 current_location变量记录每个时刻蛇的位置
方便边界检查,如果撞墙和撞自己的话就gameover,还有正好下一个位置是食物
的话就把食物放进蛇身
draw($(snake_body.shift()),'white')
draw($(tem),'yellow');
这里就是填充背景色啦,把蛇身的最后一个变为白色 把新的变成黄色,用js十分容易 实现
下面就是轮到控制按键的实现
$(document).keydown(function(e){
window.clearInterval(timer);
var goon = true;
switch(e.keyCode){
case 37: goon=moveleft(); current_direction = 'left';
break;
case 38: goon= moveup(); current_direction = 'up';
break;
case 39: goon= moveRight() ;current_direction = 'right';
break;
case 40: goon= movedown(); current_direction = 'down';
break;
}
if(goon)
system_action()
});
var system_action = function(){
timer = window.setInterval(function(){
switch( current_direction){
case 'left':
moveleft();
break;
case 'right':
moveRight();
break;
case 'up':
moveup();
break;
case 'down':
movedown();
break;
}
}, speed);//speed为600比较流畅
}
下面分析程序
上面的很简单绑定一下按键事件上下左右的按键,读者会发现有一个
current_direction 变量,无错,这就是保存当前的运动方向
因为用户按键完成以后系统就会为蛇自动运动,明白吗
还有避免用户一直长按,所以在代码之前先清除定时器
按完键再恢复定时器!!!!
代码就这么多,是不是觉得很简单的,其实你也可以
一定要自己动手啊
记住
tem = ['#',current_location.y,'_', ++current_location.x].join('');
比用+号连接字符串效率高多了,有兴趣的探究一下汇编的实现
如果多人支持的话我会贴出源码的,大家要积极啊
var draw = function(obj, c) {
obj.css('background',c)
} 非常简单的填充背景色代码,学过window创建窗口和消息机制的人一定觉得很相似
好拉,下次再说