您的位置:首页 > Web前端 > JavaScript

贪吃蛇

2015-10-16 21:16 661 查看
练习代码,贪吃蛇。

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

代码的思路就是把整个游戏的过程分为两个对象:一个是蛇对象,一个是果实对象。蛇的行为包括初始化蛇、蛇移动、蛇吃果子长大以及蛇死了。蛇吃果子长大即判断蛇头和果实重合时,果子消失重建,蛇长度+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

//初始化蛇对象,长度为3
this.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
4000
= new Snake();
var apple = new Apple();

snake.createSnake();
apple.createApple(snake);

window.setInterval("snake.move(apple)", 100);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript canvas