<!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>