失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 用Vue实现一个街机游戏摇杆

用Vue实现一个街机游戏摇杆

时间:2022-02-05 20:27:07

相关推荐

用Vue实现一个街机游戏摇杆

前言

最早实现这个效果,是用Objective-C在iOS里实现的。原仓库地址:/archive/p/ccjoystick/downloads

在Vue里实现这个东西没啥用处,毕竟Vue也不是一个游戏框架,但是谁叫Vue这个话题的热度最高呢😁,写文章还是希望被更多人看到嘛…

印象里我在不同时期曾经用三种语言分别实现过这个案例。所以无论用什么框架、语言,只要你了解背后的原理,都很容易实现。

三层UI

全部UI分为三层

第一层是杆头,尺寸不会变化,拖拽的视觉效果区。

第二层是杆体,高度可拉伸,用于拟物流模仿真实感。

第三层是底,只是放在画面中,为了让视觉感受更完整。

当然没有第二层和第三层是不影响摇杆功能的,但谁叫我是一个拟物流的前端偏执狂呢?

把这三个层通过绝对定位+z-index叠起来,通过设置touch事件让杆头可以拖动。为了让大家看得清楚层级,我们先把杆头变透明。

圆形的拖拽区

摇杆嘛,圆形的洞里有根杆(不要呀),所以我们必须把拖拽限制在一个圆形区域里

onTouchMove(e){varcurTouch=e.touches[0];vartleft=curTouch.clientX-startLeft;varttop=curTouch.clientY-startTop;//获取点击位置和起点的直线距离,也就是半径vardistance=getDistance(tleft,ttop,0,0);//如果这个距离是否大于圆形可移动区域的半径,则强行变更if(distance>=this.ballMoveRadius)distance=this.ballMoveRadius;//最后通过夹角,正弦,余弦,半径还原x,y坐标varangle=Math.atan2((ttop-0),(tleft-0));this.left=Math.cos(angle)*distance;this.top=Math.sin(angle)*distance;}

代码中比较核心的部分是:我们先通过所在点原点位置求出半径distance,以及之间的夹角角度angle。然后通过限定半径和夹角角度还原出xy的坐标。就可以达到控制拖动在圆形区域内的效果了。

//获取两点间直线距离的算法vargetDistance=function(x1,y1,x2,y2){var_x=Math.abs(x1-x2);var_y=Math.abs(y1-y2);returnMath.sqrt(_x*_x+_y*_y);}

羞涩的杆体

杆体是这里面最麻烦的一块,需要通过摇杆的拖拽的距离变化长度,同时根据摇杆的位置旋转角度。

<viewclass='stick':class="{animation:inDraging===false&&transition}":style="{height:stickHeight+'px',transform:'translateX(-50%)'}"><view:style="{transform:'rotate('+(angle/(3.14159/180)-90)+'deg)'}"style="transform-origin:50%0%;width:100%;height:100%;"><slotname="stick"></slot></view></view>

这里我用了两层dom来完成这个杆体,一层用height进行高度变化,一层用transfrom设置旋转角度和旋转中心点。大家有更好的实现方法吗,在评论区告诉我吧。

夹角转为旋转角度算法angle/(3.14159/180),减去90是为了让度数起点在12点钟的位置。

onTouchMove(e){varcurTouch=e.touches[0];vartleft=curTouch.clientX-startLeft;varttop=curTouch.clientY-startTop;vardistance=getDistance(tleft,ttop,0,0);if(distance>=this.ballMoveRadius)distance=this.ballMoveRadius;varangle=Math.atan2((ttop-0),(tleft-0));this.left=Math.cos(angle)*distance;this.top=Math.sin(angle)*distance;//同步杆体的高度,旋转角度this.stickHeight=distance;this.angle=angle;}

现在摇杆UE基本就完成了,接下来我们要输出一些数值,毕竟摇杆不能光自己,得用来控制其他的元素进行运动。

摇杆数值

方向

方向我们在杆体运动的时候,已经写完了,就是那个角度angle

力度

power=当前半径/最大半径;

摇杆力度这件事在拳皇里是不存在的,但是在很多游戏中分轻推重推(其实就是摇杆当前距离和最大距离的比),比如轻推是走,重推是跑。

gif有点掉帧,大家能看出来运动的快慢吗?

组件化

现在把上面的成果封装成一个vue组件,方便复用。

<ezjoystick:touchRadius="100":ballMoveRadius="50":transition="true"@onJoyStickUpdate="onBeetleJoystickUpdate"><viewslot="ball"></view><viewslot="stick"></view><viewslot="bottom"></view></ezjoystick>

三个属性

touchRadius触摸检测的实际半径

ballMoveRadius杆头的最大移动范围半径

transition是否开启缓动回位

三个slot

三个slot都是非必须的,不填的话,该部分就是空dom。具体可参考源码。

ball杆头

stick杆体

bottom

两个事件

onJoystickUpdate有数值变化就会触发

onJoystickCancel停止触摸时触发

实现经典UI

组件封装好了,接下来用咱们这个组件实现几个经典的界面吧

街机摇杆 十字键

模拟十字键,核心是把角度转成4个方向,这里我随手写了一下,应该有更优雅的实现。

onCrossJoyStickUpdate(obj){this.crossupPressed=false;this.crossrightPressed=false;this.crossdownPressed=false;this.crossleftPressed=false;if(obj.angle>-2.35&&obj.angle<-0.75){this.crossupPressed=true;}elseif(obj.angle>-0.75&&obj.angle<0.75){this.crossrightPressed=true;}elseif(obj.angle>0.75&&obj.angle<2.35){this.crossdownPressed=true;}else{this.crossleftPressed=true;}}

王者荣耀的摇杆

在外层关联旋转一个箭头而已…

源码仓库

/ezshine/ezjoystick

clone源码后使用HBuilerX打开可以快速看到实例,或将components复制到vuecli项目中导入使用

如果觉得《用Vue实现一个街机游戏摇杆》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。