js貪吃蛇代碼分享
貪吃蛇js代碼分享
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>簡易貪吃蛇原型</title>
<style>
body,div{margin:0;padding:0;}
.snake{width:600px;height:600px;margin:0 auto;background:#ccc;position:relative;overflow:hidden;}
.snake_item{position:absolute;width:18px;height:18px;border:1px solid #000;line-height:20px;background:#666;color:#fff;text-align:center;}
.snake_food{position:absolute;width:18px;height:18px;border:1px solid #000;background:#f00;}
.gamestart,.gamerestart,.score{position:absolute;top:50%;left:0;margin-top:-20px;width:100%;height:40px;line-height:40px;text-align:center;text-align:center;}
.gamestart a,.gamerestart a{color:#333;font-size:30px;text-decoration:none;}
.gameover{position:absolute;top:50%;left:0;margin-top:-60px;color:#333;font-size:40px;width:100%;height:40px;line-height:40px;text-align:center;}
.score{margin-top:-20px;color:#333;font-size:16px;}
.gamerestart{margin-top:20px;}
</style>
<script src="//cdnjscn.b0.upaiyun.com/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
$(function(){
var snake=new Snake({wrap:$(".snake")}); //實例化一個貪食蛇
});
//貪食蛇構造函數
function Snake(opts){
this.defaults={
initSpeed:500, //初始速度
initNum:5
};
this.opt=$.extend({},this.defaults,opts);
this.wrap=this.opt.wrap; //包裹對象
this.initNum=0; //初始方塊數
this.iSpeed=0; //初始速度
this.foodX=0; //存儲隨機食物的位置
this.foodY=0;
this.eatLeft=0; //存儲吃完食物添加位置
this.eatTop=0;
this.wrapWidth=this.wrap.outerWidth();
this.wrapHeight=this.wrap.outerHeight();
this.items=null; //方塊數jq對象
this.len=0; //方塊數個數
this.itemSize=0; //方塊尺寸
this.arrLeft=[]; //存儲每個方塊的位置
this.arrTop=[];
this.timer=null;
this.curDirect=null; //當前蛇移動的方向
this.score=0; //得分
this.gameStart();
}
Snake.prototype={
constructor:Snake, //重新指定構造函數
/**
* 游戲開始方法
* @method gameOver
**/
gameStart:function(){
var _this=this;
var gameStartHtml='<div class="gamestart"><a href="javascript:;">開始游戲</a></div>';
this.wrap.append(gameStartHtml);
this.wrap.find(".gamestart a").click(function(){
_this.init();
$(this).parent().remove();
});
},
/**
* 游戲結束方法
* @method gameOver
**/
gameOver:function(){
var _this=this;
var gameOverHtml='<div class="gameover">GAME OVER</div>';
this.wrap.append(gameOverHtml);
var scoreHtml='<div class="score">您的得分:'+this.score+'</div>';
this.wrap.append(scoreHtml);
var gameRestart='<div class="gamerestart"><a href="javascript:;">重新開始</a></div>';
this.wrap.append(gameRestart);
$(document).off("keydown"); //移除鍵盤事件
this.wrap.find(".gamerestart a").click(function(){
_this.wrap.empty();
_this.init();
});
},
/**
* 初始化方法
* @method init
**/
init:function(){
var _this=this;
this.initNum=this.opt.initNum;
var itemHtml='';
//創建貪食蛇
for(var i=0;i<this.initNum;i++){
itemHtml+='<div class="snake_item"></div>';
}
this.wrap.append(itemHtml);
//重新開始游戲時重置這些屬性
this.items=this.wrap.find(".snake_item");
this.len=this.items.length;
this.itemSize=this.items.eq(0).outerWidth(true);
this.arrLeft=[];
this.arrTop=[];
this.iSpeed=this.opt.initSpeed;
this.curDirect="right";
this.score=0;
//每一小方塊初始坐標
for(var i=0;i<this.len;i++){
this.arrLeft.push(this.itemSize*(this.len-1-i));
this.arrTop.push(0);
this.items.eq(i).css({"left":_this.arrLeft[i],"top":_this.arrTop[i]});
};
this.move("right"); //初始向右運動
this.createFood(); //隨機生成一個小方塊
//鍵盤事件
$(document).on("keydown",function(event){
event.preventDefault();
// keyCode :上--38 下---40 左--37 右--39
if(event.which==38&&_this.curDirect!="bottom"&&_this.curDirect!="top"){
_this.move("top");
}else if(event.which==40&&_this.curDirect!="top"&&_this.curDirect!="bottom"){
_this.move("bottom");
}else if(event.which==37&&_this.curDirect!="right"&&_this.curDirect!="left"){
_this.move("left");
}else if(event.which==39&&_this.curDirect!="left"&&_this.curDirect!="right"){
_this.move("right");
}
});
},
/**
* 移動方法
* @method move
* @param {string} direct 傳遞運動的方向
**/
move:function(direct){
var _this=this;
clearInterval(_this.timer);
var curX=0;
var curY=0;
this.timer=setInterval(function(){
//存放最后一個方塊位置
_this.eatLeft=_this.arrLeft[0];
_this.eatTop=_this.arrTop[0];
//數組重置(每走一步就把新的位置存入數組,所以要先清空數組)
_this.arrLeft=[];
_this.arrTop=[];
//四種方向判斷(如果當前方向和鼠標響應的方向相反,那么繼續當前方向移動)
if(direct=="top"){
curY=parseInt(_this.items.eq(0).css("top"))-_this.itemSize;
curX=parseInt(_this.items.eq(0).css("left"));
_this.curDirect="top";
}else if(direct=="bottom"){
curY=parseInt(_this.items.eq(0).css("top"))+_this.itemSize;
curX=parseInt(_this.items.eq(0).css("left"));
_this.curDirect="bottom";
}else if(direct=="left"){
curX=parseInt(_this.items.eq(0).css("left"))-_this.itemSize;
curY=parseInt(_this.items.eq(0).css("top"));
_this.curDirect="left";
}else if(direct=="right"){
curX=parseInt(_this.items.eq(0).css("left"))+_this.itemSize;
curY=parseInt(_this.items.eq(0).css("top"));
_this.curDirect="right";
}
//根據前面一個方塊的位置獲取當前方塊的位置,并存入數組中
for(var i=_this.len-1;i>0;i--)
{
_this.arrLeft.push(parseInt(_this.items.eq(i-1).css("left")));
_this.arrTop.push(parseInt(_this.items.eq(i-1).css("top")));
_this.items.eq(i).css({"left":_this.arrLeft[_this.len-i-1]});
_this.items.eq(i).css({"top":_this.arrTop[_this.len-i-1]});
}
_this.items.eq(0).css({"left":curX,"top":curY}); //第一個方塊位置確定下來,后面的方塊都跟著前一個方塊走
_this.arrLeft.push(curX);
_this.arrTop.push(curY);
_this.fnEat(); //吃到食物操作
if(_this.knock()==false){ //判斷是夠撞到墻壁或者撞到自己
clearInterval(_this.timer);
};
},this.iSpeed);
},
/**
* 隨機一個對象坐標
* @method randomFood
* @return {obj} rdX和rdY,分別為隨機對象的x軸所標和y軸坐標
**/
randomFood:function(){
var w=this.wrapWidth;
var h=this.wrapHeight;
var itemSize=this.itemSize;
var rdX=Math.random()*w;
var rdY=Math.random()*h;
//隨機出來的坐標需要是方塊尺寸的倍數
rdX=rdX%itemSize>itemSize/2?rdX-rdX%itemSize+itemSize:rdX-rdX%itemSize;
rdY=rdY%itemSize>itemSize/2?rdY-rdY%itemSize+itemSize:rdY-rdY%itemSize;
//控制不能超出包裹區域
rdX=rdX>w-itemSize?w-itemSize:rdX;
rdY=rdY>h-itemSize?h-itemSize:rdY;
//返回隨機的坐標
return{
rdX:rdX,
rdY:rdY
}
},
/**
* 創建食物
* @method createFood
**/
createFood:function(){
var _this=this;
var rdObj=this.randomFood();
var rdX=rdObj.rdX;
var rdY=rdObj.rdY;
for(var i=0;i<this.len;i++){
if(this.arrLeft[i]==rdX&&this.arrTop[i]==rdY){ //如果第一次隨機生成的方塊位置和蛇的身體重合,那么重新隨機一次,直到不重合
rdObj=this.randomFood();
rdX=rdObj.rdX;
rdY=rdObj.rdY;
}
}
var foodHtml='<div class="snake_food"></div>';
$(foodHtml).css({"left":rdX,"top":rdY}).appendTo(_this.wrap);
this.foodX=rdX;
this.foodY=rdY;
},
/**
* 檢測是否吃到食物
* @method isEat
* @return {boolean} true表示吃到食物
**/
isEat:function(){
if(this.arrLeft[this.len-1]==this.foodX&&this.arrTop[this.len-1]==this.foodY){
return true;
}
},
/**
* 吃到食物后的操作
* @method fnEat
**/
fnEat:function(){
if(this.isEat()){
var _this=this;
var addHtml='<div class="snake_item"></div>';
$(addHtml).css({"top":_this.eatTop,"left":_this.eatLeft}).appendTo(_this.wrap);
this.items=this.wrap.find(".snake_item");//重新獲取item
this.len=this.items.length; //重新獲取方塊個數
this.score++;
this.wrap.find(".snake_food").remove();
this.createFood();
this.iSpeed=this.iSpeed<=100?100:this.iSpeed-50; //加速運動
}
},
/**
* 檢測是否碰撞
* @method isEat
* @return {boolean} false表示碰撞
**/
knock:function(){
var arrLeft=this.arrLeft;
var arrTop=this.arrTop;
var len=this.len;
//碰到墻壁,游戲結束
if(arrLeft[len-1]<0||arrLeft[len-1]>=this.wrapWidth||arrTop[len-1]<0||arrTop[len-1]>=this.wrapHeight){
this.gameOver();
return false;
}
//舌頭碰到蛇身體,游戲結束
for(var i=0;i<len-1;i++){
if(arrLeft[len-1]==arrLeft[i]&&arrTop[len-1]==arrTop[i]){
this.gameOver();
return false;
}
}
}
}
</script>
</head>
<body>
<div class="snake"></div>
</body>
</html>
本文由用戶 cdop 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!