在这个网站“http://thecodeplayer.com/walkthrough/html5-game-tutorial-make-a-snake-game-using-html5-canvas-jquery”上看别人用html5+javascript写了一个贪食蛇的游戏,感觉不错,特别是有那个播放功能,可以看着别人一步一步的完成,作者思路清晰,操作犀利(VI党v5),居然这么快的就完成了(想起最开始学C#的时候,我用C#写俄罗斯方块,貌似花了不少时间啊)。。。
最近自己也看了一些关于这方面的书,于是,自己也从头写了一个,花了两三个小时,嘿嘿。不过在试玩的过程中,发现几个问题:1、吃食物的时候,每次都会有一种停顿感;2、很快的按上下左右,即使自身长度只有3个都会出现game over。。。;3、玩着玩着,在准备吃食物的那一刹那,就卡着不动了。。。这种情况偶尔会出现,貌似没规律。。。
于是,为了满足自己那点小小的体验感(现在都把它放在第一位哦~亲~),改了下,顺便写出来吧,不然。。。这个博客。。。太。。。少。。。东东啦。。。
第一个问题,是因为每次吃到食物的时候都是加在末尾,就像这样:
@@@ * :再往前走一步就吃食物了
@@@ :往前走一步,这是没食物的情况
@@@@ :这是吃了食物的情况
吃了食物,由于尾巴没动,于是乎就感觉停顿了一下~
于是,我想改成这样:
@@@ *
@@@@ :吃到食物的时候
貌似这样。。。食物在墙边上的时候就不好了。。。
哎。。。有点小失望,不过没关系,接着看第二个问题,为了验证我对于第二个问题原因的猜想,我加了一些打印信息,包括碰撞前的方向,保存蛇身体的数组,碰撞时蛇身体的数组,这样,很容易就可以发现,原来是头反向了。。。由于按键太快了,蛇原本是往上走的,我按左,蛇头向左走了一步,这个时候我直接按右是不会往右走的,因为在控制方向那里做了判断,不能直接反向,但是,如果我按键很快,按上,蛇还没来得及移动,我又按了右,这个时候时候就可以了。。。于是乎。。。蛇就撞自己身上了。。。
于是,我想了一个很拙劣的方法(因为我觉得应该有其他更好的办法吧),定义了一个变量,每次按了方向键后为false,每次开始蛇要移动的时候为false,只有当蛇移动完了才赋值为true,然后,每次按方向键后,判断一下这个变量,如果为true,则认可这次输入,反正,什么都不做。
第三个问题。。。由于随机性很强,不排除硬件问题。。。
好吧,就这样啦。。。感觉像是一个人在唠唠叨叨。。。
PS:请54注释里那些蹩脚的English吧,那不是给你们看的~
<!DOCTYPE html> <html> <head> <title>Snake</title> </head> <body> <canvas id="canvas" width="600" height="600"> Your browser not support Canvas! </canvas> <script type="text/javascript"> var c = document.getElementById('canvas'); var ctx = c.getContext('2d'); // ctx.translate(100,100); var canvasWidth; var canvasHeight; //snake array var snakeArray; //snake unit width var px; //fps var cycle; //setInterval var gameLoop; //key var left = 37; var up = 38; var right = 39; var down = 40; //direction var d; //food var f; //score var score; //too fast become direction var flagD; init(); //init snake function init(){ canvasWidth = c.width; canvasHeight = c.height; snakeArray = []; px = 20; cycle = 500/1000; d = right; f = {x:-1,y:-1}; score = 0; flagD = true; if(typeof gameLoop != 'undefined'){ clearInterval(gameLoop); } initSnake(3); initFood(); play(); } function play(){ gameLoop = setInterval(function(){ ctx.fillStyle = 'white'; ctx.fillRect(0,0,canvasWidth,canvasHeight); ctx.strokeStyle = 'black'; ctx.strokeRect(0,0,canvasWidth,canvasHeight); moveSnake(); //paintFood(); paintSnake(snakeArray); ctx.fillStyle = 'red'; paintCell(f.x,f.y); var scoreStr = 'Score:' + score; ctx.fillText(scoreStr,5,canvasHeight - 5); },cycle*1000); } //init snake function initSnake(length){ for(var i=length;i>0;i--){ snakeArray.push({x:i,y:0}); } }; // paintSnake(); function paintSnake(){ ctx.fillStyle = 'blue'; for(var i=0;i<snakeArray.length;i++){ paintCell(snakeArray[i].x,snakeArray[i].y); } } //paint cell function paintCell(x,y){ ctx.fillRect(x*px,y*px,px-1,px-1); } // move snake function moveSnake(){ flagD = false; // console.log("move direction:" + d); // for(var tt in snakeArray){ // // console.log(tt+":"+snakeArray[tt].x+","+snakeArray[tt].y); // }; //control direction var p = {x:snakeArray[0].x,y:snakeArray[0].y}; if(d == left) p.x--; else if(d == right) p.x++; else if(d == up) p.y--; else if(d == down) p.y++; //eat food if(p.x == f.x && p.y == f.y){ score++; initFood(); }else{ snakeArray.pop(); } // if(p.x == -1 || p.x == canvasWidth/px || p.y == -1 || p.y == canvasHeight/px || checkColliction(p.x,p.y)){ alert(p.x + ":" + p.y); init(); return; } snakeArray.unshift(p); flagD = true; } // check collection function checkColliction(x,y){ for(var t in snakeArray){ if(x == snakeArray[t].x && y == snakeArray[t].y) { // console.log('collection'); // for(var tt in snakeArray){ // // console.log(tt+":"+snakeArray[tt].x+","+snakeArray[tt].y); // } return true; } } return false; } // function initFood(){ var flag = false; do{ f.x = Math.floor(canvasWidth/px*Math.random()); f.y = Math.floor(canvasHeight/px*Math.random()); for(var t in snakeArray){ if(f.x == snakeArray[t].x && f.y == snakeArray[t].y) flag = true; } }while(flag); } //add listin key window.addEventListener('keydown',function(e){ if(flagD){ if(e.keyCode == left && d != right) d = left; else if(e.keyCode == right && d != left) d = right; else if(e.keyCode == up && d!= down) d = up; else if(e.keyCode == down && d != up) d = down; flagD = false; }; }); </script> </body> </html>