<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.js"></script>
<style>
canvas{
box-shadow: 0 0 10px #000;
display: block;
margin:20px auto;
}
</style>
</head>
<body>
<canvas width="1200" height="800" id="canvas"></canvas>
</body>
<script>
$(function(){
// var draw = new Draw($('#canvas')[0]); //创建一个绘图的实例对象
// draw.main();//调用main绘制图像
function Draw(canvas){
// 初始化
this.canvas = canvas;
// 创建check函数
this.check = function(){
// 检测浏览器是否支持canvas
if (!this.canvas.getContext) {
//如果符合就输出false
return false;
// 否则输出true
}else{
return true;
}
}
this.main = function(){
// 检测兼容
if (!this.check()) {
// 如果符合就打印显示浏览器不支持canvas输出false
console.log('浏览器不支持canvas');
return false;
}
// 绘画上下文
Draw.prototype.xt = this.canvas.getContext('2d');
// 创建蛇 画出初始的蛇
var snake = new Snake(this);
snake.draw();
// 随机产生一个食物 画出初始的食物
var food = randFood(snake);
food.draw();
// 做一个动画的定时器
Draw.prototype.timer = setInterval(function(){
// 清楚旧的图像
Draw.prototype.xt.clearRect(0,0,this.canvas.width,this.canvas.height);
// 改变蛇的位置
if (!snake.move()) {
clearInterval(Draw.prototype.timer);
alert('游戏结束');
}
// 重新绘制图像
snake.draw();
food.draw();
if (isRectHit(food,snake.head)) {
Snake.prototype.isEatFood = true;
// 重新产生食物
food = randFood(snake);
}
},80);
}
}
// 蛇头(准备创建的方块)的元素
function Rect(x,y,width,height,color){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
// 完善矩形 绘制矩形
Rect.prototype.draw = function(){
// 开始绘画矩形
Draw.prototype.xt.beginPath();
// 画笔颜色
Draw.prototype.xt.fillStyle = this.color;
// 填充矩形
Draw.prototype.xt.fillRect(this.x,this.y,this.width,this.height);
// 描边
Draw.prototype.xt.strokeRect(this.x,this.y,this.width,this.height);
}
// 构造对象蛇
function Snake(obj){
// 画蛇头 蛇头的颜色是红色的
this.head = new Rect(obj.canvas.width/2-20,obj.canvas.height/2-20,40,40,'red');
//定义一个空数组存放组成整蛇的方块对象
this.body = []; //表示多个身体
// 蛇身的x比蛇头移动40
var x = this.head.x-40;
// 距离y不变
var y = this.head.y;
// 循环创建身体 默认蛇的长度是3
for (var i = 0; i < 3; i++) {
// 每吃一个东西蛇身会加一个 蛇身的颜色是灰色的
var rect = new Rect(x,y,40,40,'gray');
this.body.push(rect);
x-=40;
}
}
// 添加蛇默认的运动方向 向右
// 公有属性,任何地方能够修改方向
Snake.prototype.direction = 1;
// 定义一个是否吃到食物的标记
Snake.prototype.isEatFood = false;
// 画蛇方法
Snake.prototype.draw = function(){
// 画蛇头
this.head.draw();
// 循环创建蛇身
for (var i = 0; i < this.body.length; i++) {
this.body[i].draw();
}
}
// 蛇移动的方法
Snake.prototype.move = function(){
// 检测碰撞到墙壁
if (this.head.x<40 || this.head.y<-40 || this.head.x>$('#canvas')[0].width-40-40 || this.head.y>$('#canvas')[0].height-40-40) {
return false;
}
// 检测蛇头与蛇身
for (var i =0;i<this.body.length;i++) {
console.log(this.body[i])
if (isRectHit(this.head,this.body[i])) {
return false;
}
}
// 加一个头
var rect = new Rect(this.head.x,this.head.y,40,40,'gray');
// 添加身体开始的地方
this.body.splice(0,0,rect);
// 去掉一个尾巴,
if (Snake.prototype.isEatFood) {
Snake.prototype.isEatFood = false;
// 重新随机产生食物
}else{
this.body.pop();
}
switch(this.direction){
case 0:
this.head.y -= 40
break;
case 1:
this.head.x += 40
break;
case 2:
this.head.y +=40
break;
case 3:
this.head.x -= 40
break;
}
return true;
//判定吃到食物,即蛇头坐标与食物坐标重合
function isEatFood () {
if (Snake.head.x == food.x && Snake.head.y == food.y){
return true;
} else {
return false;
}
}
}
// 添加键盘监听
$(window).keydown(function(e){
switch(e.keyCode){
case 37:
// 如果当前的方向是向右的,不能改为向左
if (Snake.prototype.direction == 1) {
return;
}
Snake.prototype.direction = 3;
break;
case 38:
// 如果当前的方向是向下的,不能改为向上
if (Snake.prototype.direction == 2) {
return;
}
Snake.prototype.direction = 0;
break;
case 39:
if (Snake.prototype.direction == 3) {
return;
}
Snake.prototype.direction = 1;
break;
case 40:
if (Snake.prototype.direction == 0) {
return;
}
Snake.prototype.direction = 2;
break;
}
})
// 随机产生食物
function randFood(snake){
// 是否在蛇身上
isInSnake = true;
while(isInSnake){
// 产生两个位置 x,y
var x = getRandPosition(0,($('#canvas')[0].width-40)/40)*40;
var y = getRandPosition(0,($('#canvas')[0].height-40)/40)*40;
// 创建食物矩形
var food = new Rect(x-20,y-20,40,40,'green');
isInSnake = false;
// 判断这个位置是否在蛇身
// 是否是蛇头
if (isRectHit(food,snake.head)) {
isInSnake = true;
continue;
}
// 是否是蛇身
for (var i=0; i < snake.body.length; i++) {
if (isRectHit(food,snake.body[i])) {
isInSnake = true;
break;
}
}
}
return food;
}
// 产生随机数的函数
function getRandPosition(min,max){
return Math.round(Math.random()*(max-min)+min);
}
// 判断矩形是否重合
function isRectHit(rect1,rect2){
var R1_min_x = rect1.x;
var R1_min_y = rect1.y;
var R2_min_x = rect2.x;
var R2_min_y = rect2.y;
var R1_max_x = rect1.x + 20;
var R2_max_x = rect2.x + 20;
var R1_max_y = rect1.y + 20;
var R2_max_y = rect2.y + 20;
// 两个图形的最大边界和最小边界
var min_x = Math.max(R1_min_x,R2_min_x);
var max_x = Math.min(R1_max_x,R2_max_x);
var min_y = Math.max(R1_min_y,R2_min_y);
var max_y = Math.min(R1_max_y,R2_max_y);
if (min_x<max_x&&min_y<max_y) {
return true;
}else{
return false;
}
}
var draw = new Draw($('#canvas')[0]); //创建一个绘图的实例对象
draw.main();//调用main绘制图像
});
</script>
<ml>