1,先说下,javascript设计模式之单体模式
单体是一个用来划分命名空间并将一批相关的属性和方法组织在一起的对象,如果他可以被实例化,那么他只能被实例化一次。
单体模式是javascript里面最基本但是也是最有用的也是最常用的模式之一。
单体模式的特点:
1,可以用来划分命名空间,从而清除全局变量所带来的危险。
2,利用分支技术来封装浏览器直接的差异。
3,可以把代码组织的更为一体,便于阅读和维护。
单体模式的思路是:
一个类能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法(静态方法,通常使用getInstance名称)。那么当我们调用这个方法时,如果类持有的引用不为空就返回该引用,否者就创建该类的实例,并且将实例引用赋值给该类保持的那个引用再返回。同时将该类的构造函数定义为私有方法,避免其他函数使用该构造函数来实例化对象,只通过该类的静态方法来得到该类的唯一实例。
下面是使用单体模式写的,飞机大战小蜜蜂的游戏。
<!DOCTYPE html> <html> <head> <title>飞机大战小蜜蜂游戏</title> </head> <style> *{ margin:0; padding:0;} li{ list-style:none;} #div1{ width:800px; height:600px; overflow:hidden; background:black; margin:20px auto; position:relative;} #gameBtn{ color:white; font-size:20px; cursor:pointer; border:1px #FFFFFF solid; width:100px; height:30px; line-height:30px; text-align:center; position:absolute; top:285px; left:350px;} #score{ color:#FFFFFF; font-size:20px;} #bee{ position:relative;} .enemy1{ width:40px; height:28px; background:url(images/mf1.png) no-repeat; float:left;} .enemy2{ width:40px; height:28px; background:url(images/mf2.png) no-repeat; float:left;} .enemy3{ width:40px; height:28px; background:url(images/mf3.png) no-repeat; float:left;} .air1{ width:46px; height:60px; background:url(images/fj.png) no-repeat; position:absolute;} .bullet{ width:1px; overflow:hidden; height:10px; background:white; position:absolute;} </style> <script> //单体的写法:一个大的json 加入了命名空间(用点来分割)的感觉 window.onload = function(){ var oGameBtn = document.getElementById('gameBtn'); oGameBtn.onclick = function(){ this.style.display = "none"; Game.init("div1"); }; }; /* * */ var Game = { /* *小蜜蜂的数据oEnemy *style:样式 *blood:掉血 *speed:飞行的速度 *score:积分 */ oEnemy : { e1 :{style:'enemy1',blood:1,speed:5,score:1}, e2 :{style:'enemy2',blood:2,speed:7,score:2}, e3 :{style:'enemy3',blood:3,speed:10,score:3} }, /* *关卡 *colNum:一行多少个 *iSpeedX:X抽速度 *iSpeedY:Y皱速度 *times:飞下来的时间 */ gk : [ { eMap :[ 'e2','e2','e2','e2','e2','e2','e2','e2','e2','e2', 'e2','e2','e2','e2','e2','e2','e2','e2','e2','e2', 'e2','e2','e2','e2','e2','e2','e2','e2','e2','e2', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', ], colNum : 10, iSpeedX : 10, iSpeedY : 10, times : 2000 }, { eMap :[ 'e3','e3','e3','e3','e3','e3','e3','e3','e3','e3', 'e3','e3','e3','e3','e3','e3','e3','e3','e3','e3', 'e3','e3','e3','e3','e3','e3','e3','e3','e3','e3', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', ], colNum : 10, iSpeedX : 10, iSpeedY : 10, times : 2000 } ], /* *飞机的数据 *style:飞机的样式 *bulletStyle:子弹的样式 */ air : { style : 'air1', bulletStyle : 'bullet' }, /* *初始化 */ init : function(id){ this.oParent = document.getElementById(id); this.createScore(); this.createEnemy(0); this.createAir(); }, createScore : function(){//创建积分 var oS = document.createElement('div'); oS.id = 'score'; oS.innerHTML = '积分:<span>0</span>'; this.oParent.appendChild(oS); this.oSNum = oS.getElementsByTagName('span')[0]; }, createEnemy : function(iNow){//创建小蜜蜂 var gk = this.gk[iNow]; var oUl = document.createElement('ul'); var arr = []; oUl.id = 'bee'; oUl.style.width = gk.colNum * 40 + 'px'; this.oParent.appendChild(oUl); oUl.style.left = (this.oParent.offsetWidth - oUl.offsetWidth)/2 + 'px'; this.oUl = oUl; for(var i=0; i<gk.eMap.length;i++){ var oLi = document.createElement('li'); oLi.className = this.oEnemy[gk.eMap[i]].style; oLi.blood = this.oEnemy[ gk.eMap[i] ].blood; oLi.speed = this.oEnemy[ gk.eMap[i] ].speed; oLi.score = this.oEnemy[ gk.eMap[i] ].score; oUl.appendChild(oLi); } this.aLi = oUl.getElementsByTagName('li'); for(var i=0; i<this.aLi.length;i++){ arr.push([this.aLi[i].offsetLeft, this.aLi[i].offsetTop]); } for(var i=0; i<this.aLi.length;i++){ this.aLi[i].style.position = 'absolute'; this.aLi[i].style.left = arr[i][0] + 'px'; this.aLi[i].style.top = arr[i][1] + 'px'; } this.runEnemy(gk); }, runEnemy : function(gk){//小蜜蜂的运动 var This = this; var L = 0; var R = this.oParent.offsetWidth - this.oUl.offsetWidth; setInterval(function(){ if(This.oUl.offsetLeft > R){ gk.iSpeedX *= -1; This.oUl.style.top = This.oUl.offsetTop + gk.iSpeedY + 'px'; }else if(This.oUl.offsetLeft < L){ gk.iSpeedX *= -1; This.oUl.style.top = This.oUl.offsetTop + gk.iSpeedY + 'px'; } This.oUl.style.left = This.oUl.offsetLeft + gk.iSpeedX + 'px'; },200); }, createAir : function(){//创建飞机 var oA = document.createElement('div'); oA.className = this.air.style; this.oA = oA; this.oParent.appendChild(oA); oA.style.left = (this.oParent.offsetWidth - oA.offsetWidth)/2 + 'px'; oA.style.top = this.oParent.offsetHeight - oA.offsetHeight + 'px'; this.bindAir(); }, bindAir : function(){//操作飞机,左右键移动飞机位置。空格抬起发出子弹 var timer = null; var iNum = 0; var This = this; document.onkeydown = function(ev){ var ev = ev || window.event; if(!timer){ timer = setInterval(show,30); } if(ev.keyCode == 37){//左键 iNum = 1; }else if(ev.keyCode == 39){//右键 iNum = 2; } }; document.onkeyup = function(ev){//抬起发子弹 var ev = ev || window.event; clearInterval(timer); timer = null; iNum = 0; if(ev.keyCode == 32){ This.createBullet(); } }; function show(){ if(iNum == 1){ if(This.oA.style.left == -3 + 'px'){ return false; }else{ This.oA.style.left = This.oA.offsetLeft - 10 + 'px'; } }else if(iNum == 2){ if(This.oA.style.left == 757 + 'px'){ return false; }else{ This.oA.style.left = This.oA.offsetLeft + 10 + 'px'; } } }; }, createBullet : function(){//创建子弹 var oB = document.createElement('div'); oB.className = this.air.bulletStyle; this.oParent.appendChild( oB ); oB.style.left = this.oA.offsetLeft + this.oA.offsetWidth/2 - 1 + 'px'; oB.style.top = this.oA.offsetTop - 10 + 'px'; this.runBullet(oB); }, runBullet : function(oB){//子弹的运动 var This = this; oB.timer = setInterval(function(){ if(oB.offsetTop < -10){ clearInterval(oB.timer); This.oParent.removeChild( oB ); }else{ oB.style.top = oB.offsetTop - 10 + 'px'; } for(var i=0;This.aLi.length;i++){ if( This.pz(oB,This.aLi[i])){ if(This.aLi[i].blood == 1){ This.oUl.removeChild(This.aLi[i]); }else{ This.aLi[i].blood--; } clearInterval(oB.timer); This.oParent.removeChild(oB); } } },30) }, pz : function(obj1,obj2){//碰撞检测 var L1 = obj1.offsetLeft; var R1 = obj1.offsetLeft + obj1.offsetWidth; var T1 = obj1.offsetTop; var B1 = obj1.offsetTop + obj1.offsetHeight; var L2 = obj2.offsetLeft + obj2.parentNode.offsetLeft; var R2 = obj2.offsetLeft + obj2.offsetWidth + obj2.parentNode.offsetLeft; var T2 = obj2.offsetTop + obj2.parentNode.offsetTop; var B2 = obj2.offsetTop + obj2.offsetHeight + obj2.parentNode.offsetTop;; if( R1<L2 || L1>R2 || T1>B2 || B1<T2 ){ return false; }else{ return true; } } }; </script> <body> <div id="div1"> <div id="gameBtn">开始游戏</div> </div> </body> </html>
还没有完成,,但是目前的是可以用的,,可以打蜜蜂,,未完成:积分的累计,蜜蜂攻击飞机。等。。。
未完待续,,,,,
下面是完成的
<!DOCTYPE html> <html> <head> <title>飞机大战小蜜蜂游戏</title> </head> <style> *{ margin:0; padding:0;} li{ list-style:none;} #div1{ width:800px; height:600px; overflow:hidden; background:black; margin:20px auto; position:relative;} #gameBtn{ color:white; font-size:20px; cursor:pointer; border:1px #FFFFFF solid; width:100px; height:30px; line-height:30px; text-align:center; position:absolute; top:285px; left:350px;} #score{ color:#FFFFFF; font-size:20px;} #bee{ position:relative;} .enemy1{ width:40px; height:28px; background:url(images/mf1.png) no-repeat; float:left;} .enemy2{ width:40px; height:28px; background:url(images/mf2.png) no-repeat; float:left;} .enemy3{ width:40px; height:28px; background:url(images/mf3.png) no-repeat; float:left;} .air1{ width:46px; height:60px; background:url(images/fj.png) no-repeat; position:absolute;} .bullet{ width:1px; overflow:hidden; height:10px; background:white; position:absolute;} </style> <script> //单体的写法:一个大的json 加入了命名空间(用点来分割)的感觉 window.onload = function(){ var oGameBtn = document.getElementById('gameBtn'); oGameBtn.onclick = function(){ this.style.display = "none"; Game.init("div1"); }; }; /* * */ var Game = { /* *小蜜蜂的数据oEnemy *style:样式 *blood:掉血 *speed:飞行的速度 *score:积分 */ oEnemy : { e1 :{style:'enemy1',blood:1,speed:5,score:1}, e2 :{style:'enemy2',blood:2,speed:7,score:2}, e3 :{style:'enemy3',blood:3,speed:10,score:3} }, /* *关卡 *colNum:一行多少个 *iSpeedX:X抽速度 *iSpeedY:Y皱速度 *times:飞下来的时间 */ gk : [ { eMap :[ 'e2','e2','e2','e2','e2','e2','e2','e2','e2','e2', 'e2','e2','e2','e2','e2','e2','e2','e2','e2','e2', 'e2','e2','e2','e2','e2','e2','e2','e2','e2','e2', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', ], colNum : 10, iSpeedX : 10, iSpeedY : 10, times : 2000 }, { eMap :[ 'e3','e3','e3','e3','e3','e3','e3','e3','e3','e3', 'e3','e3','e3','e3','e3','e3','e3','e3','e3','e3', 'e3','e3','e3','e3','e3','e3','e3','e3','e3','e3', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', 'e1','e1','e1','e1','e1','e1','e1','e1','e1','e1', ], colNum : 10, iSpeedX : 10, iSpeedY : 10, times : 2000 } ], /* *飞机的数据 *style:飞机的样式 *bulletStyle:子弹的样式 */ air : { style : 'air1', bulletStyle : 'bullet' }, /* *初始化 */ init : function(id){ this.oParent = document.getElementById(id); this.createScore(); this.createEnemy(0); this.createAir(); }, createScore : function(){//创建积分 var oS = document.createElement('div'); oS.id = 'score'; oS.innerHTML = '积分:<span>0</span>'; this.oParent.appendChild(oS); this.oSNum = oS.getElementsByTagName('span')[0]; }, createEnemy : function(iNow){//创建小蜜蜂 if(this.oUl){ clearInterval(this.oUl.timer); this.oParent.removeChild(this.oUl); } document.title = '第'+(iNow+1)+'关'; var gk = this.gk[iNow]; var oUl = document.createElement('ul'); var arr = []; oUl.id = 'bee'; oUl.style.width = gk.colNum * 40 + 'px'; this.oParent.appendChild(oUl); oUl.style.left = (this.oParent.offsetWidth - oUl.offsetWidth)/2 + 'px'; this.oUl = oUl; for(var i=0; i<gk.eMap.length;i++){ var oLi = document.createElement('li'); oLi.className = this.oEnemy[gk.eMap[i]].style; oLi.blood = this.oEnemy[ gk.eMap[i] ].blood; oLi.speed = this.oEnemy[ gk.eMap[i] ].speed; oLi.score = this.oEnemy[ gk.eMap[i] ].score; oUl.appendChild(oLi); } this.aLi = oUl.getElementsByTagName('li'); for(var i=0; i<this.aLi.length;i++){ arr.push([this.aLi[i].offsetLeft, this.aLi[i].offsetTop]); } for(var i=0; i<this.aLi.length;i++){ this.aLi[i].style.position = 'absolute'; this.aLi[i].style.left = arr[i][0] + 'px'; this.aLi[i].style.top = arr[i][1] + 'px'; } this.runEnemy(gk); }, runEnemy : function(gk){//小蜜蜂的运动 var This = this; var L = 0; var R = this.oParent.offsetWidth - this.oUl.offsetWidth; this.oUl.timer = setInterval(function(){ if(This.oUl.offsetLeft > R){ gk.iSpeedX *= -1; This.oUl.style.top = This.oUl.offsetTop + gk.iSpeedY + 'px'; }else if(This.oUl.offsetLeft < L){ gk.iSpeedX *= -1; This.oUl.style.top = This.oUl.offsetTop + gk.iSpeedY + 'px'; } This.oUl.style.left = This.oUl.offsetLeft + gk.iSpeedX + 'px'; },200); setInterval(function(){ This.oneMove(); },gk.times); }, oneMove : function(){//单兵作战 var nowLi = this.aLi[Math.floor(Math.random()*this.aLi.length)]; var This = this; nowLi.timer = setInterval(function(){ var a = (This.oA.offsetLeft + This.oA.offsetWidth/2) - (nowLi.offsetLeft + nowLi.parentNode.offsetLeft + This.oA.offsetWidth/2); var b = (This.oA.offsetTop + This.oA.offsetHeight/2) - (nowLi.offsetTop + nowLi.parentNode.offsetTop + This.oA.offsetHeight/2); var c = Math.sqrt(a*a + b*b); var iSX = nowLi.speed * a/c; var iSY = nowLi.speed * b/c; nowLi.style.left = nowLi.offsetLeft + iSX + 'px'; nowLi.style.top = nowLi.offsetTop + iSY + 'px'; if(This.pz(This.oA,nowLi)){ alert('游戏结束'); window.location.reload(); } },30); }, createAir : function(){//创建飞机 var oA = document.createElement('div'); oA.className = this.air.style; this.oA = oA; this.oParent.appendChild(oA); oA.style.left = (this.oParent.offsetWidth - oA.offsetWidth)/2 + 'px'; oA.style.top = this.oParent.offsetHeight - oA.offsetHeight + 'px'; this.bindAir(); }, bindAir : function(){//操作飞机,左右键移动飞机位置。空格抬起发出子弹 var timer = null; var iNum = 0; var This = this; document.onkeydown = function(ev){ var ev = ev || window.event; if(!timer){ timer = setInterval(show,30); } if(ev.keyCode == 37){//左键 iNum = 1; }else if(ev.keyCode == 39){//右键 iNum = 2; } }; document.onkeyup = function(ev){//抬起发子弹 var ev = ev || window.event; clearInterval(timer); timer = null; iNum = 0; if(ev.keyCode == 32){ This.createBullet(); } }; function show(){ if(iNum == 1){ if(This.oA.style.left == -3 + 'px'){ return false; }else{ This.oA.style.left = This.oA.offsetLeft - 10 + 'px'; } }else if(iNum == 2){ if(This.oA.style.left == 757 + 'px'){ return false; }else{ This.oA.style.left = This.oA.offsetLeft + 10 + 'px'; } } } }, createBullet : function(){//创建子弹 var oB = document.createElement('div'); oB.className = this.air.bulletStyle; this.oParent.appendChild( oB ); oB.style.left = this.oA.offsetLeft + this.oA.offsetWidth/2 - 1 + 'px'; oB.style.top = this.oA.offsetTop - 10 + 'px'; this.runBullet(oB); }, runBullet : function(oB){//子弹的运动 var This = this; oB.timer = setInterval(function(){ if(oB.offsetTop < -10){ clearInterval(oB.timer); This.oParent.removeChild( oB ); }else{ oB.style.top = oB.offsetTop - 10 + 'px'; } for(var i=0;i<This.aLi.length;i++){ if( This.pz(oB,This.aLi[i]) ){ if( This.aLi[i].blood == 1 ){ clearInterval(This.aLi[i].timer); This.oSNum.innerHTML = parseInt(This.oSNum.innerHTML) + This.aLi[i].score; This.oUl.removeChild(This.aLi[i]); }else{ This.aLi[i].blood--; } clearInterval(oB.timer); This.oParent.removeChild(oB); } } if( !This.aLi.length ){ This.createEnemy(1); } },30) }, pz : function(obj1,obj2){//碰撞检测 var L1 = obj1.offsetLeft; var R1 = obj1.offsetLeft + obj1.offsetWidth; var T1 = obj1.offsetTop; var B1 = obj1.offsetTop + obj1.offsetHeight; var L2 = obj2.offsetLeft + obj2.parentNode.offsetLeft; var R2 = obj2.offsetLeft + obj2.offsetWidth + obj2.parentNode.offsetLeft; var T2 = obj2.offsetTop + obj2.parentNode.offsetTop; var B2 = obj2.offsetTop + obj2.offsetHeight + obj2.parentNode.offsetTop; if( R1<L2 || L1>R2 || T1>B2 || B1<T2 ){ return false; }else{ return true; } } }; </script> <body> <div id="div1"> <div id="gameBtn">开始游戏</div> </div> </body> </html>
相关推荐
该资源包的执行效果查看地址:...“地图之家”专栏中的“93.(cesium篇)cesium动态单体化-倾斜摄影(楼栋)”。如下载有问题,可联系博主。 解压密码:cesium
该资源包的执行效果查看地址:...“地图之家”专栏中的“94.(cesium篇)cesium动态单体化-倾斜摄影(楼层)”。如下载有问题,可联系博主。 解压密码:cesium
《园林景观单体模型——2D小乔木在SketchUp中的应用》 园林景观设计是建筑与环境艺术的重要组成部分,而植物配置则是其中的关键环节。2D小乔木作为园林景观设计中的常见元素,以其简洁的形态和丰富的视觉效果,为...
单体文档--yudao-vue-pro,芋道源码收费文档,完整开发技术文档
第01节:Java EE 单体架构 - 内容概述 .mp4
园林景观单体模型-太阳伞-Sketchup草图大师.zip
在"园林景观单体模型-植物树木-2-3D花乔-Sketchup草图大师.zip"压缩包中,文件名“园林景观单体模型-植物树木-2-3D花乔-Sketchup草图大师”暗示了该资源包含一系列针对园林景观设计的3D模型,特别是花乔类植物。...
《园林景观单体模型——植物树木3D盆栽在SketchUp草图大师中的应用》 在园林景观设计中,植物树木是不可或缺的重要元素,它们既能够美化环境,又能够为人们提供休闲空间。3D盆栽作为其中的一种特殊形式,常常被用于...
该资源包的执行效果查看地址:...“地图之家”专栏中的“96.(cesium篇)cesium动态单体化-3D建筑物(楼层)”。如下载有问题,可联系博主。 解压密码:cesium
【标题】"若依单体项目-springboot+js-无redis-无vue" 暗示这是一个基于Spring Boot框架的后台系统,采用JavaScript作为前端技术,但未使用Redis作为缓存服务,也没有采用Vue.js进行前端开发。下面将详细阐述这些...
《园林景观单体模型——植物树木——竹类在SketchUp中的应用》 园林景观设计是建筑与环境艺术的重要组成部分,而植物配置则是其中的关键环节。本资料“园林景观单体模型-植物树木-竹类-Sketchup草图大师.zip”正是...
《园林景观单体模型——Sketchup草图大师中的绿色乔木设计》 在园林景观设计领域,植物配置是至关重要的元素之一,它不仅为环境增添了生机,也为人们提供了视觉享受和生态环境服务。Sketchup草图大师是一款广泛应用...
该资源包的执行效果查看地址:...“地图之家”专栏中的“95.(cesium篇)cesium动态单体化-3D建筑物(楼栋)”。如下载有问题,可联系博主。 解压密码:cesium
《园林景观单体模型——景观喷泉在SketchUp中的应用》 园林景观设计是一门集艺术与技术于一体的学科,它涵盖了自然环境、建筑空间、视觉美学等多个领域。在这个设计过程中,单体模型扮演着至关重要的角色,它们是...
单体测试指南 单体测试(Unit Test)是一种软件测试方法,旨在验证软件的每个单元是否正确地执行其预期的功能。单体测试是软件开发中不可或缺的一部分,目的是为了确保软件的可靠性、稳定性和高效性。 从文件中,...
本资料包“园林景观单体模型-植物树木-推荐--绿色灌木(综合)-Sketchup草图大师.zip”正是针对这一主题,提供了丰富的SketchUp模型资源,便于设计师进行快速、高效的景观设计。 SketchUp是一款广泛应用于建筑设计...
《园林景观单体模型-简约现代-Sketchup草图大师》是针对现代园林景观设计的一份宝贵资源,它集合了多种简洁、时尚的景观元素模型,适用于土木工程、建筑地产以及高等教育领域的毕业设计和教学实践。这个压缩包内含...
标题中的“园林景观单体模型-景观凳子-Sketchup草图大师.zip”指的是一个包含园林景观设计中使用的景观凳子模型的压缩文件。这个文件是用SketchUp(草图大师)软件创建的,SketchUp是一款广泛应用于建筑设计、室内...
标题中的“园林景观单体模型-植物树木-3D莲花睡莲-Sketchup草图大师.zip”揭示了这个压缩包包含的内容是与园林景观设计相关的3D模型,具体是莲花和睡莲这两种植物的3D模型,适用于SketchUp软件。SketchUp是一款广泛...
本资源包“园林景观单体模型-石狮子-Sketchup草图大师.zip”便是针对这一主题,提供了详细的3D模型文件,旨在帮助设计师们更好地理解和运用石狮子元素,以提升设计作品的文化内涵和视觉效果。 SketchUp草图大师是一...