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();
js 贪食蛇-双蛇抢食相关推荐
- java贪吃蛇设计流程_JAVA版贪食蛇(贪吃蛇)游戏的设计与实现(含录像)
JAVA版贪食蛇(贪吃蛇)游戏的设计与实现(含录像)(任务书,开题报告,外文翻译,毕业论文12000字,程序代码,MySQL数据库,答辩PPT,答辩视频录像) 摘要 "贪食蛇"游戏 ...
- java小程序贪吃蛇代码_微信小程序Demo之贪食蛇
原标题:微信小程序Demo之贪食蛇 差不多大半年前,笔者发布了一篇关于OC版贪食蛇开发的文章,时隔多月,微信小程序横空出世,于是闲来无事的我又写了一个小程序版. 01页面布局 关于小程序笔者就不做介绍 ...
- linux终端贪吃蛇,分享|nSnake: 在Linux的终端上玩经典的贪食蛇游戏
你知道20世纪末的那些古老的诺基亚手机上最棒的东西是什么吗? 贪食蛇! 我以前在这个看似无聊但却让人上瘾的游戏上花费了大把的时间.在古老的诺基亚手机被智能手机取代的同时,贪食蛇也被另外的无聊但却令人上 ...
- 原生js实现贪食蛇小游戏
先不多说先上图 下面是代码部分(这里你可以根据需要改变蛇头和身体还有食物的图片,然后默认的样式是使用纯颜色的如果没有更改我的背景图片的话------改这些图开始是想搞笑一下朋友哈哈哈,请不要在意哈), ...
- typescript学习记录-练习项目-贪食蛇
参考文章:https://www.bilibili.com/video/BV1Xy4y1v7S2?p=22 项目搭建 将之前的package.json,tsconfig.json,webpack.co ...
- tomcat websock html5,websocket实战(4) websocket版贪食蛇游戏(tomcat官方自带)
通过前面3篇的阐述,相信可以构建一个简单的socket应用了.当然,也会遗漏了许多知识点,相信会在以后分享的实例中捎带说明下. 本文的主要是分析下tomcat官方自带的贪食蛇游戏.为什么选择分析这个项 ...
- 使用C++设计贪食蛇小游戏
说明:所有代码均可在Visual Studio 2013上编译执行.并未测试在其它编译器上编译情况. 游戏规则 贪食蛇游戏要求玩家控制方向键(或WSAD键)来控制小蛇的前进方向,以使蛇吃掉面板上随即位 ...
- 在微信小游戏中开发一个贪食蛇
为什么80%的码农都做不了架构师?>>> 我自己也写过一个贪食蛇的小游戏,不过是对dom的操作,微信小游戏是采用js语法基于canvas的开发.为了省事在网上直接搜了一个基于c ...
- python编写小游戏之三入最最简陋简单贪食蛇编写2
紧接上回,已经完成了单独的贪食蛇的控制,但是呢,居然没有苹果可以吃,所以,非常简单的加入苹果,同时呢,修改一下主程序中贪食蛇的创建,单独编写一个贪食蛇身体生成函数,这样将来要做双蛇也很简单了. #创建 ...
最新文章
- ROC(receiver operating characteristic curve)曲线与ROC分析
- sqlite3 多线程 c语言,sqlite3 c语言编程 之 三个基本函数
- 蓝桥杯 历届试题 分考场(DFS+枚举)
- Binder子系统之调试分析(一)
- javascript淘宝主图放大镜功能
- 2020 JVM生态报告
- python 线性回归 技术方案亮点_基于Python的线性回归实战
- arduino读取matlab串口,Matlab Arduino实时串行通信,采样0.004 s
- c#写字板实现加粗功能_Windows 7中写字板和绘画中的新功能
- 杭电 1233 最小生成树 kruskal()算法
- 事理逻辑为核心的自然语言处理理论实践与工业探索项目
- Nginx实现HTTP反向代理配置
- 检查已终止。收集事实数据时检测到错误
- php在哪改缩略图的大小,Thinkphp自定义生成缩略图尺寸的方法
- java版我的世界光追,老瓶装新酒 光追版《我的世界》将至你心动了吗
- 关于英文系统中的中文乱码的更改
- HeadFirstJava——5_编写程序
- git for Mac安装(包含客户端软件Github Desktop的安装配置)
- 超市选址c语言程序,谈谈超市选址的重要性
- 校园卡水卡最低成本破解具体过程(补上上次工具教程)By:dj1149 -02
热门文章
- 【100%通过率】华为OD机试真题 JavaScript 实现【密室逃生游戏】【2022 Q4 | 100分】
- 【JavaScript】定时器
- 为什么互联网流行 996 而非886、776
- SPOOL导出大量数据时,导出不全问题处理
- 基于SSM学生档案管理
- 读计算机操作系统的读后感,《计算机操作系统》读后感锦集
- 每日阅读2021.11.22
- R语言 class() mode() typeof() 查看函数的区别
- 【实现操作系统 03】使用 FAT12 文件系统实现简单的 Boot 加载 Loader 到内存
- SpringBoot+mybatis+Druid 实现运行时数据源的动态创建管理