写给室友的贪吃蛇网页版
写给室友的贪吃蛇网页版
0x00 效果图
目前此html页面已经挂载在这个页面(已经取消挂载了,可以直接复制下方代码本地执行),可以点进去玩试试,做了一丢丢的屏幕自适应工作
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>