js 贪食蛇-双蛇抢食

最近在看javascript权威指南,真是写的好啊,在没看html5之前先写个小游戏练练手,看完全部以后策划一个html5游戏,这个游戏断断续续写了大概一周时间,采用面向对象的方式开发的,完成以后还是发现有很多之前设计不足的情况,在下个游戏中一定要改进,有兴趣的朋友给提点意见

1.0js 贪食蛇初稿,上下左右控制方向 空格暂定 回去继续搞..

1.1 面向对象开发的魅力,马上转双蛇抢食,后续开发拦杀

1.2 拦杀已开发完成

本地IE8 火狐17.0 谷歌23.0已测试通过
[img]http://dl.iteye.com/upload/attachment/0077/9501/63d3e2ad-ca52-346a-8759-083747022a51.png[/img]
var SnakeGame = function(options) {
//游戏配置项
this.level = 5;//第几关 与速度相关
this.blockWidth = 13;//身体食物面积(推荐10-20,耐玩性高)
this.initBodyNum = 5;//初始身体长度

if (options) {//加载控制器 食物 和身体颜色
this.controler = options.controler;
this._fm = options.fm;
this.color = options.color;
}

};

SnakeGame.prototype = {
start : function() {//开始游戏
//随机分配一个初始位置
this.initBodyPos = this.getRnadPos(this.refsnakes);

//创建身体管理器
this.setBodyManager(new SnakeGame.BodyManager({
speed : 500 / this.level,
blockWidth : this.blockWidth,
initBodyNum : this.initBodyNum,
initBodyPos : this.initBodyPos
}));

//初始化身体
this._bm.initBody(this._fm);

//绑定鼠标事件
this.keyBind();
},
getRnadPos : function(num){
var pos = parseInt(Math.random()*(getWindowHeight()/this.blockWidth))*this.blockWidth;
if(num&&num[0]["initBodyPos"]==pos)
return this.getRnadPos();
return pos;
},
setBodyManager : function(manager) {
this._bm = manager;
this._bm._parent = this;
},
setFoodManager : function(manager) {
this._fm = manager;
},
keyBind : function() {
var me = this;
var _keyback = document.onkeydown;
document.onkeydown = function(e) {
if (_keyback) {
_keyback(e);
}

var event = e || window.event;
switch (event.keyCode) {
case me.controler["left"]:
me._bm.moveDir = 4;
break;
case me.controler["top"]:
me._bm.moveDir = 1;
break;
case me.controler["buttom"]:
me._bm.moveDir = 3;
break;
case me.controler["right"]:
me._bm.moveDir = 2;
break;
case 32:
me._bm.spendMove();
break;
}

};
},
setRefSnakeBody : function(snake){//管理所有身体对象
//被注掉的部分可以减少调用时的代码 但是不利于扩展分辨敌我
/* if(!this.refsnakes){debugger;
this.refsnakes = [snake];
snake.setRefSnakeBody(this);
}else{
var flag = true;
for(var i = 0;i<this.refsnakes.length;i++){
if(snake===this.refsnakes[i]){
flag = false;
}
}
if(flag){
this.refsnakes.push(snake);
for(var i = 0;i<this.refsnakes.length;i++){
this.refsnakes[i].setRefSnakeBody(snake);
}
}
} */

this.refsnakes = snake;
}
};

