美文网首页游戏开发小白变怪兽
自定义虚拟摇杆组件让你一劳永逸

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

作者: 测试开发小白变怪兽 | 来源:发表于2019-09-25 11:12 被阅读0次

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

    实现思路:

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

    实现过程:

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

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

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

    // Rocker.js
    
    cc.Class({
        extends: cc.Component,
    
        properties: {
            sceneNode: {    // 场景节点
                type: cc.Node,
                default: null,
            },
    
            playerNode: {    // player节点
                type: cc.Node,
                default: null,
            },
    
            playerNodeSpeed: 100,    // player移动速度
    
            Max_r: 100,    // 摇杆移动半径,根据自己美术资源进行调整
        },
    
        onLoad() {
            // 隐藏摇杆组件节点
            this.node.active = false;
    
            // 获取摇杆节点并初始化摇杆节点位置及角度
            this.joystick = this.node.getChildByName('joystick')
            this.joystick.setPosition(cc.v2(0, 0));
            this.dir = cc.v2(0, 0);
    
            // 注册父节点的 touch 监听事件
            this.sceneNode.on(cc.Node.EventType.TOUCH_START, this.cbTouchStart, this);
            this.sceneNode.on(cc.Node.EventType.TOUCH_MOVE, this.cbTouchMove, this);
            this.sceneNode.on(cc.Node.EventType.TOUCH_END, this.cbTouchEnd, this);
            this.sceneNode.on(cc.Node.EventType.TOUCH_CANCEL, this.cbTouchCancel, this);
        },
    
        update(dt) {
            if (this.dir.mag() < 0.5) {
                return;
            }
    
            let vx = this.dir.x * this.playerNodeSpeed;
            let vy = this.dir.y * this.playerNodeSpeed;
    
            let sx = vx * dt;
            let sy = vy * dt;
            //移动
            this.playerNode.x += sx;
            this.playerNode.y += sy;
    
            let windowsSize = cc.winSize;
    
            let minX = -windowsSize.width / 2 + this.playerNode.width / 2;    // 最小X坐标
            let maxX = Math.abs(minX);    // 最大X坐标
            let minY = -windowsSize.height / 2 + this.playerNode.height / 2;    // 最小Y坐标
            let maxY = Math.abs(minY);    // 最大Y坐标
    
            let currentPos = this.playerNode.getPosition();
    
            if (currentPos.x < minX) {
                currentPos.x = minX;
            } else if (currentPos.x > maxX) {
                currentPos.x = maxX;
            } 
            
            if (currentPos.y < minY) {
                currentPos.y = minY;
            } else if (currentPos.y > maxY) {
                currentPos.y = maxY;
            }
    
            this.playerNode.setPosition(currentPos);
    
            //方向计算
            var r = Math.atan2(this.dir.y, this.dir.x);
            var degree = r * 180 / (Math.PI);
            degree = 360 - degree + 90;
            this.playerNode.rotation = degree;
        },
    
        cbTouchStart(event) {
            let pos = event.getLocation();
    
            // 点击时显示摇杆组件节点并设置位置
            this.node.active = true;
            let rPos = this.sceneNode.convertToNodeSpaceAR(pos);    // 将世界坐标转化为场景节点的相对坐标
            this.node.setPosition(rPos);
            
            // 初始化摇杆节点位置及角度
            this.joystick.setPosition(cc.v2(0, 0));
            this.dir = cc.v2(0, 0);
        },
    
        cbTouchMove(event) {
            var pos = event.getLocation();
    
            var jPos = this.node.convertToNodeSpaceAR(pos);    // 将世界坐标转化为摇杆组件节点的相对坐标
    
            // 获取摇杆的角度
            let len = jPos.mag();
            this.dir.x = jPos.x / len;
            this.dir.y = jPos.y / len;
    
            // 设置摇杆的位置
            if (len > this.Max_r) {
                jPos.x = this.Max_r * jPos.x / len;
                jPos.y = this.Max_r * jPos.y / len;
            }
            this.joystick.setPosition(jPos);
        },
    
        cbTouchEnd(event) {
            // 初始化摇杆节点位置及角度
            this.joystick.setPosition(cc.v2(0, 0));
            this.dir = cc.v2(0, 0);
            this.node.active = false;
        },
    
        cbTouchCancel(event) {
            // 初始化摇杆节点位置及角度
            this.joystick.setPosition(cc.v2(0, 0));
            this.dir = cc.v2(0, 0);
            this.node.active = false;
        }
    });
    
    

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

    使用步骤:

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

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

    最后:

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


    推荐阅读:

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

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

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


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

    image

    相关文章

      网友评论

        本文标题:自定义虚拟摇杆组件让你一劳永逸

        本文链接:https://www.haomeiwen.com/subject/kyplyctx.html