这是一个使用html,javascript实现的简陋的贪吃蛇程序
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>贪吃蛇</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style type="text/css"> html,body{ margin:0; padding: 0; width:100%; height:100%; background-color: #3f3f3f; } canvas{ position:relative; left:50%; top:50%; margin-left:-300px; margin-top:-300px; border:1px solid #000; background-color: #f0f0f0; } </style> </head> <body> <canvas id="gameCanvas" width="600" height="600"></canvas> <script type="text/javascript" src="./js/main.js"></script> </body> </html>
(function(context){ //game config var config={ width:600, height:600, unit:10 }; //game snake var snake={ body:[], v:1, direction:"left", init:function(){ this.body.push({x:config.width/config.unit/2,y:config.height/config.unit/2}); }, draw:function(){ context.save(); for(var i=0;i<this.body.length;i++){ context.fillRect(this.body[i].x*config.unit,this.body[i].y*config.unit,config.unit,config.unit); } context.restore(); }, move:function(direction){ if(this.direction=="left"&&direction=="right") return; if(this.direction=="up"&&direction=="down") return; if(this.direction=="right"&&direction=="left") return; if(this.direction=="down"&&direction=="up") return; this.direction=direction||this.direction; var nextX=this.body[0].x; var nextY=this.body[0].y; if("left"==this.direction){ nextX-=this.v; }else if("up"==this.direction){ nextY-=this.v; }else if("right"==this.direction){ nextX+=this.v; }else if("down"==this.direction){ nextY+=this.v; } this.body.pop(), this.body.unshift({x:nextX,y:nextY}); }, eatFood:function(food){ this.body.push({x:food.x,y:food.y}); environment.destroyFood(food); } }; var environment={ currEntifyId:0, entity:[], init:function(){ }, nextEntifyId:function(){ return this.currEntifyId++; }, createFood:function(){ this.entity.push({id:this.nextEntifyId(),x:parseInt(Math.random()*(config.width/config.unit)), y:parseInt(Math.random()*(config.height/config.unit)), type:"food"}); }, destroyFood:function(food){ var newEntify=[]; for(var i=0;i<this.entity.length;i++){ if(this.entity[i].id==food.id) continue; newEntify.push(this.entity[i]); } this.entity=newEntify; }, draw:function(){ context.save(); var hasFood=false; for(var i=0;i<this.entity.length;i++){ if(this.entity[i].type=="food"){ hasFood=true; context.fillRect(this.entity[i].x*config.unit,this.entity[i].y*config.unit,config.unit,config.unit); } } context.restore(); if(!hasFood) this.createFood(); } }; //game event manager var gameEvent={ onSnakeEatFood:function(snake,food){ snake.eatFood(food); }, onSnakeAgainstWall:function(){ alert("game over!!!"); }, onSnakeEatSelf:function(){ alert("game over!!!"); } }; //keybord event document.onkeydown=function(event){ var key=event.keyCode; if(key==37){ //left snake.move("left"); }else if(key==38){ //up snake.move("up"); }else if(key==39){ //right snake.move("right"); }else if(key==40){ //down snake.move("down"); } }; //init game environment.init(); snake.init(); //main game loop var currentFrame=0; (function gameLoop(){ if(currentFrame%10==0){ //clear canvas context.clearRect(0,0,config.width,config.height); //check event if(snake.body[0].x<=0||snake.body[0].y<=0|| snake.body[0].x>=config.width/config.unit||snake.body[0].y>=config.height/config.unit){ gameEvent.onSnakeAgainstWall(); } for(var i=1;i<snake.body.length;i++){ var dX2=Math.pow(snake.body[0].x-snake.body[i].x,2); var dY2=Math.pow(snake.body[0].y-snake.body[i].y,2); if((dX2+dY2)==0){ gameEvent.onSnakeEatSelf(); } } for(var i=0;i<environment.entity.length;i++){ var entifyX=environment.entity[i].x; var entifyY=environment.entity[i].y; var entifyType=environment.entity[i].type; var dX2=Math.pow((snake.body[0].x-entifyX),2); var dY2=Math.pow((snake.body[0].y-entifyY),2); if((dX2+dY2)==0){ gameEvent.onSnakeEatFood(snake,environment.entity[i]); } } //draw stage environment.draw(); snake.move(); snake.draw(); } //next frame currentFrame++; requestAnimationFrame(gameLoop); })(); })(document.getElementById("gameCanvas").getContext("2d"));