//身体管理器
SnakeGame.BodyManager = function(options) {
this.bodyArr = [];//存放bady的数组

this.moveDir = 2;//下一步方向 1上 2右 3下 4左

this.nowDir = 0; //正在移动的方向

this.gameOptions = options;
};SnakeGame.BodyManager.prototype = {

initBody : function(manager) {//初始化身体
this.setFoodManager(manager);

for ( var i = 0; i < this.gameOptions["initBodyNum"]; i++) {
var style = this._parent.color||"red";
if (i == 0) {
style = "black";
}
this.createBody({
position : "absolute",
width : this.gameOptions["blockWidth"],
height : this.gameOptions["blockWidth"],
top : this._parent.initBodyPos,
backgroundColor : style,
border : '1px',
left : 0//this.gameOptions["initBodyPos"]
//- (i * this.gameOptions["blockWidth"])
});
}

this.startMove();
},
createBody : function(options) {//创建一块身体

var _body = document.createElement("div");
_body.style.position = "absolute";
_body.style.width = options["width"] + "px";
_body.style.height = options["height"] + "px";
_body.style.top = options["top"] + "px";
_body.style.left = options["left"] + "px";
_body.style.background = options["backgroundColor"];
_body.style.display = options["display"] || "block";
_body.style.border = "1px solid";
this.bodyArr.push(_body);

document.body.appendChild(_body);

return _body;
},
moveBody : function(num) {//移动身体
if (this.nowDir != 0
&& Math.abs(this.moveDir - this.nowDir) % 2 == 0) {//控制限制,例:在方向为左时 按左或右无效
this.moveDir = this.nowDir;
}
var lastPosition = {};
for ( var i = 0; i < this.bodyArr.length; i++) {
this.bodyArr[i].style.display = "block";//显示身体

var _l = getElementPos(this.bodyArr[i]).x;//获取身体坐标
var _t = getElementPos(this.bodyArr[i]).y;
var _cssparam = {
left : _l,
top : _t
};
var _dw = parseInt(this.bodyArr[i].offsetWidth,
10);//获取块的宽度,因为是正方形所以高度也一样
if (i == 0) {//是头的情况下
var _dir, _len;//方向 和 移动的距离
if (this.moveDir == 1 || this.moveDir == 3) {//1或3是垂直移动
_dir = "top";
if (this.moveDir == 1) {
num = 0 - num;
}
_len = getElementPos(this.bodyArr[i]).y + num;
if (_len<0 || _len>getWindowHeight()) {
this.stopMove();
return;
}
} else {//2或4是水平移动
_dir = "left";
if (this.moveDir == 4) {
num = 0 - num;
}
_len = getElementPos(this.bodyArr[i]).x + num;
if (_len<0 || _len+_dw>getWindowWidth()) {
this.stopMove();
return;
}
}

_cssparam[_dir] = _len;

for ( var j = 1; j < this.bodyArr.length; j++) {//如果头部撞到了自己的身体
var _l2 = getElementPos(this.bodyArr[j]).x;
var _t2 = getElementPos(this.bodyArr[j]).y;

if (_l2 == _cssparam["left"] && _t2 == _cssparam["top"]) {
this.stopMove();
return;
}
}

if(this._parent.refsnakes&&this._parent.refsnakes.length>0){//判断是否撞到对手的身体上
for(var h = 0;h<this._parent.refsnakes.length;h++){
var refbodys = this._parent.refsnakes[h]._bm["bodyArr"];
for(var f = 0;f<refbodys.length;f++){
if(refbodys[f].offsetLeft == _cssparam["left"] && refbodys[f].offsetTop == _cssparam["top"]){
if(f==0){//如果撞的对手的头,那么同归
this._parent.refsnakes[h]._bm.stopMove(true);
this.stopMove();
alert("打和");
return;
}
this.stopMove();
return;
}
}

}

}

} else {//不是头部的话 只要照着上一个块的位置移动就行了
_cssparam["left"] = lastPosition.x;
_cssparam["top"] = lastPosition.y;
}

this.bodyArr[i].style.left = _cssparam["left"] + "px";
this.bodyArr[i].style.top = _cssparam["top"] + "px";

//记录上一个块
lastPosition.x = _l;
lastPosition.y = _t;
}

//头部位置
var _hpl = this.bodyArr[0].style.left;
var _hpt = this.bodyArr[0].style.top;

//如果头部吃到食物
if (this._fm && _hpl == this._fm.pos["x"] + "px"
&& _hpt == this._fm.pos["y"] + "px") {
this.createBody({//创建一个隐藏的身体,身体会马上根据上一个块的坐标把他带上去
position : "absolute",
width : this.gameOptions["blockWidth"],
height : this.gameOptions["blockWidth"],
top : -10,
backgroundColor : this._parent.color,
border : '1px',
left : -10,
display : "none"
});
this._fm.randomPosi();
//this.changeSpeed(1);
}

this.nowDir = this.moveDir;
},
startMove : function() {//开始移动
var me = this;
function intervalCall() {//将移动方法闭包起来
me.moveBody(me.gameOptions["blockWidth"]);
}
this.moveTimer = setInterval(intervalCall,//根据速度开始执行
this.gameOptions["speed"]);
},
changeSpeed : function(num) {//加速的方法
this.gameOptions["speed"] = this.gameOptions["speed"] - num;
this.spendMove();
this.startMove();
},
spendMove : function() {//暂定
var me = this;
if (!this.moveTimer) {
me.startMove();
} else {
clearInterval(this.moveTimer);
this.moveTimer = null;
}
},
setFoodManager : function(manager) {//提供食物管理器
this._fm = manager;
},
stopMove : function(flag) {//发生碰撞即将停止
clearInterval(this.moveTimer);
for ( var j = 0; j < this.bodyArr.length; j++) {//当前身体清空掉
this.bodyArr[j].parentNode.removeChild(this.bodyArr[j]);
}
if(this._parent.refsnakes){
if(this._parent.refsnakes.length==1){//如果一只有个对手,那么这个对手赢了
if(!flag){
alert(this._parent.refsnakes[0].color+" 赢");
}

var reload = function(){
window.location.reload();
}
setTimeout(reload,3000);//3秒后重新游戏
}

for(var i = 0;i<this._parent.refsnakes.length;i++){//把自己从别人的对手列表中清除
var subref = this._parent.refsnakes[i].refsnakes;

for(var j = 0;j<subref.length;j++){
if(subref[j]==this._parent){
subref.splice(j,1);
}
}
}
}
}
};

