JS开发打气球游戏
2017-10-10 15:50
246 查看
JS开发打气球游戏
观视频《月薪4万的程序员有多强?半小时原生JS开发打气球游戏,征服现场数万人!》
清晨,日常打开B站,被首页此视频的标题所吸引,虽一看就是标题党,但还是没能抑制住好奇心。视频共计60*3分钟,学习到了很多东西。其中后半部分有许多正三观的见解也非常认同。
视频地址:https://www.bilibili.com/video/av15152538/
在线试玩:http://sandbox.runjs.cn/show/luderhbq
参考视频写的demo:https://coding.net/u/yimocoding/p/WeDemo/git/tree/气球大战
看了视频,自己来实现试试
花了半天的时间,人生中的第二个游戏终于完成了,想起第一次做拼图游戏也已经是3年前了~来吧,试玩一下,看能消灭多少个气球【笑哭】:http://sandbox.runjs.cn/show/luderhbq
然后,一起来一步步构建自己的【气球大战】(文中代码为核心代码,后续有优化,故非完整代码),可以在runjs中去查看
1.用css3画一个气球
看视频的时候觉得自己这个会那个也会,写代码的时候才发现没有智能提示啥都不会,打错单词的次数不是一次两次~transform:http://www.runoob.com/cssref/css3-pr-transform.html
圆角边框:http://www.runoob.com/cssref/css3-pr-border-radius.html
气球效果预览
css代码
//html→→_→→<div class="balloon"></div>
body{margin:0;padding:0} .balloon{width:150px;height:150px;position:absolute;left:0;top:0;background-color:pink;border-radius:50% 50% 10% 50%;transform:rotate(45deg);box-shadow:1px 1px 20px 20px red inset} .balloon:after{width:20px;height:20px;content:"";display:block;background:0 0;position:absolute;right:-15px;bottom:-15px;border-left:5px solid red;border-top:5px solid red} .balloon:before{width:2px;height:50px;content:"";display:block;background:pink;position:absolute;right:-10px;top:100%;margin-top:-16px;transform:rotate(-45deg)}
2.随机创建气球
首先定义了一些变量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=8;//速度的定量 var defBnNumber=10;//初始化气球
首先编写并调用初始化方法生成气球
生成气球代码
init(defBnNumber); //初始化气球 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-'+(bnElements.length+i+1)); //分散排列 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中 document.body.appendChild(docFragment); }
效果预览
3.气球向上移动
创建一个move方法并在初始化后调用气球移动代码
move();//移动气球 只需要调用一次即可 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>-ballH){//窗口中 var speed=currentElement.getAttribute('speed'); currentElement.style.top=offsetTop-speed+'px' } else{ //移除dom节点 document.body.removeChild(currentElement); //移除数组中 bnElements.splice(i,1); init(1); } } setTimeout(move,1000/30); }
效果预览
4.点击气球,气球消失
发现颜色有点丑~~遂改。气球消失代码
bindClick(); //绑定点击气球事件 function bindClick(){ document.body.addEventListener('click',function(e){ if(e.target.className=='balloon'){ boom.call(e.target,function(){ e.target.parentNode.removeChild(e.target); bnElements.splice(bnElements.lastIndexOf(e.target),1); init(1); }); } }); } function boom(callback){ //var that=this; //替换了上下文,但是没有使用this的意义. var speed=this.getAttribute('speed'); this.timer=setInterval(function(){ this.style.opacity=0.1*(speed--) console.log(this.offsetWidth); if(speed<1){ callback&&callback(); clearInterval(this.timer); } }.bind(this),1000/30); }
效果预览
核心代码终于写完,在我的纯静态工具站点生成二维码扫一扫,在我的小米手机上玩了玩,ok正常,然后再新入手的ipad中试了试。。。擦。坑爹呢,点了咋没反应啊。好吧,为了ipad能玩,强忍着泪水(饿的)解决了iOS的safari兼容问题~
5.解决遇到的safari浏览器兼容问题
问题一:Safari中单击事件不能绑定到document.body上~~,因为无效~解决方法:给元素加了个父级~,若click事件有问题则还需要将click换成touchend~
问题二:transform变换z-index层级渲染异常
解决方法:未变换的元素上添加样式:
transform: translateZ(120px);
参考文章:http://www.zhangxinxu.com/wordpress/2016/08/safari-3d-transform-z-index/
总结
get了几个以前不知道没用过的新技能文档片段
当需要将一堆节点添加到dom中可以使用
document.createDocumentFragment();创建虚拟文档节点,让后将节点先添加到此虚拟节点中,再将此节点追加到指定元素,能够降低dom渲染次数
使用位运算符取整
取0-9的随机数
~~(Math.random()*10)//
Math.random()大于等于 0.0 且小于 1.0
Math.max()
Math.min()可以用来限定边界值
setInterval问题:
可能会丢帧(浏览器的刷新频率为60FPS,一秒最大可以重绘60次),故理论上setinterval()间隔时间大于1000/60就不会参数丢帧的情况
时间线偏移(甚至重叠没执行完就执行下一次任务了),若需要每次都执行完才执行下次任务则使用
setTimeout+递归
this的传递(可以使用bind()去绑定this,不能使用call,会提示没有权限)
传递this到
setInterval中:
setInterval(function(){}.bind(this),1000/30)
值的相等判断使用
===会比
==性能好一点,大部分情况应当使用
===
判断回调函数并执行回调函数
以前我是这样写的:if(typeof(callback)==='function')callback();
视频中有用短路运算符实现即:
callback&&callback()
踩了踩safari的坑
最可怕的事情,不是别人比你强,而是比你强的人比你还努力!!!
相关文章推荐
- 用html5和js制作一个游戏启动界面(html5游戏开发一)、
- 别碰钉子 cocos2d js 版本,即将上线,此游戏充分利手cocos2d js 的chipmunk物理引擎开发...
- 自学cocos2d js游戏开发应该按什么步骤进行
- 深入浅出node.js游戏服务器开发1——基础架构与框架介绍
- JS开发HTML5游戏《神奇的六边形》(五)
- HTML5+JS游戏开发模块----canvas图片拖放
- js如何开发游戏(聊天篇)
- HTML5游戏开发引擎Pixi.js新手入门讲解
- Js版游戏打砖块开发过程详细
- 使用COCOS2D-JS开发你的第一个游戏
- 系列文章之二 用cocos2d-js和pomelo开发MMORPG传奇手游-启动游戏(一)
- 系列文章之二 用cocos2d-js和pomelo开发MMORPG传奇手游-启动游戏续(一)
- Phaser.js开发-星星狗游戏(下)
- 深入浅出node.js游戏服务器开发1——基础架构与框架介绍
- 如何用Cocos2d-JS快速开发一个微信游戏《来自喵星的你》
- Html5+Lufylegend.js游戏开发(一)引擎介绍及原理
- 【Unity3d】游戏开发笔记二 C#与JS之间的语法差异
- 如何在神箭手上快速开发爬虫——第二课 如何爬取JS动态生成的数据【豌豆荚游戏排行榜】
- 【html5-css3游戏开发】js框架选择
- HTML5游戏开发之 -- lufylegend. js猜拳游戏(竖屏)