javascript用canvas实现贪吃蛇

        前一阵子用纯php+session写了个贪吃蛇纯php实现贪吃蛇游戏(不使用JavaScript),这次再来个正常点儿的,JavaScript贪吃蛇,算法从上一版php贪吃蛇移植过来的,把部分php函数改成了JavaScript的方法,php版本是用table标签画蛇,JavaScript是用canvas画蛇,实现方法不一样,但算法都是一样的,下面还是先上效果图,再上代码。

 

 

         界面没仔细雕琢,很简陋,下面还是先上代码。

<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title>贪吃蛇</title>
		<style>
			body{
				overflow:hidden;
				background:#000;
			}
			canvas{
				position:absolute;
				top:10px;
				left:6px;
				background:#000;
				border:1px solid green;
			}
			.ctrl{
				position:absolute;
				top:430px;
				left:6px;
				width: 400px;
				background:#000;
				border:1px solid green;
			}
			button{
				background: green;
				color: #fff;
				font-size: 30px;
				border:none;
				width:50px;
				height: 40px; 
				text-align:center;
			}
			span{
				color:green;
				font-size:20px;
			}
		</style>
	</head>
	
	
	
		<!-- 引入vConsole的JS庫 
  <script src="./frameWork/vConsole/dist/vconsole.min.js"></script>
<script>
// 初始化vConsole
window.vConsole = new window.VConsole({
  defaultPlugins: ['system', 'network', 'element', 'storage'], // 可以在此設定要默認加載的面板
  maxLogNumber: 1000,
  // disableLogScrolling: true,
  onReady: () => {
		
  },
  onClearLog: () => {
    console.log('on clearLog');
  }
});
</script>

-->
	
	
	
	
	<body>
		<canvas width="400" height="400"></canvas>
		<div class="ctrl">
			<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button onclick="snake.direction='up'">↑</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>得分:0</span></p>
			<p>&nbsp;&nbsp;<button onclick="snake.direction='left'">←</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button onclick="snake.direction='right'">→</button>&nbsp;&nbsp;&nbsp;&nbsp;<button onclick="snake.startPause()">▶</button></p>
			<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button onclick="snake.direction='down'">↓</button></p>
		</div>
	</body>
	<script>
	class Snake{
		constructor(){
			this.snake=[[19,19]];
			this.rate=200;
			this.getFood();
			this.direction="left";
			this.score=0;
			this.print("🐍");
		}
		print(str){
			let sc=document.querySelector("canvas").getContext("2d");
			sc.clearRect(0,0,400,400);
			sc.fillStyle="green";
			if(str!=undefined){
				sc.textAlign='center';
    			sc.font='bold 60px Arial';
    			sc.fillStyle="green";
    			sc.fillText(str,190,190);
				return;
			}
			sc.fillRect(this.food[0]*20,this.food[1]*20,20,20);//画食物
			for(var i in this.snake){
				sc.fillRect(this.snake[i][0]*20,this.snake[i][1]*20,20,20);
			}//画蛇
			document.querySelector("span").innerText="得分:"+this.score;
		}
		cpu(){
			let snakeHead=[];
			//计算蛇头坐标
			switch(this.direction){
				case "up":{
					snakeHead=[
						this.snake[0][0],
						this.snake[0][1]-1
					];
					break;
				}
				case "down":{
					snakeHead=[
						this.snake[0][0],
						this.snake[0][1]+1
					];
					break;
				}
				case "left":{
					snakeHead=[
						this.snake[0][0]-1,
						this.snake[0][1]
					];
					break;
				}
				case "right":{
					snakeHead=[
						this.snake[0][0]+1,
						this.snake[0][1]
					];
					break;
				}
			}
			//咬到自己,游戏结束
			if(this.inArray(snakeHead,this.snake)){
				this.gameOver();
				return;
			}
			//添加蛇头坐标
			this.snake.unshift(snakeHead);
			//撞墙,游戏结束
			if(this.snake[0][0]<0||this.snake[0][1]<0||this.snake[0][0]>19||this.snake[0][1]>19){
				this.gameOver();
				return;
			}
			//咬到食物得一分
			if(this.inArray(this.food,this.snake)){
				this.getFood();
				this.score+=1;
			}else{
				this.snake.splice(this.snake.length-1,1);
			}
		}
		getFood(){
			this.food=[Math.round(Math.random()*19),Math.round(Math.random()*19)];
			if(this.inArray(this.food,this.snake)){
				this.getFood();
			}
		}
		inArray(arr1,arr2){
			let ina=false;
			for(var i in arr2){
				if(arr2[i][0]==arr1[0]&&arr2[i][1]==arr1[1]){
					ina=true;
					break;
				}
			}
			return ina;
		}
		startPause(){
			if(this.run==null){
				document.querySelectorAll("button")[3].innerText="■";
				this.run=setInterval(function(){
					snake.cpu();
					snake.print();
				},this.rate);
			}else{
				document.querySelectorAll("button")[3].innerText="▶";
				clearInterval(this.run);
				this.run=null;
			}
		}
		gameOver(){
			this.startPause();
			this.snake=[[19,19]];
			this.getFood();
			this.direction="left";
			setTimeout(`snake.print("game over ")`,snake.rate+1);
			this.score=0;
		}
	}
		
	this.snake=new Snake();
		</script>
	</body>
</html>

        贪吃蛇无非就是添头去尾,撞墙判断和吃自己判断,通过二维数组就能实现,JavaScript不像php那样没有常驻内存,没有定时器,但是处理数组的方法还是php好用一些,比如in_array()函数,JavaScript就得自己实现一个inArray方法。

$this.cpu()方法负责计算蛇体位置数组和食物以及方向控制和得分情况

this.print()方法负责通过页面自动刷新把数据显示在屏幕上

 大体流程就是这样,代码注释比较详细了。

要是在电脑端玩最好加上键盘监听,通过键盘控制蛇体方向,这里不再赘述,很简单。

好了,今天就分享这些。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值