- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title > 贪吃蛇 </title>
- </head>
- <body>
- <canvas id="game" width="450" height="450" style="border:1px solid red;margin:30px auto;display:
- block;"></canvas>
- <script type="text/javascript">
- var canvas = document.getElementById("game");
- // 拿到上下文, 画图工具
- var cxt = canvas.getContext("2d");
- // 每个格子的宽度
- var width = 15;
- // 面向对象, 蛇的身体是一节一节的
- /*
- 定义一个 Cell 类, 具备 x 和 y 还具备 f
- x 和 y 代表格子的坐标, f 代表方向
- f 方向
- 1 代表左,-1 代表右
- 2 代表下,-2 代表上
- */
- function Cell(x,y,f){
- this.x=x;
- this.y=y;
- this.f=f;
- }
- function Food(x,y){
- this.x=x;
- this.y=y;
- }
- // 蛇的对象 蛇是由 Cell 组成的
- var snake =[];
- var length = 2;// 蛇的长度
- var speed = 100;//100 毫秒移动一个单元格
- var food= new Food(15,15);
- // 初始化蛇的身体
- for(var i=0;i<length;i++){
- snake[i] = new Cell(i, 0, -1)
- }
- for(var i = 0;i<snake.length;i++){
- var cell= snake[i];
- cxt.fillStyle = "gray";
- if(i==snake.length-1){
- cxt.fillStyle="red";
- }
- cxt.beginPath();
- cxt.rect(cell.x*width ,cell.y*width,width,width);
- cxt.closePath();
- cxt.fill();
- }
- cxt.fillStyle = "green";
- cxt.beginPath();
- cxt.rect(food.x*width ,food.y*width,width,width);
- cxt.closePath();
- cxt.fill();
- // 怎么让蛇头跟着键盘动, 监听键盘事件
- document.onkeydown = function(e){
- var code = e.keyCode;
- var direction = 0;
- switch(code){
- case 37:direction = 1;break;
- case 38:direction = 2;break;
- case 39:direction = -1;break;
- case 40:direction = -2;break;
- case 87:direction = 2;break;
- case 65:direction = 1;break;
- case 83:direction = -2;break;
- case 68:direction = -1;break;
- }//switch
- var head = snake[snake.length-1];
- if(direction!=0&&(head.f+direction)!=0){
- // 调用蛇的移动方法
- moveSnake(direction);
- }//if(direction)
- }//function(e)
- function moveSnake(direction){
- var head = snake[snake.length-1];// 蛇头
- if(!direction){
- direction=head.f;
- }
- var newSnake = [];
- var newHead = new Cell(head.x, head.y, head.f);
- for(var i = 1;i<snake.length;i++){
- newSnake[i-1] = snake[i];
- }
- newHead.f=direction;
- // 修改 x 和 y 的值
- switch(direction){
- case 1:newHead.x-- ;break;
- case 2:newHead.y-- ;break;
- case -1:newHead.x++ ;break;
- case -2:newHead.y++ ;break;
- }
- newSnake[newSnake.length]=newHead
- snake=newSnake;
- gameOver();
- draw();
- }
- function gameOver(){
- // 检查撞到游戏的边框
- var head = snake[snake.length-1];
- if(head.x>=30||head.y>=30||head.x<0||head.y<0){
- alert("撞墙, 游戏结束");
- window.location.reload();
- }
- // 不能咬到自己
- for(var i=0;i < snake.length-1;i++){
- if(snake[i].x == head.x && snake[i].y == head.y){
- alert("撞到自己了, 游戏结束");
- window.location.reload();
- }
- }
- }
- function draw(){
- cxt.clearRect(0, 0, 450, 450);
- cxt.fillStyle = "green";
- cxt.beginPath();
- cxt.rect(food.x*width ,food.y*width,width,width);
- cxt.closePath();
- cxt.fill();
- // 判断蛇的蛇头是不是和食物的坐标重合
- var head = snake[snake.length-1];
- if(head.x==food.x&&head.y==food.y){
- var newHead = new Cell(head.x, head.y, head.f);
- // 修改 x 和 y 的值
- switch(newHead.f){
- case 1:newHead.x-- ;break;
- case 2:newHead.y-- ;break;
- case -1:newHead.x++ ;break;
- case -2:newHead.y++ ;break;
- }
- snake[snake.length] = newHead;
- randFood();
- }
- for(var i = 0;i<snake.length;i++){
- var cell= snake[i];
- cxt.fillStyle = "gray";
- if(i==snake.length-1){
- cxt.fillStyle="red";
- }
- cxt.beginPath();
- cxt.rect(cell.x*width ,cell.y*width,width,width);
- cxt.closePath();
- cxt.fill();
- }
- }
- function randFood(){
- food.x=Math.ceil(Math.random()*28)+1;
- food.y=Math.ceil(Math.random()*28)+1;
- }
- var autoRun = setInterval(moveSnake,speed);
- </script>
- </body>
- </html>
来源: http://www.bubuko.com/infodetail-2507580.html