写给室友的贪吃蛇网页版

写给室友的贪吃蛇网页版

0x00 效果图

​ 目前此html页面已经挂载在这个页面(已经取消挂载了,可以直接复制下方代码本地执行),可以点进去玩试试,做了一丢丢的屏幕自适应工作

image-20200919183205792

0x01 代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,
    width=device-width,initial-scale=1.0" />
    <title>snake</title>
    <meta name="author"  content="nightmare-man">
    <meta name="description" content="life if char,study is long long.">
	<meta name="keywords"  content="student,211本科">
	<style>
		html{ height:100%; overflow:hidden;}

		body{ background:blueviolet; height:100%;}
		* {
			border-style: none;
			outline-style: none;
			margin: 0;
			padding: 0;
		}
		#my_canvas {
			position: absolute;
			left: 0px;
			top: 0px;
			width: 100%;
			height: 100%;
		}
		#input-div{
			position: absolute;
			left: 0px;
			top: 0px;
			width: 100%;
			height: 100%;
			z-index: 100;
		}
		button{
			position: absolute;
			opacity: 0.2;
			background-color: cornflowerblue;
			z-index: 100;
		}
		</style>
</head>

<body >
	<div id="video-div">
		<canvas id="my_canvas" onclick="player_input(event)">
	
		</canvas>
		
	</div>	
	<div id="input-div">

		<button id="play" onclick="start_or_pause();">play</button>
		<button id="up" onclick="new_position=0;">up</button>
		<button id="down" onclick="new_position=3;">down</button>
		<button id="left" onclick="new_position=2;">left</button>
		<button id="right" onclick="new_position=1;">right</button>
	</div>	
	
	<script>
		
		function start_or_pause(){
			if(game_status==0){

				b_p.innerHTML="pause";
				game_status=1;
			}else if(game_status==1){
				b_p.innerHTML="play";
				game_status=0;
			}else{
				clear_screen(mc);
				new_position=3;
				old_position=3;
				score=0;
				hungry_time=0;//记录没有吃到东西的时间 到达一定时间 就会生成另一个
				game_status=0;//0是暂停停止 1是运行 3是游戏结束 
				game_tick=25;
				snake_block=[[Math.floor( col_cnt/2-1),Math.floor( row_cnt/2)],[Math.floor( col_cnt/2),Math.floor( row_cnt/2)],[Math.floor( col_cnt/2+1),Math.floor( row_cnt/2)]];
				food_block=[];
				barrier_block=[];
				speed=20;
				speed_cnt=0;
				try_time=0;
				b_p.innerHTML="play";
				add_barrier();
				add_food();
				draw_snake(snake_block,mc,block_width);
                game_status=0;
				//game_tick=null;
			}
		}
		function clear_screen(my_canvas){
			var ctx=my_canvas.getContext("2d");
			ctx.clearRect(0,0,my_canvas.width,my_canvas.height);
		}
		function free_block(head){
			var ret=0;
			barrier_block.forEach(function(elem){
				if(elem[0]===head[0]&&elem[1]===head[1]){//吃东西了
					ret=-1;
				}
			});
			snake_block.forEach(function(elem){
				if(elem[0]===head[0]&&elem[1]===head[1]){//吃东西了
					ret=-1;
				}
			});
			return ret;
		}
		function add_food(){
			var new_food=[1,1];
			

			new_food[0]=parseInt( Math.random()*col_cnt);
			new_food[1]=parseInt(Math.random()*row_cnt);
			while(free_block(new_food)==-1){
				new_food[0]=parseInt( Math.random()*col_cnt);
			new_food[1]=parseInt(Math.random()*row_cnt);
			}
			
			
			food_block.push(new_food);
			
			
		}
		function add_barrier(){
			var new_food=[1,1];
			
			new_food[0]=parseInt( Math.random()*col_cnt);
			new_food[1]=parseInt(Math.random()*row_cnt);
			
			
			
			barrier_block.push(new_food);
		}
		function draw_snake(snake_block,my_canvas,block_width){
			var ctx=my_canvas.getContext("2d");
			
		ctx.font="20px Arial";
		ctx.fillText("score:"+score+" speed:"+Math.floor(speed-score/5),10,globalHeight-20);
			barrier_block.forEach(function(elem){
				ctx.fillStyle="#0000ff";
				ctx.fillRect(elem[0]*block_width,elem[1]*block_width,block_width,block_width);
			});
			food_block.forEach(function(elem){
				ctx.fillStyle="#ff0000";
				ctx.fillRect(elem[0]*block_width,elem[1]*block_width,block_width,block_width);
			});
			snake_block.forEach(function(elem,idx){
				
				
				if(idx==0){
					ctx.fillStyle="#000000";//黑色为蛇头
				}else{
					ctx.fillStyle="#222222";//灰色为蛇身体
				}
				
				ctx.fillRect(elem[0]*block_width,elem[1]*block_width,block_width,block_width);
			});
		}
		//以下进行移动 返回新的 snake_block数组
		function move_snake(snake_block,max_col,max_row,game_tick){
			var last_node=snake_block.pop();//删除最后一个
			var new_head=[1,1];
			new_head[0]=snake_block[0][0];
			new_head[1]=snake_block[0][1];
			if(new_position+old_position==3){
				new_position=old_position;//不允许直接倒车
			}
			switch(new_position){
				case 0:{
					new_head[1]--;//向上
					break;
				}
				case 1:{
					new_head[0]++;//向右
					break;
				}
				case 2:{
					new_head[0]--;
					break;
				}
				case 3:{
					new_head[1]++;
					break;
				}
			}
			old_position=new_position;//移动完成后更新old_position;


			if(new_head[0]>=max_col||new_head[0]<0||new_head[1]<0||new_head[1]>=max_row){//检测撞墙
				clearInterval(game_tick);
				alert("your snake crash!");
				game_status=2;
				b_p.innerHTML="restart";
			}
			
			if(free_block(new_head)===-1){
				clearInterval(game_tick);
				alert("your snake crash!");
				game_status=2;
				b_p.innerHTML="restart";
			}
			var eat_flag=0;
			food_block.forEach(function(elem,idx){
				if(elem[0]===new_head[0]&&elem[1]===new_head[1]){//吃东西了
					food_block.splice(idx,1);
					snake_block[snake_block.length]=last_node;
					score++;
					add_food();
					add_barrier();
					try_time=0;
					eat_flag=1;
				}
			});
			if(eat_flag==0){
				try_time++;
				if(try_time>40){
					add_food();
					try_time=0;
				}
			}
			snake_block_head=[new_head];
			snake_block=snake_block_head.concat(snake_block);
			return snake_block;
		}
		//以下是代码主线程
		var mc=document.getElementById("my_canvas");
		var globalHeight=document.body.clientHeight;
		var globalWidth=document.body.clientWidth; 
		var min_length;
		var col_cnt;
		var block_width;
		var row_cnt;
		
		var b_p=document.getElementById("play");
		var b_u=document.getElementById("up");
		var b_d=document.getElementById("down");
		var b_l=document.getElementById("left");
		var b_r=document.getElementById("right");
		var b_list=[b_p,b_l,b_r,b_u,b_d];

		if(globalHeight>globalWidth){//竖屏
			min_length=globalWidth;
			if(globalHeight>1.5*globalWidth){
				
				col_cnt=16;
			}else{
				col_cnt=20;
				
			}
			
			
			block_width=Math.floor( min_length/col_cnt);
			row_cnt=Math.floor(globalHeight/block_width);
		}else{
			min_length=globalHeight;
			
			if(globalWidth>1.5*globalHeight){
				
				row_cnt=16;
			}else{
				row_cnt=20;
				
			}
			
			block_width=Math.floor( min_length/row_cnt);
			col_cnt= Math.floor( globalWidth/block_width);
		}

		var b_lenghth=Math.floor(min_length/((globalHeight>globalWidth?col_cnt:row_cnt)/2));
		b_list.forEach(function(elem){
			elem.style.width=b_lenghth+"px";
			elem.style.height=b_lenghth+"px";
		});

		var center_b_left=Math.floor(globalWidth/2-b_lenghth/2);
		var center_b_top=Math.floor(globalHeight/2+globalHeight/4-b_lenghth/2);
		b_p.style.left= center_b_left+"px" ;
		b_p.style.top=center_b_top+"px" ;

		b_l.style.left=(center_b_left-b_lenghth)+"px";
		b_l.style.top=(center_b_top)+"px";

		b_r.style.left=(center_b_left+b_lenghth)+"px";
		b_r.style.top=(center_b_top)+"px";

		b_u.style.left=(center_b_left)+"px";
		b_u.style.top=(center_b_top-b_lenghth)+"px";

		b_d.style.left=(center_b_left)+"px";
		b_d.style.top=(center_b_top+b_lenghth)+"px";


		
		mc.width=globalWidth;
		mc.height=globalHeight;
		var new_position=3;
		var old_position=3;
		var score=0;
		var hungry_time=0;//记录没有吃到东西的时间 到达一定时间 就会生成另一个
		var game_status=0;//0是暂停停止 1是运行 2是游戏结束 
		var game_tick=25;
		var snake_block=[[Math.floor( col_cnt/2-1),Math.floor( row_cnt/2)],[Math.floor( col_cnt/2),Math.floor( row_cnt/2)],[Math.floor( col_cnt/2+1),Math.floor( row_cnt/2)]];
		var food_block=[];
		var barrier_block=[];
		var speed=20;
		var speed_cnt=0;
		var try_time=0;
		b_p.innerHTML="play";
		add_barrier();
		add_food();
		draw_snake(snake_block,mc,block_width);
		setInterval(function(){
			speed_cnt++;
			if(speed_cnt>Math.floor(speed-score/5)&&game_status==1){
				speed_cnt=0;
				clear_screen(mc);
				snake_block=move_snake(snake_block,col_cnt,row_cnt,game_tick);
				draw_snake(snake_block,mc,block_width);
			}
		},game_tick);
	</script>
</body>
</html>