<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#myCanvas {
background-color: burlywood;
}
</style>
</head>
<body>
<input type="button" name="btn" id="btn" value="开始" /><br />
<canvas id="myCanvas" width="1000" height="600"></canvas>
</body>
<script type="text/javascript">
var canvas = document.getElementById("myCanvas");
var pen = canvas.getContext("2d");
var btn = document.getElementById("btn");
var sankeLength = 5;
var timer = null;
btn.onclick = function() {
function Snake() {
this.x = -40;
this.y = 40;
this.w = 40;
this.h = 40;
this.color = "gray";
this.speed = 40;
// 方向
this.left = false;
this.top = false;
// 默认往右
this.right = true;
this.bottom = false;
// 用于装蛇的每个矩形块的信息(包括头部的)
this.bodys = [];
}
//snake相关的方法
Snake.prototype.drawSnake = function() {
for(var i = 0; i < this.bodys.length; i++) {
var snakeRect = this.bodys[i];
pen.beginPath();
if(i == this.bodys.length - 1) { //找出蛇身颜色黄色
pen.fillStyle = "yellow";
//其实"蛇头"是在数组中的最后一位
} else { //找出蛇头
pen.fillStyle = this.color;
}
pen.fillRect(snakeRect.x, snakeRect.y, snakeRect.w, snakeRect.h)
pen.closePath();
}
}
//处理保存蛇身的数组
Snake.prototype.savePath = function() {
var posi = {
x: this.x,
y: this.y,
w: this.w,
h: this.h
}
//把所有位置信息保存数组里
if(this.bodys.length == sankeLength) { //控制蛇长
this.bodys.shift();
}
this.bodys.push(posi);
//改变数组长度
};
//画蛇
//蛇移动
Snake.prototype.move = function() {
if(this.top) {
this.y -= this.speed;
} else if(this.bottom) {
this.y += this.speed;
} else if(this.left) {
this.x -= this.speed;
} else if(this.right) {
this.x += this.speed;
}
//自己吃自己
for(var i = 0; i < this.bodys.length; i++) {
var tempRect = this.bodys[i];
if(tempRect.x == this.x && tempRect.y == this.y) {
clearInterval(timer);
alert("game over");
}
};
//移动到超出边界的位置
if(this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) {
clearInterval(timer);
alert("game over");
}
};
//上下左右
document.onkeydown = function(ev) {
var evObj = ev || window.event;
switch(ev.keyCode) {
case 37:
if(!sna.right) {
sna.left = true;
sna.top = false;
sna.right = false;
sna.bottom = false;
}
break;
case 38:
if(!sna.bottom) {
sna.left = false;
sna.top = true;
sna.right = false;
sna.bottom = false;
}
break;
case 39:
if(!sna.left) {
sna.left = false;
sna.top = false;
sna.bottom = false;
sna.right = true;
}
break;
case 40:
if(!sna.top) {
sna.left = false;
sna.top = false;
sna.bottom = true;
sna.right = false;
}
break;
default:
break;
}
};
var sna = new Snake();
//食物food
function Food() {
this.x = 0;
this.y = 0;
this.w = 40;
this.h = 40;
this.color = "red";
}
//在A类的方法中使用B类的属性
//1 声明全局变量接受
//2 将b作为形参传给 a的方法中
//3 在A方法之前声明一个A类的对象
//Food相关方法
Food.prototype.drawFood = function() {
pen.beginPath();
pen.fillStyle = this.color;
pen.fillRect(this.x, this.y, this.w, this.h);
pen.closePath();
};
function rand(max, min) {
return parseInt(Math.random() * (max + 1 - min) + min);
}
//给食物设置位置
Food.prototype.setFoodPosition = function() {
//随机位置
this.x = rand(0, (canvas.width - this.w) / 40) * 40;
console.log(this.x);
this.y = rand(0, (canvas.height - this.h) / 40) * 40;
console.log(this.y);
for(var i = 0; i < sna.bodys.length; i++) {
var tempRect = sna.bodys[i];
//当食物出现在蛇身上
if(tempRect.x == this.x && tempRect == this.y) {
break;
}
}
// this.setFoodPosition();
};
var food = new Food();
food.setFoodPosition();
//验证
timer = setInterval(function() {
pen.clearRect(0, 0, canvas.width, canvas.height);
sna.move();
sna.savePath();
sna.drawSnake();
//
food.drawFood();
var result = checkCrash(sna, food);
if(result) {
food.setFoodPosition();
sankeLength++;
}
}, 300)
//公共方法
//矩形碰撞检测
//这个方法的使用前提:两个对象必须有x,y,w,h属性
function checkCrash(obj1, obj2) {
//求临界值
var disX = obj1.w / 2 + obj2.w / 2;
var disY = obj1.h / 2 + obj2.h / 2;
//计算两个中心点的距离
var centerX = Math.abs(
(obj2.x + obj2.w / 2) -
(obj1.x + obj1.w / 2)
);
var centerY = Math.abs(
(obj2.y + obj2.h / 2) -
(obj1.y + obj1.h / 2)
);
if(centerX < disX && centerY < disY) {
return true;
} else {
return false;
}
};
}
</script>
</html>
![](https://images2015.cnblogs.com/blog/996760/201609/996760-20160927115448547-1345308439.png)