用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分就很厉害了哦!):在线贪吃蛇游戏
除了广告和敏感话题言论之外,可以畅所欲言。 | |
为自己起个简短易记的名字。 | |
方便我可以联系到你,绝对不会被公开。 | |
你的个人主页,链接会加在昵称上方便大家访问。 |