用JavaScript写游戏?一直以来,使用JS都是写一些交互和特效而已,从没写过游戏,加之一个月没有更新博客了,蜘蛛都不来了……所以这次就贴一个前段时间写的贪吃蛇游戏吧,这个贪吃蛇游戏规则不同于小时候掌上游戏机的那种类型,这个贪吃蛇每吃完一个果子,果子就会变成果核,蛇身自动加长一截,蛇吃到果核也会死掉,随着吃的果子越来越多,蛇身越来越长,游戏难度将会越来越大。
贪吃蛇的基本原理很简单:蛇在运动的过程中只要蛇头运动,然后其他每一截蛇身的位置等于前面一截蛇身的位置。
HTML和CSS就不贴代码出来了。首先创建蛇:蛇的每一截都可以用html标签元素来模拟,假设外部的容器对象为oWrap,在oWrap里面添加一只四截的蛇:
/*
创建蛇:
oWrap:最外层容器,包含游戏画布所有内容
oSnake[]:存放蛇身的每一截,HTML元素:<b></b>
row:列、line:行
initX:初始行数、initY:初始列数
initLeng:蛇的初始长度
*/
var oWrap = document.getElementById('wrap');
var oSnake=[], initX = 15, initY = 11, initLeng = 4;
for( var i = 0; i < initLeng; i++ ) {
oSnake[i] = document.createElement('b');
oSnake[i].line = initX+i;
oSnake[i].row = initY+1;
setPosition(oSnake[i]);
oWrap.appendChild(oSnake[i]);
}
oSnake[0].style.background = '#070'; // 蛇头深色
这样就在oWrap里添加了四个b元素,然后在CSS里要将b设定为块级元素,宽高各为16PX(var scale=16),画布暂设为560px×400px,25行,35列。完成之后就是一条安静的蛇躺在中间:
用setInterval()使蛇运动起来,以及贪吃蛇的所有核心部分都在定时器里面执行。首先是监听键盘事件,通过键盘的方向键来控制蛇的方向(键盘值为:← 37,↑ 38,→ 39,↓ 40;当然,游戏方向键也有必要考虑下:A 65,W 83,D 65,S 87)
var key = null, direction = "left";
document.onkeydown = function( e ) { //监听键盘
var eve = e || event;
key = eve.keyCode || eve.which || eve.charCode;
// 根据按下的方向键确定移动方向:
switch( key ) {
case null: case 37: case 65: direction="left"; break;
case 38: case 87: direction = "up"; break;
case 39: case 68: direction = "right"; break;
case 40: case 83: direction = "down"; break;
default:direction = "left";
}
}// keydown end
键盘key值获取之后,然后就是回到贪吃蛇的运动原理了:每一截的位置等于前面一截的位置,以此类推:
// 蛇身后面一截的位置等于前面一截:
for( var i = oSnake.length-1; i > 0; i-- ) {
oSnake[i].line = oSnake[i-1].line;
oSnake[i].row = oSnake[i-1].row;
}
// 改变方向:(只需改变蛇头的方向)
switch( direction ) {
case 'left': {
if( oSnake[0].line > 1 ) oSnake[0].line--;
else death(oSnake);
};break;
case 'up': {
if( oSnake[0].row > 1 ) oSnake[0].row--;
else death(oSnake);
};break;
case 'right': {
if( oSnake[0].line < 33 ) oSnake[0].line++;
else death(oSnake);
};break;
case 'down': {
if( oSnake[0].row < 23 ) oSnake[0].row++;
else death(oSnake);
};break;
default: return;
}
// 获取新的坐标之后重新设置每一截的位置
for( var i = 0, len = oSnake.length; i < len; i++ ) {
oSnake[i].style.left = scale*oSnake[i].line + 'px';
oSnake[i].style.top = scale*oSnake[i].row + 'px';
}
上面的变量scale为蛇的每一截尺寸,设置为16px,到这一步就能实现方向键控制蛇的运动方向了。下面一步就是创建一个随机位置的果实构造函数,拥有创建果实的方法createFruit()和记录吃剩记录beStone():
function Fruit( obj ) {
/*
fx:2~34随机行数,
fy:2~24随机列数
Math.random()*(上限-下限+1)+下限
*/
this.fruit = null;
this.createFruit = function() { // 创建产生果实的方法
this.fx = parseInt( Math.random()*33 + 2 );
this.fy = parseInt( Math.random()*23 + 2 );
deathLine.push( this.fx - 1 );
deathRow.push( this.fy - 1 );
this.fruit = document.createElement('div'); // 创建一个果实
var xAxis = ( this.fx - 1 ) * scale;
var yAxis = ( this.fy - 1 ) * scale;
this.fruit.style.cssText = "position:absolute;
left: "+xAxis + "px;
top: "+yAxis + "px;
width: 16px;
height: 16px;
background: #F60;
z-index: 4;
background: url(fruit.png) no-repeat;";
obj.appendChild(this.fruit);
}
this.beStone = function() { // 吃掉的果实变为果核
this.fruit.style.background = "url(eaten.png) no-repeat";
}
}
然后就是实例化蛇:
/* 创建果实: */
var oFruit= new Fruit(oWrap);
oFruit.createFruit();
蛇头吃到自身的任何一个部位都要死掉:
// 蛇身任意一处重叠时(吃到自己,蛇头与身体任意一截重叠)挂掉!
for( var i = 1, len = oSnake.length; i < len; i++ ) {
if( oSnake[i].line == oSnake[0].line && oSnake[i].row == oSnake[0].row ) {
alert("Game Over!");
}
}
蛇吃到果实后自身增加一截,并且判断是否吃到果核,如果是吃到果核也要挂掉:
// 蛇头首次吃到果实后:
var deathLine = [], deathRow=[], score = 0, degree = 10; // 存放每一个果核的位置
if( oSnake[0].line + 1 == oFruit.fx && oSnake[0].row+1 == oFruit.fy ) {
// 分数增加:
document.getElementById('score').innerHTML = score += degree;
// 吃掉果实后蛇身增加一截(加到最后一截):
var newSnake = document.createElement('b');
newSnake.line = oSnake[oSnake.length-1].line;
newSnake.row = oSnake[oSnake.length-1].row;
oSnake.push(newSnake);
for( var i = 0, len = oSnake.length; i < len; i++ ) {
oSnake[i].style.left = scale*oSnake[i].line + 'px';
oSnake[i].style.top = scale*oSnake[i].row + 'px';
}
oWrap.appendChild(oSnake[oSnake.length-1]);
// 标记果核已经被吃掉(变成果核)
oFruit.beStone();
// 吃完后再重新生成一个“果实”
window.setTimeout(function() {
oFruit.createFruit();
}, speed);
}else { // 蛇头吃到果核:
for( var i = 0, len = deathLine.length; i < len; i++ ) {
if( oSnake[0].line == deathLine[i] && oSnake[0].row == deathRow[i] ) {
alert("Game Over!");
}
}
}
至此,大致原理就扯完了,不知道网友们能看得懂么?水平有限啊~可以在线试玩一下,(能玩到600分就很厉害了哦!):在线贪吃蛇游戏