思路:
画蛇 食物被吃掉之后随机位置出现 食物不能随机在蛇身上 碰到墙也结束了 碰到食物变长 蛇能动 画蛇头和蛇身
2.让蛇动起来 默认的开启游戏的时候有一个方向 键盘能够控制方向 animate 定时器
3.有食物 随机投放 产生随机的位置 判断位置是否在蛇头或者蛇身上,如果在 重新产生位置,如果不在画食物
4.吃食物 判断吃到食物 碰到检测 吃到食物添加蛇身
5.判断游戏结束 蛇头碰到蛇身 蛇头碰到墙壁
直接上代码:
Documentcanvas{
box-shadow: 0 0 10px #000;
display: block;
margin: 20px auto;
}
$(function(){
//canvas绘图的构造函数
function Draw(canvas){
this.canvas = canvas;
this.check = function(){
//检测浏览器是否支持canvas
if(!this.canvas.getContext){
console.log('浏览器不支持canvas')
// 返回值是boolean false不支持 true支持
return false;
}else{
return true;
}
}
this.main = function(){
//检测兼容
if(!this.check()){
console.log('浏览器不支持canvas')
return false;
}
//把xt定义在原型对象上,方便使用
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);
//改变蛇的位置
// snake.move();
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);
}
}
// 矩形起始点x坐标 矩形起始点y坐标 矩形的宽度 矩形的高度 矩形的填充颜色 画笔 上下文
function Rect(x,y,width,height,color){
//传进来的变量 赋值给this
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,obj.canvas.height/2,40,40,'pink');
//画蛇身 身体不只一个 所以用[] 表示多个身体
this.body = [];
//第一个蛇身的位置 = 蛇头的位置-40
var x = this.head.x - 40;
//y没有发生变化 在同一水平面上
var y = this.head.y;
//循环创建身体实例
for(var i=0;i<3;i++){
var rect = new Rect(x,y,40,40,'cyan');
// 压栈 每吃一个矩形推到自己的身体里
this.body.push(rect);
// x是变化的
x -= 40;
}
}
//添加蛇默认的移动方向 向右
//公有的属性 任何地方都能修改 并与实例分享
Snake.prototype.direction = 1;
//定义一个是否吃到食物的标记
Snake.prototype.isEatFood = false;
//画蛇的方法
Snake.prototype.draw = function(){
//画蛇头
this.head.draw();
//画蛇身
for(var i=0;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(item in this.body){
// if(isRectHit(this.head,this.body[item])){
// return false;
// }
// }
for(var i=0;i
if(isRectHit(this.head,this.body[i])){
return false;
}
}
//加身体个头
var rect = new Rect(this.head.x,this.head.y,40,40,'cyan');
//添加到身体开始的地方
this.body.splice(0,0,rect);
//去掉一个尾巴
if(Snake.prototype.isEatFood){
Snake.prototype.isEatFood = false;
//重新随机产生食物
}else{
this.body.pop();
}
//确定蛇头的移动
switch(this.direction){
//改变蛇头的位置
case 0:
//向上减少 一个方格40
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;
}
})
//随机产生食物
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
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){
//第一个矩形的最小值 x轴
var R1_min_x = rect1.x;
var R2_min_x = rect2.x;
//y轴
var R1_min_y = rect1.y;
var R2_min_y = rect2.y;
//第一个矩形的最大值
var R1_max_x = rect1.x+40;
var R2_max_x = rect2.x+40;
//y轴
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);
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);
//当x轴小边的最大值小于等于x大边和y轴小边的最大值小于等于y大边同时成立 碰撞
if(min_x
//碰撞在一起返回true 否则返回false
return true;
}else{
return false;
}
};
var draw = new Draw($('#canvas')[0]);//创建一个绘图的实例对象
draw.main();//调用main绘制图像
})
效果如下:
1.png