//食物管理器
SnakeGame.FoodManager = function(options) {
this.gameOptions = options;
var me = this;

this.foodDom;

this.getRandomPos = function() {
var _rw = parseInt(Math.random()
* (getWindowWidth() / me.gameOptions["blockWidth"] - 1));
var _rh = parseInt(Math.random()
* (getWindowHeight() / me.gameOptions["blockWidth"] - 1));

return {
x : _rw * me.gameOptions["blockWidth"],
y : _rh * me.gameOptions["blockWidth"]
}

}
this.pos = this.getRandomPos();
this.initFood({
backgroundColor : "blue",
left : this.pos["x"],
top : this.pos["y"],
width : this.gameOptions["blockWidth"],
height : this.gameOptions["blockWidth"]
});
}

SnakeGame.FoodManager.prototype = {
initFood : function(options) {
this.foodDom = document.createElement("div");
this.foodDom.style.position = "absolute";
this.foodDom.style.width = options["width"] + "px";
this.foodDom.style.height = options["height"] + "px";
this.foodDom.style.top = options["top"] + "px";
this.foodDom.style.left = options["left"] + "px";
this.foodDom.style.background = options["backgroundColor"];

document.body.appendChild(this.foodDom);
},
randomPosi : function() {
this.pos = this.getRandomPos();
this.foodDom.style.top = this.pos["y"] + "px";
this.foodDom.style.left = this.pos["x"] + "px";
}

}
var param = new SnakeGame();

//构造食物管理器
var fm = new SnakeGame.FoodManager({
blockWidth : param.blockWidth
});


//两条蛇 有不同的控制方式 相同的食物管理器
var snake1 = new SnakeGame({
controler : {
buttom : 83,
left : 65,
top : 87,
right : 68
},
fm : fm,
color : 'red'
});


var snake2 = new SnakeGame({
controler : {
buttom : 40,
left : 37,
top : 38,
right : 39
},
fm : fm,
color : 'green'
});

/* var snake3 = new SnakeGame({
controler : {
buttom : 40,
left : 37,
top : 38,
right : 39
},
fm : fm,
color : 'yellow'
}); */
snake1.setRefSnakeBody([snake2/* ,snake3 */]);//配置对手列表,由此来分辨是敌是友
snake2.setRefSnakeBody([snake1/* ,snake3 */]);
//snake3.setRefSnakeBody([snake2,snake1]);

snake1.start();
snake2.start();
//snake3.start();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值