思路:
1.创建画布
2.创建的蛇头、身体、食物
3.蛇头、身体、食物随机产生坐标
4.设置蛇头的初始方向
5.设置按键改变蛇头方向
6.开启定时器,自动移动蛇头
7.判断是否吃到食物
8.碰撞则随机产生食物
9.食物被吃掉,蛇加一节,去掉原来的食物,生成新的食物
10.蛇跑起来:下一节到前一节的位置,蛇头根据方向变,删除原来的蛇,新建蛇;当出界时,游戏结束;当蛇头吃到自己的时候,游戏结束
<!DOCTYPE html>
<html>
<head>
<title></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="800" height="600" id="canvas"></canvas>
</body>
<script>
$(function(){
function Draw(canvas){ //创建一个draw对象
this.canvas = canvas; //给drow对象复制canvas
this.check = function(){
//检测浏览器是否支持canvas
if(!this.canvas.getContext){
return false; //表示不支持返回false
}else{
return true; //表示支持返回true
}
}
this.main = function(){
//检测兼容
if(!this.check()){
console.log('浏览器不支持canvas');
return false;//表示不支持返回false
}
//获取canvas绘制上下文
Draw.prototype.xt = this.canvas.getContext('2d');
var snake = new Snake(this); //创建蛇的对象
snake.draw(); //调用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);
}
},200);
}
}
//随机产生食物
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,y,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;//第一个矩形的x最小边
var R2_min_x = rect2.x;//第二个矩形的x最小边
var R1_min_y = rect1.y;//第一个矩形的y最小边
var R2_min_y = rect2.y;//第二个矩形的y最小边
var R1_max_x = rect1.x+40;
var R2_max_x = rect2.x+40;
var R1_max_y = rect1.y+40;
var R2_max_y = rect2.y+40;
var min_x = Math.max(R1_min_x,R2_min_x);//x最小值中的最大值
var max_x = Math.min(R1_max_x,R2_max_x);
var min_y = Math.max(R1_min_y,R2_min_y);//y最小值中的最大值
var max_y = Math.min(R1_max_y,R2_max_y);
if(min_x<max_x && min_y<max_y){
return true;//碰撞一起返回true
}else{
return false;//没碰撞一起返回false
}
}
//判断举行是否重合
function Rect(x,y,width,height,color){
this.x=x; //矩形起始点x坐标
this.y=y; //矩形起始点y坐标
this.width = width; //矩形的宽度
this.height = height; //矩形的高度
this.color = color; //矩形的填充颜色
}
Rect.prototype.draw = function(){//画矩形
Draw.prototype.xt.beginPath(); //在Draw添加画笔
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,obj.canvas.height/2-20,40,40,'red');
//蛇身
this.body =[];//表示多个身体
var x = this.head.x - 40; //定义第一个蛇身的位置 蛇头的位置width/2-20-40
var y = this.head.y; // 竖直距离相同
//循环创建身体
for (var i = 0; i < 3; i++) { //创建3个身体
var rect = new Rect(x,y,40,40,'gray');//创建矩形一个蛇的身体宽高40,颜色灰色
this.body.push(rect); //每创建一个对象推一个rect到身体
x -=40; //x每个-40,y不变
}
}
//添加蛇默认的移动方向 向右 公有属性任何地方可以修改访问 实例共享
Snake.prototype.direction = 1;
//画蛇的方法
this.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);
//从起始位置往后宽高40填充红色
//去掉一个尾巴
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;
}
//添加键盘监听
$(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;
}
})
var draw = new Draw($('#canvas')[0]);//创建一个绘图的实例对象
draw.main();//调用main绘制函数
var rect1 = new Rect(0,0,40,40);
var rect2 = new Rect(0,0,40,40);
console.log(isRectHit(rect1,rect2));
})
</script>
</html>