效果图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>贪吃蛇</title>
<link rel="stylesheet" href="css/snake.css">
<script src="js/snake.js"></script>
</head>
<body>
<div class="snake-wrap">
<div class="info-bd">
<div class="info-item">
得分:<span class="score">0</span>分
</div>
<div class="info-item">
用时:<span class="second">0</span>秒
</div>
</div>
<div class="game-bd">
<canvas id="gameCan" width="600" height="600"></canvas>
</div>
<div class="btn-group">
<div class="btn">
<button class="j-start">开始</button>
</div>
<div class="btn">
<button class="j-pause">暂停</button>
</div>
<div class="btn">
<button class="j-reset">重置</button>
</div>
</div>
</div>
</body>
</html>
button{
outline: none;
border: none;
}
.snake-wrap{
width: 600px;
height: 720px;
margin: 50px auto;
background: limegreen;
}
.info-bd{
height: 60px;
}
.info-bd .info-item{
float: left;
width: 50%;
height: 100%;
text-align: center;;
font-size: 20px;
line-height: 60px;
color: #fff;
}
.game-bd{
height: 600px;
background: #000;
}
.btn-group{
height: 60px;
}
.btn-group .btn{
width: 33.3%;
float: left;
height: 100%;
}
.btn-group .btn button{
background: transparent;
width: 100%;
height: 100%;
color: #fff;
font-size: 20px;
cursor: pointer;
}
.btn-group .btn button:hover{
background: lime;
}
.btn-group .btn button:disabled{
background: lightgreen;
}
window.onload = function(){
var can = document.getElementById('gameCan'),
oStart = document.getElementsByClassName('j-start')[0],
oPause = document.getElementsByClassName('j-pause')[0],
oReset = document.getElementsByClassName('j-reset')[0],
oSecond = document.getElementsByClassName('second')[0],
oScore = document.getElementsByClassName('score')[0],
ctx = can.getContext('2d'),
//画布width
cWidth = ctx.canvas.width,
//画布Height
cHeight = ctx.canvas.height,
//半径
r = 10,
//游戏用时
second = 0;
//定时器
t = null,
//得分
score = 0;
//用时时间定时器
st = null,
//每次移动增加的坐标
size = r * 2,
//初始蛇的长度
bodyNum = 3;
//实例化
var s = new Snake();
//键盘事件
document.onkeydown = function(){
var e = e || window.event;
var code = e.keyCode;
if(code === 38){
s.dir = s.dir !== "DOWN" ? "UP" : "DOWN";
}else if(code === 40){
s.dir = s.dir !== "UP" ? "DOWN" : "UP";
}else if(code === 37){
s.dir = s.dir !== "RIGHT" ? "LEFT" : "RIGHT";
}else if(code === 39){
s.dir = s.dir !== "LEFT" ? "RIGHT" : "LEFT";
}
}
oPause.onclick = function(){
pause.call(this);
}
oReset.onclick = function(){
reset.call(this);
}
oStart.onclick = function(){
start.call(this);
}
//构造函数
function Body(x,y,c){
this.x = x;//横坐标
this.y = y;//纵坐标
this.c = c;//color
}
Body.prototype.draw = function(){
//绘制圆形填充色
ctx.fillStyle = this.c;
//开始绘制
ctx.beginPath();
//绘制圆形
ctx.arc(this.x + r,this.y + r,r,0,2 * Math.PI,false);
//填充
ctx.fill();
}
//绘制蛇
function Snake(){
this.snakeArr = [];
this.bodySize = this.snakeArr.length || bodyNum;
//初始方向
this.dir = 'DOWN',
cWidth = cWidth,
cHeight = cHeight;
for(var i = 0;i < this.bodySize; i ++){
this.snakeArr.push(
new Body(0,i * r * 2,(i === this.bodySize - 1?'red':'green'))
)
}
}
//让蛇运动
Snake.prototype.move = function(){
//清除画布
ctx.clearRect(0,0,cWidth,cHeight);
var head = this.snakeArr[this.snakeArr.length - 1];//蛇头
var _this = this;
var snakeArr = _this.snakeArr;
createFood(snakeArr);
t = setInterval(function(){
for(var i = 0; i <_this.snakeArr.length; i++){
ctx.clearRect(snakeArr[i].x,snakeArr[i].y,size,size);
if( i !== snakeArr.length - 1){
//第一个坐标等于第二个坐标 变更坐标
snakeArr[i].x = snakeArr[i + 1].x;
snakeArr[i].y = snakeArr[i + 1].y;
}
}
//判断方向以及坐标变换
if(_this.dir === "DOWN"){
head.y = head.y == cHeight ? 0 : (head.y + size);
}else if(_this.dir === "UP"){
head.y = head.y == -size ? (cHeight - size) : (head.y - size);
}else if(_this.dir === "RIGHT"){
head.x = head.x == cWidth ? 0 : (head.x + size);
}else if(_this.dir === "LEFT"){
head.x = head.x == -size ? (cWidth - size) : (head.x - size);
}
for(var i = 0; i < snakeArr.length; i++){
//绘制圆
snakeArr[i].draw();
if( i != snakeArr.length - 1){
//判断蛇头碰到蛇身体
if(head.x === snakeArr[i].x && head.y === snakeArr[i].y){
//清除定时器
clearInterval(t);
ctx.clearRect(0,0,cWidth,cHeight);
alert("GAME OVER");
reset();
return;
}
}
}
//蛇吃到食物
if(s.foodX === head.x && s.foodY === head.y){
var x,
y;
score ++;
oScore.innerText = score;
createFood(snakeArr);
if(snakeArr[0].x === snakeArr[1].x){
x = snakeArr[0].x;
if(snakeArr[0].y > snakeArr[1].y){
y = snakeArr[0].y + size;
}else if(snakeArr[0].y < snakeArr[1].y){
y = snakeArr[0].y - size;
}
}else if(snakeArr[0].y === snakeArr[1].y){
y = snakeArr[0].y;
if(snakeArr[0].x > snakeArr[1].x){
x = snakeArr[0].x + size;
}else if(snakeArr[0].x < snakeArr[1].x){
x = snakeArr[0].x - size;
}
}
snakeArr.unshift(new Body(x,y,'green'));
}
},200)
}
//绘制食物
function createFood(snakeArr){
s.foodX = setRandPos().x;
s.foodY = setRandPos().y;
for(var i = 0; i <snakeArr.length; i++){
if(s.foodX === snakeArr[i].x && s.foodY === snakeArr[i].y){
s.foodX = setRandPos().x;
s.foodY = setRandPos().y;
}
}
new Body(s.foodX,s.foodY,'yellow').draw();
}
//食物的随机坐标
function setRandPos(){
var arr = [];
for(var i = 0; i < cWidth - size;i++){
if(i%size == 0){
arr.push(i);
}
}
return {
x:arr[Math.floor(Math.random() * arr.length +1) - 1],
y:arr[Math.floor(Math.random() * arr.length +1) - 1]
}
}
function start(){
s.move();
this.disabled = "disabled";
oPause.disabled = "";
st = setInterval(function(){
second ++;
oSecond.innerText = second;
},1000)
}
function pause(){
clearInterval(st);
clearInterval(t);
this.disabled = "disabled";
oStart.disabled = "";
}
function reset(){
clearInterval(st);
clearInterval(t);
oStart.disabled = "";
oPause.disabled = "";
oSecond.innerText = 0;
oScore.innerText = 0;
ctx.clearRect(0,0,cWidth,cHeight);
s = new Snake();
}
}
想要获得更多资料的 请微信搜索公众号 【热血科技】,关注一下即可。