• 自定义虚拟摇杆组件让你一劳永逸


    最近在研究虚拟摇杆实现方式的时候,发现网上的教程的实现方式可移植性并不是特别好,于是我决定自己实现一个虚拟摇杆组件,保存到自己的组件库,方便以后用到的时候直接使用(关注公众号后台回复「虚拟摇杆组件」可获取该组件),下面正文开始。

    实现思路:

    为了实现高度可移植,定义了两个节点属性,用于绑定场景和玩家角色,另外添加 PlayerNodeSpeed 属性和 MaxR 属性用于控制玩家移动速度和摇杆节点的移动范围。

    实现过程:

    1.首先创建一个空节点 Rocker,下面挂载上虚拟摇杆的背景 rockerBg 和摇杆节点 joystick:

    2.然后给创建好节点添加合适的虚拟摇杆资源,没有资源的小伙伴可以关注公众号后台回复「虚拟摇杆」获取多套美术资源:

    3.之后编写脚本如下,代码中已经尽可能详细做好了备注,如果仍有不清楚的小伙伴可以后台私信我,看到后我会及时回复的:

      1 // Rocker.js
      2 
      3 cc.Class({
      4     extends: cc.Component,
      5 
      6     properties: {
      7         sceneNode: {    // 场景节点
      8             type: cc.Node,
      9             default: null,
     10         },
     11 
     12         playerNode: {    // player节点
     13             type: cc.Node,
     14             default: null,
     15         },
     16 
     17         playerNodeSpeed: 100,    // player移动速度
     18 
     19         Max_r: 100,    // 摇杆移动半径,根据自己美术资源进行调整
     20     },
     21 
     22     onLoad() {
     23         // 隐藏摇杆组件节点
     24         this.node.active = false;
     25 
     26         // 获取摇杆节点并初始化摇杆节点位置及角度
     27         this.joystick = this.node.getChildByName('joystick')
     28         this.joystick.setPosition(cc.v2(0, 0));
     29         this.dir = cc.v2(0, 0);
     30 
     31         // 注册父节点的 touch 监听事件
     32         this.sceneNode.on(cc.Node.EventType.TOUCH_START, this.cbTouchStart, this);
     33         this.sceneNode.on(cc.Node.EventType.TOUCH_MOVE, this.cbTouchMove, this);
     34         this.sceneNode.on(cc.Node.EventType.TOUCH_END, this.cbTouchEnd, this);
     35         this.sceneNode.on(cc.Node.EventType.TOUCH_CANCEL, this.cbTouchCancel, this);
     36     },
     37 
     38     update(dt) {
     39         if (this.dir.mag() < 0.5) {
     40             return;
     41         }
     42 
     43         let vx = this.dir.x * this.playerNodeSpeed;
     44         let vy = this.dir.y * this.playerNodeSpeed;
     45 
     46         let sx = vx * dt;
     47         let sy = vy * dt;
     48         //移动
     49         this.playerNode.x += sx;
     50         this.playerNode.y += sy;
     51 
     52         let windowsSize = cc.winSize;
     53 
     54         let minX = -windowsSize.width / 2 + this.playerNode.width / 2;    // 最小X坐标
     55         let maxX = Math.abs(minX);    // 最大X坐标
     56         let minY = -windowsSize.height / 2 + this.playerNode.height / 2;    // 最小Y坐标
     57         let maxY = Math.abs(minY);    // 最大Y坐标
     58 
     59         let currentPos = this.playerNode.getPosition();
     60 
     61         if (currentPos.x < minX) {
     62             currentPos.x = minX;
     63         } else if (currentPos.x > maxX) {
     64             currentPos.x = maxX;
     65         } 
     66         
     67         if (currentPos.y < minY) {
     68             currentPos.y = minY;
     69         } else if (currentPos.y > maxY) {
     70             currentPos.y = maxY;
     71         }
     72 
     73         this.playerNode.setPosition(currentPos);
     74 
     75         //方向计算
     76         var r = Math.atan2(this.dir.y, this.dir.x);
     77         var degree = r * 180 / (Math.PI);
     78         degree = 360 - degree + 90;
     79         this.playerNode.rotation = degree;
     80     },
     81 
     82     cbTouchStart(event) {
     83         let pos = event.getLocation();
     84 
     85         // 点击时显示摇杆组件节点并设置位置
     86         this.node.active = true;
     87         let rPos = this.sceneNode.convertToNodeSpaceAR(pos);    // 将世界坐标转化为场景节点的相对坐标
     88         this.node.setPosition(rPos);
     89         
     90         // 初始化摇杆节点位置及角度
     91         this.joystick.setPosition(cc.v2(0, 0));
     92         this.dir = cc.v2(0, 0);
     93     },
     94 
     95     cbTouchMove(event) {
     96         var pos = event.getLocation();
     97 
     98         var jPos = this.node.convertToNodeSpaceAR(pos);    // 将世界坐标转化为摇杆组件节点的相对坐标
     99 
    100         // 获取摇杆的角度
    101         let len = jPos.mag();
    102         this.dir.x = jPos.x / len;
    103         this.dir.y = jPos.y / len;
    104 
    105         // 设置摇杆的位置
    106         if (len > this.Max_r) {
    107             jPos.x = this.Max_r * jPos.x / len;
    108             jPos.y = this.Max_r * jPos.y / len;
    109         }
    110         this.joystick.setPosition(jPos);
    111     },
    112 
    113     cbTouchEnd(event) {
    114         // 初始化摇杆节点位置及角度
    115         this.joystick.setPosition(cc.v2(0, 0));
    116         this.dir = cc.v2(0, 0);
    117         this.node.active = false;
    118     },
    119 
    120     cbTouchCancel(event) {
    121         // 初始化摇杆节点位置及角度
    122         this.joystick.setPosition(cc.v2(0, 0));
    123         this.dir = cc.v2(0, 0);
    124         this.node.active = false;
    125     }
    126 });

    4.最后将写好的脚本挂载到 Rocker 节点上保存为 Prefab 就可以使用了:

    使用步骤:

    1.创建好场景和玩家角色后,将 Rocker 组件拖到场景中,并将 Canvas 和 玩家角色挂载到对应的位置,设置好合适的移动速度和摇杆移动半径后就可以使用了:

    2.可以看到已经可以流畅的控制玩家移动了:

    最后:

    不知道小伙伴们学会了没有,赶快来试试看吧,有什么好的建议都可以在下面评论或者私信告诉我哦!


    推荐阅读:

    让蔡徐坤来教你实现游戏中的帧动画(上)

    让蔡徐坤来教你实现游戏中的帧动画(中)

    一文教你实现「飞机大战」里战机的控制逻辑


    我是「Super于」,立志做一个每天都有正反馈的人!

  • 相关阅读:
    Struts2
    Struts2
    学习python的第九天
    学习python的第八天--作业
    学习python的第七天--作业
    学习python第六天 --作业
    学习python的第六天---1(理论)
    学习python第五天
    学习python第四天
    学习python第三天
  • 原文地址:https://www.cnblogs.com/yu97271486/p/11459189.html
Copyright © 2020-2023  润新知