贪吃蛇

来源:互联网 发布:mac air充电器 编辑:程序博客网 时间:2024/04/30 12:25

练习代码,贪吃蛇。

贪吃蛇中难想的地方就是怎么能让蛇运动起来,看了网上的资料才知道,蛇的移动,其实就是后面的节点代替前面节点的位置,同时根据按键方向更新蛇头节点、去掉尾巴,这样一来就出现贪吃蛇运动的情形啦~

代码的思路就是把整个游戏的过程分为两个对象:一个是蛇对象,一个是果实对象。蛇的行为包括初始化蛇、蛇移动、蛇吃果子长大以及蛇死了。蛇吃果子长大即判断蛇头和果实重合时,果子消失重建,蛇长度+1。蛇死分为两种情况,一种是撞墙死,一种是撞自己死,其中撞自己死目前使用的是循环判断蛇身是否和蛇头重合【感觉应该有更好的办法的,需要再想】。

果实行为相对简单,随机在canvas选择位置创建果实【其中有判断不能和蛇身重合,和蛇死的代码类似,所以直接用蛇死代码判断了】。

因为是第一次写贪吃蛇和使用canvas,觉得还是有些困难。之后一点一点解决问题,首先想怎么在canvas上画图,于是画了一条静止的“小蛇”出来;然后想怎么画果实,随机产生果实这个还好;然后就是关键的步骤,怎么让蛇动起来,一开始写出来的只是每次按一个键就动一下,蛇动起来后,着手写蛇怎么死啊,怎么吃果子啊,怎么长大啊等等。进而发现蛇头和果实不能重合的问题,这才理解,看别人的贪吃蛇代码时没理解的“%10”。别人的代码都好难懂啊好难懂→_→。

canvas的绘图是相对方便的,包括蛇头和果实重合时,果实会自动消失。这个如果使用java或者c,应该还要写一个果实消失的行为。

代码的计分规则很简单,就是吃一个果实长大一节;时间方面也是设置的固定的100ms,没有根据蛇的长度变化setInterval的时间。

文章的部分代码参考了http://pustone.com/science/375.html 【其实html代码基本就是他的啦~有些js代码的命名规则也是用的他的~但是他的js代码我目前还没看懂→_→】

<1> html代码

<!doctype html><meta lang=zh charset=utf-8><html><head><title>贪吃蛇</title></head><body onkeyup="whichDirection(event);"><h1>贪吃蛇</h1><hr><canvas id="Snake-Canvas" width=1000 height=500></canvas><hr><p>当前得分:<span id="Snake-Score"></span>蛇长:<span id="Snake-Length"></span></p><p id="Snake-Status"></p><script src="Snake.js"></script></body></html>


<2> js代码

//工具方法1:在canvas创造一个点function createPoint(x, y, color){var c = document.getElementById("Snake-Canvas");var context = c.getContext("2d");this.x = x;this.y = y;this.color = color || "black";context.fillStyle = this.color;context.fillRect(x, y, 10, 10);}//工具方法2:响应按键function whichDirection(event){//响应按键,改变蛇的方向// 例如如果蛇正在往左边走,不能向右走,按左键和按其他无效键的情况一致// 所以,实际只能向上或者向下走if(event.keyCode == 32){alert("Game Pause!");}if(snake.direction == "left" || snake.direction == "right"){snake.direction = event.keyCode == 38&&"up" || event.keyCode == 40&&"down" || snake.direction;}else{snake.direction = event.keyCode == 37&&"left" || event.keyCode == 39&&"right" || snake.direction;}}//蛇对象function Snake(length){this.Length = length||3;this.snakeBody = [];this.direction = "left";//默认left//初始化蛇对象,长度为3this.createSnake = function(){this.snakeBody[0] = new createPoint(500, 200);this.snakeBody[1] = new createPoint(510, 200);this.snakeBody[2] = new createPoint(520, 200);//写入页面信息var s_len = document.getElementById("Snake-Length");s_len.innerHTML = this.snakeBody.length;document.getElementById("Snake-Score").innerHTML = 0;document.getElementById("Snake-Status").innerHTML = "健康地活着";}this.growUp = function(apple){//如果蛇头和果实重叠,那么蛇就在末尾长大if(apple.x == this.snakeBody[0].x && apple.y == this.snakeBody[0].y){var len = this.snakeBody.length;var s_x = this.snakeBody[len-1].x, s_y = this.snakeBody[len-1].y;this.snakeBody[len] = new createPoint(s_x, s_y);this.Length = len + 1;//更新分数。每吃一个果实一分var o_score = parseInt(document.getElementById("Snake-Score").innerHTML);o_score++;document.getElementById("Snake-Score").innerHTML = o_score;//更新蛇长度,每吃一个果实增加一节document.getElementById("Snake-Length").innerHTML = this.snakeBody.length;//重新生成果实apple.createApple(snake);}}//蛇移动this.move = function(apple){//先要判断蛇头的情况,如果不死的情况下,才能进行移动,如果死了直接放弃移动var head_x = this.snakeBody[0].x;var head_y = this.snakeBody[0].y;switch(this.direction){case "left":head_x = head_x - 10;break;case "right":head_x = head_x + 10;break;case "up":head_y = head_y - 10;break;case "down":head_y = head_y + 10;break;}if(this.die(head_x, head_y)){document.getElementById("Snake-Status").innerHTML = "死了=-=";alert("游戏结束!");location.reload();//刷新页面开始游戏return false;}else{for(var i=this.snakeBody.length - 1; i>0; i--){var i_x = this.snakeBody[i].x;var i_y = this.snakeBody[i].y;if(i == this.snakeBody.length - 1){var c = document.getElementById("Snake-Canvas");var context = c.getContext("2d");context.clearRect(i_x, i_y, 10, 10);this.snakeBody[i] = this.snakeBody[i-1];}else {this.snakeBody[i] = this.snakeBody[i-1];}}//后面的蛇全部复制完成,才对蛇头进行更新this.snakeBody[0] = new createPoint(head_x, head_y);this.growUp(apple);}//计时增加}//蛇死this.die = function(head_x, head_y){var flag = false;//头部和身体其他部分重合,死for(var i=1;i<this.snakeBody.length;i++){var s_x = this.snakeBody[i].x;var s_y = this.snakeBody[i].y;if(head_x==s_x && head_y == s_y){flag = true;break;}}//头部撞墙,死if(head_x >1000 || head_x < 0 ) flag = true;else if(head_y > 500 || head_y < 0 ) flag = true;else flag = flag;return flag;}}function Apple(){//随机在canvas上出现一个果实this.x = 0;this.y = 0;//createPoint(this.x, this.y, "red");this.createApple = function(snake){var flag = false;// 产生的果实不可以和蛇身重合,虽然概率很低do{this.x = Math.floor(Math.random()*1000);this.y = Math.floor(Math.random()*500);this.x = this.x - this.x%10;this.y = this.y - this.y%10;if(snake.snakeBody[0].x == this.x && snake.snakeBody[0].y == this.y ) flag = true;else if(snake.die(this.x, this.y)) flag = true;else flag = false;}while(flag);return createPoint(this.x, this.y, "red");}}alert("开始游戏,可按空格键暂停");var snake = new Snake();var apple = new Apple();snake.createSnake();apple.createApple(snake);window.setInterval("snake.move(apple)", 100);




0 0