html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
body {
text-align: center;
padding-top: 50px;
}
</style>
<canvas width="600" height="600" style="box-shadow: 0 0 10px #333;" id="canvas"></canvas>
<script src="canvas17.js"></script>
</body>
</html>
<!--
1先把蛇画出来
蛇头和蛇的身子
2蛇动起来
添加键盘事件
animate运动
3随机投放食物
坐标位置
食物是否投放到了蛇头和蛇的身子上(数组排重)
4吃食物
碰撞检测
将蛇的身加一
5边缘检测
判断游戏是否结束
-->
js代码:
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var isEatFood = false;
var timer;
function Rect(x, y, width, height, color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
Rect.prototype.rDraw = function () {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
ctx.strokeRect(this.x, this.y, this.width, this.height);
ctx.closePath();
}
//创建snake对象
function Snake() {
//蛇头
this.head = new Rect(canvas.width / 2 - 20, canvas.height / 2 - 20, 20, 20, 'red');
//蛇身
this.body = new Array();
var x = this.head.x - 20;
var y = this.head.y;
for (var i = 0; i < 3; i++) {
var rect = new Rect(x, y, 20, 20, 'gray');
this.body.push(rect);
x -= 20;
this.direction = 2;
}
}
var snake = new Snake();
}
Snake.prototype.sDraw = function () {
//绘制蛇头
this.head.rDraw();
//绘制蛇身
for (var i = 0; i < this.body.length; i++) {
this.body[i].rDraw();
}
}
snake.sDraw();
// 加头去尾
Snake.prototype.move = function () {
//加头
var rect = new Rect(this.head.x, this.head.y, this.head.width, this.head.height, 'gray');
this.body.splice(0, 0, rect); //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
//去尾
if (isEatFood == false) { //正常没有碰到食物
this.body.pop();
} else {
isEatFood = false;
}
// this.body.pop(); pop() 方法用于删除并返回数组的最后一个元素。
switch (this.direction) {
case 0: {
this.head.x -= this.head.width;
break;
}
case 1: {
this.head.y -= this.head.height;
break;
}
case 2: {
this.head.x += this.head.width;
break;
}
case 3: {
this.head.y += this.head.height;
break;
}
}
if (this.head.x >= canvas.width || this.head.x < 0 || this.head.y >= canvas.height || this.head.y <= 0) {
clearInterval(timer);
// timer = null;
alert('Game over !!!');
}
for (var i = 0; i < this.body.length; i++) {
if (isRectHit(this.head, this.body[i])) {
clearInterval(timer);
timer = null;
alert('Game over !!!');
}
}
}
function randForFood() {
var isInsnake = true;
while (isInsnake) {
var x = getRandInRange(0, (canvas.width - 20) / 20) * 20;
var y = getRandInRange(0, (canvas.height - 20) / 20) * 20; //格子换成坐标 * 20
//食物矩形
var rect = new Rect(x, y, 20, 20, 'blue');
//判断食物与头重叠
if (isRectHit(snake.head, rect)) {
isInsnake = true;
continue;
}
isInsnake = false;
//判断食物是否与蛇身重叠
for (var i = 0; i < snake.body.length; i++) {
if (isRectHit(snake.body[i], rect)) {
isInsnake = true;
break;
}
}
}
return rect;
}
function isRectHit(rect1, rect2) {
var minX1 = rect1.x;
var minX2 = rect2.x;
var minY1 = rect1.y;
var minY2 = rect2.y;
var maxX1 = rect1.x + rect1.width;
var maxX2 = rect2.x + rect2.width;
var maxY1 = rect1.y + rect1.height;
var maxY2 = rect2.y + rect2.height;
//判断矩形相交的最大/最小值
var minX = Math.max(minX1, minX2);
var minY = Math.max(minY1, minY2);
var maxX = Math.min(maxX1, maxX2);
var maxY = Math.min(maxY1, maxY2);
if (minX < maxX && minY < maxY) {
return true;
} else {
return false;
}
}
function getRandInRange(min, max) {
return Math.round(Math.random() * (max - min) + min);//格子做表 round() 方法可把一个数字舍入为最接近的整数 ?man,min哪来的
}
var food = randForFood();
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
snake.move();
snake.sDraw();
food.rDraw();
if (isRectHit(snake.head, food)) {
// console.log('吃到了');
isEatFood = true;
food = randForFood();
}
}
timer = setInterval(animate, 50);
document.onkeydown = function (e) {
var event = e || window.event;
switch (event.keyCode) {
case 37: {
snake.direction = 0;
break;
}
case 38: {
snake.direction = 1;
break;
}
case 39: {
snake.direction = 2;
break;
}
case 40: {
snake.direction = 3;
break;
}
}
}
unction Rect() -->初始化正方形
Rect.prototype.rDraw -->画出正方形
function Snake() -->蛇的初始形状(最开始的几节蛇的身体 以及包含的逻辑关系)
Snake.prototype.sDraw -->画出蛇(可以用上画正方形的方法即rDraw)
Snake.prototype.move -->(这里面只是包含了 1碰到食物和没有碰到食物的情况 2 做出改变方向 3 判断是否触壁)
function randForFood() -->判断是否相交
function animate(); -->整个运动过程(用定时器让整体动起来)
function isRectHit(); -->相交条件
document.onkeydown(e); -->键盘绑定事件