《四福猫跑》原生js游戏
时间:2023-03-28 00:26:35
HTML
#rock{border:2pxsolidblack;/*background-color:black;*/}写在前面SegmentFault四福的吉祥物是一只个性独特、特立独行、热爱自由(>^ω^<)的独角猫,同时也是社区的首席捕鱼官。所以本作品以四福猫为原型,配合原生js完成一款跑酷类小游戏游戏链接https://simplerobort.github.i...技术栈构成(javascript游戏可用引擎:1.Babylon.js;2、Three.js;3、Turbulenz;4、Famo.us;5、PlayCanvas.js;6、GooEngine;7、CooperLicht;8、Voxel等。)从上面可以看出,js可以使用的游戏引擎还是蛮多的。最近为了进入metaverse,正在学习threeJs。为了更好的理解游戏,我没有使用任何游戏引擎(有轮子我就不用,我自己造!)采用的技术栈是:vue+vuex+vueRouter+nativejs(角色碰撞,跳跃,自由落体等)实现过程和思维设计思路如下(障碍很草率哈哈)人物作为模块移动,死亡,跳跃相关代码逻辑放在人物模块中。主要是这样比较合理。就是因为有字符可以有这个功能,所以这些功能应该和字符强绑定。障碍物和触碰即死的障碍物作为模块被重复使用。商店管理公共状态:当前通过关卡、障碍物信息、角色是否移动相关信息路由器管理页面:欢迎页面、各关卡、死亡页面、胜利页面游戏核心模块:角色移动跳跃、物理碰撞角色实现角色风格角色的静止、跳跃、死亡使用gif,通过双向绑定src,根据逻辑替换完成任务状态的变化。
模板>>左右移动从字符样式的代码截图可以看出,字符的移动其实就是将字符的左右两侧绑定到组件状态,然后就可以快速修改左边了andbottom完成角色左右移动的逻辑:moveOpen会在角色组件初始化的时候被调用,moveOpen只做了三件事监听键盘按下键盘弹出调用moveClockmoveOpen:function(){document.onkeydown=()=>{...}document.onkeyup=()=>{...}this.moveClock()}下面详细说说这三件事情都做了什么1.监听键盘按下假设我们现在按住D键移动。其实做完这两件事,如果已经死了,逻辑就停止了(因为死了有动画,防止死亡动画中仍然可以移动)在goRight函数中,将角色向右移动状态改为truedocument.onkeydown=()=>{if(this.isDead)returnconstkey=window.event.keyCodeswitch(key){case65://Athis.goLeft(0)breakcase68://Dthis.goRight(0)breakcase87:case32://Wthis.jump(8)break}}goLeft:function(类型){if(type===0){this.changeStatus('isLeft',true)//changeStatus是修改store的包}elseif(type===1){this.changeStatus('isLeft',false)}},goRight:function(type){if(type===0){这个。changeStatus('isRight',true)}elseif(type===1){这个。changeStatus('isRight',false)}},2.监听键盘弹出只做一件事:将角色对应的移动状态改为falsedocument.onkeyup=()=>{constkey=window.event.keyCode开关(键){case65://Athis.goLeft(1)breakcase68://Dthis.goRight(1)break}}3.调用moveClockmoveclock其实就是启动一个定时器,每次执行4个动作状态或者死亡状态不执行,返回游戏界面受限:当小人在左边或最右边时,不允许继续走出障碍物:判断是否遇到障碍物,判断是死了还是winorstopmovementFalling:判断是否适合下落条件移动:最后执行moveClock:function(){setInterval(()=>{const{human}=this.$refsconst{cantgo,freeFall}=this.$store.gettersconst{stayIndex,humanInfo}=this.$store.stateconstHleft=parseFloat(this.Hleft)constHbottom=parseFloat(this.Hbottom)//因为定时器一直在运行,所以不执行逻辑if(this.isDead||(!humanInfo.isLeft&&!humanInfo.isRight))return//当反派在最左边或最右边时,没有移动者允许constcondition=humanInfo.isLeft吗?human.offsetLeft<=0:humanInfo.isRight&&(human.offsetLeft+15)>=1280if(condition){this.Hleft=humanInfo.isLeft?'0px':'1265px'return}//判断走还是死还是赢还是停constleft=humanInfo.isLeft?Hleft-5:Hleft+15if(cantgo(left,Hbottom,'stopArea'))返回if(cantgo(left,Hbottom,'deadArea'))returnthis.gotDead()if(cantgo(left,Hbottom,'winArea'))returnthis.win()//在index不为-1的情况下,表示你当前踩的是障碍物,而不是地面//freefall判断你是否走出障碍物,你会掉if(stayIndex!==-1&&freeFall(Hleft))this.jump(0)//最后执行运动constforWard=humanInfo.isLeft?-2.5:2.5this.Hleft=Hleft+forWard+'px'},10)}CharacterjumpingCharacterjumping为了模拟逐渐减速直到落地的过程,对主角跳跃使用递归递减做三件事拦截副作用:当已经处于跳跃状态或死亡状态时,不允许再次跳跃修改跳跃状态:修改跳跃状态为true,将角色gif改为跳跃gif跳跃计算:执行递归functionjpjp函数主要做了3件事来判断是否遇到了禁止移动的障碍物。如果你触摸它,如果它处于上升状态,将速度修正为0并开始下降行为。如果是下降状态,停止跳跃行为,判断是遇到死亡障碍还是胜利障碍。对象判断是否死亡进入胜利画面判断这个位移是否触地,触到则停止跳跃,不触则减速,递归jp函数,直到触到障碍物或地面跳跃:function(speed){//如果死亡或跳跃拒绝启动跳跃行为if(this.isDead||this.$store.state.humanInfo.isJump)return//改变跳跃状态为真this.changeStatus('isJump',true)this.humanPic=require('@/assets/human/jump1.0.1.gif')constjp=()=>{const{cantJump}=this.$store.gettersconstjpheight=parseFloat(this.Hbottom)constHleft=parseFloat(this.Hleft)//判断上升或下降时是否遇到障碍物触发具体行为if(cantJump(speed>0,jpheight,Hleft,'stopArea')){//如果当前正在下降,则停止if(speed<=0)returnthis.jumpStop()//如果当前正在下降上升,它会直接将速度更改为0,并将其更改为下降speed=0}if(cantJump(speed>0,jpheight,Hleft,'deadArea'))returnthis.gotDead()if(cantJump(speed>0,jpheight,Hleft,'winArea')(isTouchLand){this.$store.commit('changestayIndex',-1)returnthis.jumpStop()}//没有遇到什么意外情况,减速继续递归speed-=0.2setTimeout(jp,10)}jp()},障碍物执行当前障碍物初始化一共有三种障碍物:死亡障碍物,停止障碍物,胜利障碍物,都是以无状态组件的形式完成的,目的是只需要关注障碍物的位置,而不用写一次逻辑。使用一次当障碍物产生时,它只是将自己的宽高定位信息传给store,store会把这些信息保存在一个数组