参考了很多,没有加注释,只加了写的步骤
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#myCanvas{
background-color: #FFFFFF;
}
</style>
</head>
<!--
第一步: 创建一个舞台
1. canvas幕布,设置大小,背景以及边界颜色
2. span成绩显示
3. button开始按钮,设置点击事件
第二步: 创建蛇对象:属性和动作
1. bodyArray蛇身体属性,一个数组,每一块有x与y坐标,例如bodyArray[i]=[{x:1},{y:2}]
2. move移动动作,不干涉头部,身体其他部位依次向前.
3. moveup, movedown, moveleft and moveright:具体控制头部移动,之后调用2move方法移动身体,例如,向上移动则x不变,y-1
4. eatFood蛇吃食物动作,蛇吃掉食物之后,身体向后增长,这里需要根据最后两节身体来判断增长方向,
在复杂一点需要考虑墙的因素,这里还需要初始化食物对象,food=[{x:1},{y:2}],只要头部和food坐标重合就是吃掉.
然后食物重新刷新,这里还要考虑分数,只要吃掉食物,就将分数增加,这里有需要一个变量MyScore and score
5. changeDirection变向,如果6isChangeDirection允许变向就把currentDirection改变
6. isChangeDirection是否可以变向,可以用一个二维数组,前后一组,左右一组,找到当前方向一组,如果变向也在改组就不能变,同样除了这四个方向外其他都不能变
这里我们需要设置一个二维数组directionTwoArray=[['left','right'],['up','down']];另外判断是否是四个方向还需要一个一维数组directionOneArrray=['left','right','up','down'];
第三步: 设置游戏规则:蛇撞死
1. isSnakeKnockWall判断蛇是否撞墙方法:只要判断头部坐标就可以, 这里需要根据变量unit判断,因此需要两个新变量wUnitNumber, hUnitNumber
2. isSnakeKnockBody怕那顿蛇是否撞到身体:这个遍历依次就可以
第四步: 键盘控制
1. 使用WASD分别控制up, left, down and right,只要是正确的方向,蛇就移动,执行具体的3moveSomeDirevtion方法
第五步: 绘制蛇和食物
1. drawSnake画蛇方法,画蛇用到了Canvas绘制,这里我们只要遍历就可以了,这里需要三个变量一个canvas,一个canvas的上下文ctx,
以及每节身体占多少格子的unit
2. drawFood画食物方法, 画食物和画蛇差不多,不过需要随机生成而已,但是setInterval循环的时候我不确定是不是会刷新掉,因此可能会拆成两个办法
3. clearScreen清屏方法,这是为了重新开始游戏设置的.开始游戏之前也要设置一遍
第六步: 游戏初始化和循环
1. startGame开始游戏方法,首先应该是初始化食物和蛇,然后进入循环,根据当前方向currentDirect一直向前走,除非按键改变方向.
另外开始游戏的时候还要打破循环,也就是clearInternal(window.looper),否则还是会继续画.
-->
<body>
<canvas id="myCanvas" style="width: 300px; height: 300px;"></canvas><br>
<span>你的成绩是:</span><span id="myScore"></span><br>
<button type="button" onclick="startGame();">开始游戏</button>
<script>
var width = 300;
var height = 300;
var unit = 6;
var wUnitNumber = width/unit;
var hUnitNumber = height/unit;
var myCanvas = document.getElementById('myCanvas');
var ctx = myCanvas.getContext("2d");
var directionTwoArray=[['left','right'],['up','down']];
var directionOneArrray=['left','right','up','down'];
var myScore = document.getElementById('myScore');
var score = 0;
var food = {x:1, y:2};
var snake = {
currentDirect :'right',
directionTwoArray:[['left','right'],['up','down']],
directionOneArrray:['left','right','up','down'],
bodyArray: [{x:3, y:0},{x:2, y:0},{x:1, y:0}],
move:function(preBody){
//debugger
var tempBody;
for(var i = 1; i < this.bodyArray.length; i ++){
tempBody = this.bodyArray[i];
this.bodyArray[i] = preBody;
preBody = tempBody;
// console.log("body["+i+"]"+this.bodyArray[i].x+","+this.bodyArray[i].y+" ");
}
},
moveup:function(){
//debugger
var oldHead = this.bodyArray[0];
this.bodyArray[0]= {x:oldHead.x,y:oldHead.y-1};
this.move(oldHead);
},
movedown:function(){
//debugger
var oldHead = this.bodyArray[0];
this.bodyArray[0]= {x:oldHead.x,y:oldHead.y+1};
this.move(oldHead);
},
moveleft:function(){
//debugger
var oldHead = this.bodyArray[0];
this.bodyArray[0]= {x:oldHead.x-1,y:oldHead.y};
this.move(oldHead);
},
moveright:function(){
//debugger
var oldHead = this.bodyArray[0];
this.bodyArray[0]= {x:oldHead.x+1,y:oldHead.y};
//console.log(oldHead.x+","+oldHead.y);
this.move(oldHead);
},
eatFood:function(){
var head = this.bodyArray[0];
if(head.x == food.x && head.y == food.y){
//debugger
//todo 还可能碰到墙
lastBody = this.bodyArray[this.bodyArray.length-1];
lastButOneBody = this.bodyArray[this.bodyArray.length-2];
var xMin = lastBody.x - lastButOneBody.x;
var yMin = lastBody.y - lastButOneBody.y;
var oneBody = {x:lastBody.x+xMin, y:lastBody.y+yMin}
this.bodyArray.push(oneBody);
score++;
myScore.innerHTML=score;
initFood();
}
},
isChangeDirection:function(direction){
//如果不是四个方向里面的
if(directionOneArrray.indexOf(this.currentDirect) == -1){
return false;
}
var tempTwoDirection=null;
for(var i in this.directionTwoArray){
//如果是这一组的一个方向
if(this.directionTwoArray[i].indexOf(this.currentDirect) != -1){
tempTwoDirection = this.directionTwoArray[i];
break;
}
}
if(tempTwoDirection.indexOf(direction) != -1){
return false;
}
return true;
},
changeDirection:function(direction){
if(this.isChangeDirection(direction)){
this.currentDirect = direction;
}else{
console.log("不能变向");
}
console.log("curentDirection: "+snake.currentDirect);
}
}
function isSnakeKnockWall(){
var head = snake.bodyArray[0];
if((head.x < 0 || head.y < 0) || ((head.x > wUnitNumber-1) || (head.y > hUnitNumber-1))){
return true;
}
return false;
};
function isSnakeKnockBody(){
var head = snake.bodyArray[0];
for(var i = 1; i < snake.bodyArray.length; i ++){
if(head.x == snake.bodyArray[i].x && head.y==snake.bodyArray[i].y){
return true;
}
}
return false;
};
window.onkeyup=function(key){
var direction = '';
console.log("keyCode: "+key.keyCode);
switch(key.keyCode){
case 65:
direction='left';
snake.moveleft();
break;
case 68:
direction='right';
snake.moveright();
break;
case 87:
direction='up';
snake.moveup();
break;
case 83:
direction='down';
snake.movedown();
break;
default:
break;
}
if(direction=='') return;
snake.changeDirection(direction);
};
function drawSnake(){
//console.log("snake.length: "+snake.bodyArray.length);
for(var i = 0; i < snake.bodyArray.length; i ++){
//console.log("body["+i+"]"+snake.bodyArray[i].x+","+snake.bodyArray[i].y+" ");
// ctx.fillStyle="#FF0000";
ctx.rect(snake.bodyArray[i].x*unit, snake.bodyArray[i].y*unit, unit, unit);
}
ctx.stroke();
};
function initFood(){
food.x = Math.floor(Math.random()*wUnitNumber/4);
food.y = Math.floor(Math.random()*hUnitNumber/4);
}
function drawFood(){
ctx.rect(food.x*unit, food.y*unit, unit, unit);
ctx.stroke();
}
function clearScreen(){
ctx.clearRect(0,0,width, height);
}
function startGame(){
//debugger;
clearInterval(window.looper);
//debugger;
snake.bodyArray=[{x:3, y:0},{x:2, y:0},{x:1, y:0}];
snake.currentDirect = 'right';
//clearScreen();
ctx.beginPath();
initFood();
drawFood();
drawSnake();
ctx.stroke();
window.looper=setInterval(function(){
//debugger;
//console.log("curentDirection: "+snake.currentDirect);
switch(snake.currentDirect){
case 'left':
snake.moveleft();
break;
case 'right':
//console.log("right");
snake.moveright();
break;
case 'up':
//console.log("up");
snake.moveup();
break;
case 'down':
//console.log("down");
snake.movedown();
break;
default:
break;
}
this.clearScreen();
ctx.beginPath();
snake.eatFood();
drawSnake();
drawFood();
if(isSnakeKnockWall()){
clearInterval(window.looper);
alert("GAME OVER and you SCORE:"+score);
}
},300);
}
</script>
</body>
</html>