<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src='js/jquery.min.js'></script>
<style>
#canvas{
box-shadow: 0 0 10px #000;
margin: 20px auto;
display: block;
}
</style>
</head>
<body>
<canvas id="canvas" width='1000' height='800'></canvas>
</body>
<script>
$(function(){
//canvas繪圖的構(gòu)造函數(shù)
function Draw(canvas){
this.canvas = canvas;//Draw私有屬性傳入dom獲取canvas;
//檢測(cè)兼容
this.check = function(){
if(!this.canvas.getContext){//如果this.canvas.getContext不存在就返回false如果存在就返回true
return false;
}else{
return true;
}
}
//繪圖的主函數(shù)
this.main = function(){
//判斷私有方法check()返回來(lái)的是什么如果是true就跳過
if(!this.check()){
console.log('瀏覽器不支持canvas')
}
//開整獲取畫筆
Draw.prototype.xt = this.canvas.getContext('2d')
//創(chuàng)建蛇
var snake = new Snake(this)
//畫蛇
snake.draw();
//產(chǎn)生食物
var food = randFood(snake);
food.draw();
//動(dòng)畫定時(shí)器
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('游戲結(jié)束')
}
//重新繪制蛇
snake.draw();
food.draw()
if(isRectHit(food,snake.head)){
Snake.prototype.isEatFood = true;
food = randFood(snake);
}
},100)
}
}
//創(chuàng)建矩形構(gòu)造函數(shù)
function Rect(x,y,width,height,color){
this.x= x; //創(chuàng)建私有屬性
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);//創(chuàng)建填充矩形
Draw.prototype.xt.strokeRect(this.x,this.y,this.width,this.height)//創(chuàng)建描邊矩形
}
//創(chuàng)建蛇
function Snake(obj){
this.head = new Rect(obj.canvas.width/2-20,obj.canvas.height/2,40,40,'red') //蛇頭喜庞,根據(jù)Rect構(gòu)造函數(shù)創(chuàng)建的實(shí)例對(duì)象
this.body = [] //蛇身
var x = this.head.x - 40; //定義變量
var y = this.head.y; //定義變量
//循環(huán)創(chuàng)建身體
for(var i=0;i<3;i++){
var rect = new Rect(x,y,40,40,'green');
this.body.push(rect); //通過數(shù)組方法添加蛇身
x -= 40; //蛇身位置的調(diào)整
}
}
//默認(rèn)的移動(dòng)方向
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()
}
}
//動(dòng)
Snake.prototype.move = function(){
if(this.head.x<40 || this.head.y<40 || this.head.x>$('#canvas')[0].width-80 ||this.head.y>$('#canvas')[0].height-80){
return false;
}
for(item in this.body){
if(isRectHit(this.head,this.body[item])){
return false;
}
}
//加一個(gè)頭
var rect = new Rect(this.head.x,this.head.y,40,40,'green');
//添加到身體開始的地方
this.body.splice(0,0,rect)
//去掉尾巴
if(this.isEatFood){
Snake.prototype.isEatFood = false;
//產(chǎn)生食物
}else{
this.body.pop()//去除一個(gè)身體
}
//
//改變方向
switch(this.direction){
case 0://方向?yàn)?蛇向上走
this.head.y -=40;
break;
case 1://方向?yàn)?蛇向右走
this.head.x += 40;
break;
case 2://方向?yàn)?蛇向下走
this.head.y +=40;
break;
case 3://方向?yàn)?蛇向左走
this.head.x -=40;
break;
}
return true;
}
//添加鍵盤事件
$(window).keydown(function(e){
switch(e.keyCode){
case 37://鍵盤按左方向如果是右直接返回妙痹,如果不是方向變?yōu)樽?/p>
if(Snake.prototype.direction == 1){
return;
}
Snake.prototype.direction = 3;
break;
case 38://鍵盤按左方向如果是下直接返回如撞鹉,果不是方向變?yōu)樯?/p>
if(Snake.prototype.direction == 2){
return;
}
Snake.prototype.direction = 0;
break;
case 39://鍵盤按左方向如果是左直接返回,如果不是方向變?yōu)橛?/p>
if(Snake.prototype.direction == 3){
return;
}
Snake.prototype.direction = 1;
break;
case 40://鍵盤按左方向如果是上直接返回蠢沿,如果不是方向變?yōu)橄?/p>
if(Snake.prototype.direction == 0){
return;
}
Snake.prototype.direction = 2;
break;
}
})
//隨機(jī)產(chǎn)生食物
function randFood(snake){
var isInSnake = true;//定義默認(rèn)食物在蛇身上
//判斷食物是否在蛇身上
while(isInSnake){
//產(chǎn)生兩個(gè)位置
var x = getRandPosition(0,($('#canvas')[0].width-40)/40)*40;//x軸的位置
var y = getRandPosition(0,($('#canvas')[0].height-40)/40)*40;//y軸的位置
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; //返回一個(gè)食物矩形
}
//創(chuàng)建隨機(jī)坐標(biāo)函數(shù)
function getRandPosition(min,max){
return Math.round(Math.random()*(max-min)+min)//返回一個(gè)隨機(jī)的整數(shù)值
}
//碰撞檢測(cè)參數(shù)為兩個(gè)矩形
function isRectHit(rect1,rect2){
var R1_min_x = rect1.x;? //矩形1的x軸起始點(diǎn)
var R2_min_x = rect2.x; //矩形2的x軸起始點(diǎn)
var R1_min_y = rect1.y; //矩形1的y軸起始點(diǎn)
var R2_min_y = rect2.y; //矩形2的y軸起始點(diǎn)
var R1_max_x = rect1.x+40; //矩形1的x周的結(jié)束點(diǎn)
var R2_max_x = rect2.x+40; //矩形2的x周的結(jié)束點(diǎn)
var R1_max_y = rect1.y+40; //矩形1的y周的結(jié)束點(diǎn)
var R2_max_y = rect2.y+40; //矩形2的y周的結(jié)束點(diǎn)
var min_x = Math.max(R1_min_x,R2_min_x) //矩形1矩形2兩個(gè)中最大的x軸起始點(diǎn)
var max_x = Math.min(R1_max_x,R2_max_x) //矩形1矩形2兩個(gè)中最小的x軸結(jié)束點(diǎn)
var min_y = Math.max(R1_min_y,R2_min_y) //矩形1矩形2兩個(gè)中最大的y軸起始點(diǎn)
var max_y = Math.min(R1_max_y,R2_max_y) //矩形1矩形2兩個(gè)中最小的y軸結(jié)束點(diǎn)
//如果條件成立返回布爾值
if(min_x<max_x && min_y<max_y){
return true;
}else{
return false;
}
}
//創(chuàng)建一個(gè)實(shí)例對(duì)象
var draw? = new Draw($('#canvas')[0])
//調(diào)用主函數(shù)
draw.main();
})
</script>
</html>