JS打气球游戏


tags: javascript


在B站中看见了一个JS大气球这么一个教程,才知道原来JS+HTML5+CSS3能那么有趣。但是视频中没并没有给出源码。于是在别人的博客中搜到了对应的源码以及他自己实现的思路,该博主对其进行了改编。

http://www.cnblogs.com/morang/p/7636148.html

以上的博文有源码的下载。下面我就直接贴上源码了。思路就在博文中。


<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html>
	<head>
		<title>气球大战</title>
		<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0">
		<style>

		/*CSS3能够将气球描绘出来,使用到了圆形、旋转、阴影等技术*/
			body{margin:0px;padding:0px;}
			#ballDiv{position: fixed;top: 0;left: 0;}
			.balloon{
				width:150px;
				height:150px;
				position:absolute;
				left:0px;
				top:0px;
				background-color:#f3778d;
				border-radius:50% 50% 10% 50%;
				transform:rotate(45deg);
				box-shadow:1px 1px 20px 20px pink inset;
				z-index:10;
			}
			/*这里使用到了伪元素,可以不用到html中定义元素就可以实现功能了!*/
			.balloon:after{
				width:20px;
				height:20px;
				content:"";
				display:block;
				background:transparent;
				position:absolute;
				right: -15px;
				bottom: -15px;
				border-left:5px solid pink;
				border-top:5px solid pink;
			}
			/*这里使用到了伪元素,可以不用到html中定义元素就可以实现功能了!*/
			.balloon:before{
					width: 2px;
					height: 50px;
					content: "";
					display: block;
					background: #ffc0cb;
					position: absolute;
					right: -10px;
					top: 100%;
					margin-top: -16px;
					transform: rotate(-45deg);
			}
		</style>
	</head>
	<body>
		<div id="gameinfo" style="transform: translateZ(360px);">
			<p>
				最高连击:<span id='maxDoubleHit'>0</span>				
			</p>
			<p>
				本次游戏:<span id='currentDoubleHit'>0</span>				
			</p>
			<p id="gamemsg" style="display:none;">
				<span style="color:red;font-weight:bold;">
					Game Over
				</span>
				<button onclick="javscript:location.reload();">
					重新开始
				</button>
			</p>
		</div>
		<div id="ballDiv">
			
			
		</div>
		<!--<div class="balloon"></div>-->
		<script>
			var maxDoubleHit=localStorage.getItem('eliminateCount')||0
			var currentDoubleHit=0
			//当做一个缓存池,优化性能的。
    		var bnElements=[];//存放所有气球
			var random=Math.random;//随机函数
			var wW=window.innerWidth;//窗口宽度
			var wH=window.innerHeight;//窗口高度
			var ballW=160;//气球的宽度
			var ballH=300;//气球的宽度
			var minSpeed=3;//最小速度,每次向上移动至少3px
			var speedNum=5;//速度的定量
			var defBnNumber=5;//初始化气球
			var moveTimer;
			var isEnd=false;			
			var jindex=1;
			var ballDiv=document.getElementById('ballDiv');
			
			//初始化			
			init(defBnNumber);
			//移动
			move();
			//绑定单击事件
			bindClick();
			
			//游戏信息
			document.getElementById('maxDoubleHit').innerText=maxDoubleHit
			function record(){
				if(isEnd){
					clearTimeout(moveTimer);
					bnElements=[];
					document.getElementById('gamemsg').style.display='block';
					document.getElementById('gameinfo').style='transform: translateZ(360px);position: fixed;top:0;left:0;z-index:999';
				}
				else{
					init(1);
					document.getElementById('currentDoubleHit').innerText=++currentDoubleHit;
					if(currentDoubleHit>maxDoubleHit){
						document.getElementById('maxDoubleHit').innerText=currentDoubleHit;
						localStorage.setItem('eliminateCount',currentDoubleHit)
					}
				}
			}
    		//初始化气球
			function init(num){
				//创建一个虚拟文档节点
				var docFragment=document.createDocumentFragment();
				for(var i=0;i<num;i++){
					var bnElement=document.createElement('div');
					bnElement.className='balloon';
					//速度随机,限定最小值
					var speed=Math.max(minSpeed,~~(random()*speedNum));
					bnElement.setAttribute('speed',speed);//~~取整 移动速度
					bnElement.setAttribute('id','ball-'+jindex++);
					//分散排列
					var x=(~~(random()*wW))-ballW;
					x=Math.max(0,x);
					bnElement.style.left=x+'px';				
					bnElement.style.top=wH+'px';//露一点出来			
					
					//1.先将创建的气球放入创建的虚拟文档节点
					docFragment.appendChild(bnElement);
					bnElements.push(bnElement);
				}
				//2.将虚拟文档节点添加到body中
				ballDiv.appendChild(docFragment);
			}

			//使用定时器来对气球进行移动。
			function move(){
				var bl=bnElements.length
				for(var i=0;i<bl;i++){
						var currentElement=bnElements[i]
						if(currentElement==null){
							continue;
						}
						var offsetTop=currentElement.offsetTop;
					if(offsetTop>0){//窗口中

							//offset就是针对窗口的位置来进行移动的。
							var speed=currentElement.getAttribute('speed');
							currentElement.style.top=offsetTop-speed+'px'
						}
						else{
							//移除dom节点
							//ballDiv.removeChild(currentElement);
							//移除数组中
							//bnElements.splice(i,1);
							//init(1);
							isEnd=true;
							record();
						}
				}
				moveTimer=setTimeout(move,1000/30);
			}

			//对所有的气球进行单击监听事件,不要单独为每个气球来进行监听,这样耗费性能!
			function bindClick(){
			
				ballDiv.addEventListener('click',clickFunc,false);
				function clickFunc(e){
					if(!isEnd && e.target.className=='balloon'){
						bnElements.splice(bnElements.lastIndexOf(e.target),1);

						//这里使用call主动调用,在boom方法中我们就可以使用this指针了。
						boom.call(e.target,function(){
							e.target.parentNode.removeChild(e.target);
							record();
						});
					}
				}
			}
			function boom(callback){
				//var that=this; //替换了上下文,但是没有使用this的意义.
				var speed=this.getAttribute('speed');
				this.timer=setInterval(function(){
					this.style.opacity=0.1*(speed--)
					if(speed<1){
						callback&&callback();
						clearInterval(this.timer);
					}
				}.bind(this),30);
			}
			
		</script>
	</body>
