热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

摇杆控制方向原理_Vue框架|一文教会你如何实现王者荣耀游戏摇杆

前言最早实现这个效果,是2011年用Objective-C在iOS里实现的。原仓库地址:https:code.google.comarchivepccj
60fd4f9564219d4847bcc76bdaf630be.png

前言

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

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

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

三层UI

全部UI分为三层

  • 第一层是杆头,尺寸不会变化,拖拽的视觉效果区。
  • 第二层是杆体,高度可拉伸,用于拟物流模仿真实感。
  • 第三层是底,只是放在画面中,为了让视觉感受更完整。
7e74d10c11f265fbd0557ced09443051.png

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

cae90c3cce06b338f890fc00f0bcd359.gif

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

圆形的拖拽区

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

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

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

44922b158031d6c7b16a6ee68285b16a.gif

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

羞涩的杆体

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

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

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

13627ef324db1416228cdb2c0080c222.gif

onTouchMove(e){ var curTouch=e.touches[0]; var tleft=curTouch.clientX-startLeft; var ttop=curTouch.clientY-startTop; var distance = getDistance(tleft,ttop,0,0); if(distance>=this.ballMoveRadius)distance = this.ballMoveRadius; var angle = 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 = 当前半径/最大半径;

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

26db6d6c23b19c7f984c1caae8fc10ea.gif

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

组件化

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

  • 三个属性
  • touchRadius 触摸检测的实际半径
  • ballMoveRadius 杆头的最大移动范围半径
  • transition 是否开启缓动回位
三个slot三个slot都是非必须的,不填的话,该部分就是空dom。具体可参考源码。ball 杆头stick 杆体bottom 底两个事件onJoystickUpdate 有数值变化就会触发onJoystickCancel 停止触摸时触发

实现经典UI

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

  • 街机摇杆
0053e1128fd1baf6dff8e838400d9339.gif
  • 十字键
5de1a4979614acd435621cf90928a9f3.gif

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

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

  • 王者荣耀的摇杆
f9834d1ebb7c40e82539c15b0fe9d7b7.gif

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

源码仓库

https://github.com/ezshine/ezjoystick

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

后话&#xff0c;怎么实现搓招

42f8d6c400264bab74a96434b6e13cca.gif

什么是搓招&#xff1f;就是在一定时间内按顺序完成几个方向&#43;按键即可触发招式。比如此图里不知火舞的这招需要我们按顺序完成 ←↙↓↘→&#43;轻或重脚。

今日话题&#xff1a;说一说&#xff0c;你做过最自豪的一件事。

你的点赞与关注是小编坚持的动力。

246d5ade34cfa8997da864599984585b.png


推荐阅读
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • PHP反射API的功能和用途详解
    本文详细介绍了PHP反射API的功能和用途,包括动态获取信息和调用对象方法的功能,以及自动加载插件、生成文档、扩充PHP语言等用途。通过反射API,可以获取类的元数据,创建类的实例,调用方法,传递参数,动态调用类的静态方法等。PHP反射API是一种内建的OOP技术扩展,通过使用Reflection、ReflectionClass和ReflectionMethod等类,可以帮助我们分析其他类、接口、方法、属性和扩展。 ... [详细]
author-avatar
水水2502919973
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有