效果图:
实现过程
- 搭建基本HTML,CSS框架
- JS实现核心游戏过程
- canvas画布上绘制地图、小蛇、食物
- 食物随机生成,不能生成在小蛇身上
- 键盘控制小蛇移动
- 小蛇成长
- 小蛇撞墙
- setInterval添加计时器
- 添加button事件
[注]:WSAD分别控制上下左右
源代码
index.html
<!DOCTYPE html>
<html>
<head>
<title>贪吃蛇</title>
<style type='text/css'>
*{margin:0;}
.map{margin:20px auto;
height:600px;
width:900px;
background:gray;
border:10px solid #AFAEB2;
border-radius:8px;
}
#timeBox{
background-color: indigo;
height: 45px;
width: 500px;
border:10px solid #AFAEB2;
border-radius:8px;
margin:20px auto;
padding-top: 4px;
font-size: 45px;
color:white;
}
.btn{
margin-left: 500px;
}
</style>
<script src="./index.js"></script>
</head>
<body>
<p>
<div id ="timeBox" align ="center">
<span id="id_H">00</span>:
<span id="id_M">00</span>:
<span id="id_S">00</span>
</div>
<div class="btn">
<input type="button" value="开始" id ="btnStart" style="width: 100px ;height: 30px;">
<input type="button" value="暂停" id ="btnPause" style="width: 100px ;height: 30px;">
<input type="button" value="新游戏" id ="btnStartANewGanme" style="width: 100px ;height: 30px;">
<input type="button" value="入门级" id ="btnSimple" style="width: 100px ;height: 30px;">
<input type="button" value="正常级" id ="btnNomal" style="width: 100px ;height: 30px;">
<input type="button" value="地狱级" id ="btnHard" style="width: 100px ;height: 30px;">
</div>
</p>
<p>
<div class="map">
<canvas id="canvas" height="600" width="900"></canvas>
</div>
</p>
</body>
</html>
index.js
window.onload = function(){
// 简化操作
function $(id){
return document.getElementById(id);
}
var c=$("canvas");
var ctx=c.getContext("2d");
//定义一条蛇
var snake =[];
//初始化蛇的长度
var snakeCount = 6;
//food
var foodx =0;
var foody =0;
//snack move speed
var moveSpeed = 150;
// direction
var togo =0;
// draw map
function drawtable()
{
// draw Vertical line
for(var i=0;i<60;i++)//画竖线
{
ctx.strokeStyle="black";
ctx.beginPath();
ctx.moveTo(15*i,0);
ctx.lineTo(15*i,600);
ctx.closePath();
ctx.stroke();
}
// draw Horizontal line
for(var j=0;j<40;j++)
{
ctx.strokeStyle="black";
ctx.beginPath();
ctx.moveTo(0,15*j);
ctx.lineTo(900,15*j);
ctx.closePath();
ctx.stroke();
}
drawSnackAndFood();
}
function drawSnackAndFood(){
for(var k=0;k<snakeCount;k++)//画蛇的身体
{
ctx.fillStyle="#000";
if (k==snakeCount-1)
{
ctx.fillStyle="blue";//蛇头的颜色与身体区分开
}
ctx.fillRect(snake[k].x,snake[k].y,15,15);//前两个数是矩形的起始坐标,后两个数是矩形的长宽。
}
// draw food
ctx.fillStyle ="black";
ctx.fillRect(foodx,foody,15,15);
ctx.fill();
}
function start()
{
for(var k=0;k<snakeCount;k++)
{
snake[k]={x:k*15,y:0};
}
addfood();
drawtable();
//在start中调用添加食物函数
}
function addfood()
{
foodx = Math.floor(Math.random()*60)*15; //随机产生一个0-1之间的数
foody = Math.floor(Math.random()*40)*15;
for (var k=0;k<snake;k++)
{
//防止产生的随机食物落在蛇身上
if (foodx==snake[k].x&&foody==sanke[k].y)
addfood();
}
}
function move()
{
document.onkeydown=function(ev){
switch(ev.keyCode)
{
case 65: togo = 1; break;
case 87: togo = 2; break;
case 68: togo = 3; break;
case 83: togo = 4; break;
default: togo = 0;
}
}
switch (togo)
{
case 1: snake.push({x:snake[snakeCount-1].x-15,y:snake[snakeCount-1].y}); break;//left
case 2: snake.push({x:snake[snakeCount-1].x,y:snake[snakeCount-1].y-15}); break;//down
case 3: snake.push({x:snake[snakeCount-1].x+15,y:snake[snakeCount-1].y}); break;//right
case 4: snake.push({x:snake[snakeCount-1].x,y:snake[snakeCount-1].y+15}); break;//up
default: snake.push({x:snake[snakeCount-1].x+15,y:snake[snakeCount-1].y});
}
snake.shift();//删除数组第一个元素
ctx.clearRect(0,0,900,600);//清除画布重新绘制
isEat();
isDead();
drawtable();
}
function isEat()//吃到食物后长度加1
{
if(snake[snakeCount-1].x==foodx&&snake[snakeCount-1].y==foody)
{
addfood();
snakeCount++;
snake.unshift({x:-15,y:-15});
}
}
function isDead()
{
if (snake[snakeCount-1].x>885||snake[snakeCount-1].y>585||snake[snakeCount-1].x<0||snake[snakeCount-1].y<0)
{
alert("You are dead,GAME OVER!!!");
window.location.reload();
}
}
function time(){
var count=0;//开始计时后的总秒数
var timer = null;
var timer2 = null;
$("btnStart").onclick=function(){
timer=setInterval(function(){
count++;
//改变显示的时分秒
$("id_S").innerHTML=showNumber(count%60);
$("id_M").innerHTML=showNumber(parseInt(count/60)%60);
$("id_H").innerHTML=showNumber(parseInt(count/3600));
},1000)
timer2= setInterval(move,moveSpeed);
drawtable();
}
$("btnPause").onclick=function(){
clearInterval(timer);
clearInterval(timer2);
}
$("btnStartANewGanme").onclick=function(){
clearInterval(timer);
clearInterval(timer2);
count=0;
$("id_S").innerHTML="00";
$("id_M").innerHTML="00";
$("id_H").innerHTML="00";
start();
}
$("btnSimple").onclick=function(){
moveSpeed =300;
}
$("btnNomal").onclick=function(){
moveSpeed =150;
}
$("btnHard").onclick=function(){
moveSpeed =65;
}
// 处理单个数字
function showNumber(num){
if(num<10)
return "0"+num;
else
return num;
}
}
// 准备开始
start();
// 等待点击按钮
time();
}