</html>
复制代码

看了视频也学到了之前一直没有注意的东西:

  • CSS3很厉害啊,能将方形的div转成是椭圆形的[也就是气球的形状],还有盒子的阴影设置。
  • 使用伪元素就可以不用直接在html中设置标签了。配合CSS3也能够做出对应的样式。
  • 使用实体边框配合CSS3也可以做出不同的形状样式
  • 在生成元素的时候,可以先将要生成的元素加入到文档片段中,再使用文档片段来进行一次性添加到body上,这样性能会好很多!
  • 使用~~运算符能够取整数
  • 限定气球的边界就可以使用max和min函数来进行限定。这也是很好用的。
  • 移动气球我们需要用到定时器。

  • 使用call主动调用方法,把目标对象传递过去的话,我们就可以使用this指针了。
  • 在定时器中使用bind(this),就可以在定时器中使用this指针的,因为定时器默认是由浏览器window来进行调用的,默认是不能使用this的
  • 绑定单击事件的时候,不要使用循环来进行绑定,这样太耗费性能了,我们可以使用监听事件来进行一次绑定。
  • 在遍历元素数组的时候,条件是元素数组的长度时,我们可以先把该元素数组的长度初始化出来,那么也可以提升性能!不然就每次判断前都要去查询数据的长度!

for(var i=0,len = array.length; i<len;i++){}
复制代码

如果您觉得这篇文章帮助到了您,可以给作者一点鼓励

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值