canvas實現貪喫蛇效果

效果展示:

源碼展示:

頁面佈局展示:worm.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>貪喫蛇</title>
		<style type="text/css">
			canvas{
				border: 1px solid black;
			}
			div{
				width: 50px; height: 50px;	
				border: 1px solid black; cursor: pointer;
				text-align: center; line-height: 50px;
			}
		</style>
		<script type="text/javascript" src="Node.js" ></script>
		<script type="text/javascript" src="Worm.js" ></script>
		<script src="Stage.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			function load () {
				//創建一個舞臺 調用print方法打印
				stage=new Stage();
				//獲取ctx 
				var mCanvas=document.getElementById("mCanvas");
				ctx=mCanvas.getContext('2d');
				stage.print(ctx);
				startPrint();
			}
			
			function changeDir(dir){
				DIR=dir;
			}
			var task;
			var stage;
			var ctx;
			function startPrint () {
				task=window.setInterval(function () {
					stage.worm.step();
					stage.print(ctx);
				}, SPEED);
			}
			function endPrint () {
				window.clearInterval(task);
			}
			
		</script>
	</head>
	<body onload="load()">
		<canvas id="mCanvas" width="500" height="500">
		</canvas>
		
		<table>
			<tr>
				<td></td>
				<td>
					<div onclick="changeDir(UP)">UP</div>
				</td>
				<td></td>
			</tr>
			<tr>
				<td>
					<div  onclick="changeDir(LEFT)">LEFT</div>
				</td>
				<td></td>
				<td>
					<div  onclick="changeDir(RIGHT)">RIGHT</div>
				</td>
			</tr>
			<tr>
				<td></td>
				<td>
					<div  onclick="changeDir(DOWN)">DOWN</div>
				</td>
				<td></td>
			</tr>
		</table>
		
	</body>
</html>

節點類的js  :Node.js

/* 節點類 */
function Node (x, y) {
	this.x=x;
	this.y=y;
	this.equals=function (i, j) {
		return this.x==i && this.y==j;
	};
	
}

舞臺類js:Stage.js

/** 舞臺類 */
function Stage () {
	this.width=50;
	this.height=50;
	this.worm=new Worm();
	
	/* 在canvas中繪製舞臺的內容 */
	this.print=function (ctx) {
		for(i=0; i<this.width; i++){
			for(j=0; j<this.height; j++){
				//如果當前節點是蛇身子的一部分 
				//那麼換一種顏色繪製
				if(this.worm.contains(i,j)){
					ctx.fillStyle="#ab55ff";
					ctx.fillRect(i*10, j*10, 10, 10);
				}else if(this.worm.food.equals(i, j)){
					ctx.fillStyle="#000000";
					ctx.fillRect(i*10, j*10, 10, 10);
				}else{
					ctx.fillStyle="#dddddd";
					ctx.fillRect(i*10, j*10, 10, 10);
				}
			}
		}
		//在舞臺的左上角繪製分數
		ctx.font="30px Arial";
		ctx.fillStyle="#880000";
		ctx.fillText("score:"+SCORE, 10,40);
	};
}




蛇類js:Worm.js

/** 蛇類 */
var UP=0;
var DOWN=1;
var LEFT=2;
var RIGHT=3;

var DIR=UP;

var SCORE=0;
var SPEED=300;
//蛇類初始化的形狀
function Worm () {
	this.nodes=[];
	this.nodes[this.nodes.length]=new Node(20,10);
	this.nodes[this.nodes.length]=new Node(20,11);
	this.nodes[this.nodes.length]=new Node(20,12);
	this.nodes[this.nodes.length]=new Node(20,13);
	this.nodes[this.nodes.length]=new Node(20,14);
	this.nodes[this.nodes.length]=new Node(20,15);
	this.nodes[this.nodes.length]=new Node(21,15);
	this.nodes[this.nodes.length]=new Node(22,15);
	this.nodes[this.nodes.length]=new Node(23,15);
	this.nodes[this.nodes.length]=new Node(24,15);
	this.nodes[this.nodes.length]=new Node(24,16);
	this.nodes[this.nodes.length]=new Node(24,17);
	this.nodes[this.nodes.length]=new Node(24,18);
	this.nodes[this.nodes.length]=new Node(24,19);
	
	/* 蛇會走一步 */
	this.step=function () {
		//計算出頭結點  把頭節點添加到nodes數組中
		var oldHead=this.nodes[0];
		var newHead;
		switch (DIR){
			case UP:
				if(oldHead.y-1<0){
					newHead=new Node(oldHead.x, 49);
				}else{
					newHead=new Node(oldHead.x, oldHead.y-1);
				}
				break;
			case DOWN:
				if(oldHead.y+1>49){
					newHead=new Node(oldHead.x, 0);
				}else{
					newHead=new Node(oldHead.x, oldHead.y+1);
				}
				break;
			case LEFT:
				if(oldHead.x-1<0){
					newHead=new Node(49, oldHead.y);
				}else{
					newHead=new Node(oldHead.x-1, oldHead.y);
				}
				break;
			case RIGHT:
				if(oldHead.x+1>49){
					newHead=new Node(0, oldHead.y);
				}else{
					newHead=new Node(oldHead.x+1, oldHead.y);
				}
				break;
		}
		this.nodes.unshift(newHead);
		
		if(!this.food.equals(newHead.x, newHead.y)){
			//把尾節點刪掉 (在沒有喫到食物的時候)
			this.nodes.pop();
		}else{
			//喫到了食物 重新生成食物
			this.food=this.randomFood();
			SCORE+=10;
			SPEED-=50;
			endPrint();
			startPrint();
		}
	};
	
	/* 判斷i,j節點是否是當前蛇身子的一部分 */
	this.contains=function (i, j) {
		for(k=0; k<this.nodes.length; k++){
			var node=this.nodes[k];
			if(node.x==i && node.y==j){
				return true;
			}
		}
		return false;
	};
	
	//聲明生成食物的方法
	this.randomFood=function () {
		var x;
		var y;
		do{
			x=Math.floor(Math.random()*50);
			y=Math.floor(Math.random()*50);
		}while(this.contains(x, y));
		return new Node(x, y);
	};
	
	//聲明食物
	this.food=this.randomFood();
	
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章