CocosCreator封装摇杆 摇杆控制角色移动 绝对好用(如何使用 + 原理讲解)

10/18 07:17
阅读数 22

源码获取方式在最下面
先看效果
在这里插入图片描述

本文分为两个部分

如何使用
原理讲解

如何使用

一共需要四个节点

  • bg:作为背景

在这里插入图片描述

  • joystick:作为摇杆的点

在这里插入图片描述

  • player:角色(我这里拿一个小坦克当角色,因为坦克可以更直观的观察角色的旋转)

在这里插入图片描述

  • parent:作为摇杆(joystick)和背景(bg)的父节点 这是一个空节点,我们就把脚本挂在这个节点上

写脚本
先来介绍下属性(不包括刚刚说的那四个节点)

  • max_R
    类型是 number
    摇杆移动的最大半径

  • speed
    类型是 number
    玩家移动速度
    不建议太大,1-10最好


  • rotation
    类型是 number
    玩家的旋转角度

  • vector
    类型是cc.Vec2
    移动向量,通过修改这个平面向量来控制角色的移动

  • is_rotation
    类型是 Boolean
    角色是否根据摇杆的方向旋转

  • is_forbidden
    类型是 Boolean
    是否禁用摇杆
    禁用后摇杆将不能使用


新建一个脚本,把下面的代码复制粘贴到里面

const {
   
   ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
   
   

    @property(cc.Node)
    bg: cc.Node = null;//摇杆背景

    @property(cc.Node)
    joystick: cc.Node = null;//摇杆 也就是中心点

    @property(cc.Node)
    player: cc.Node = null;//角色

    @property(cc.Node)
    parent: cc.Node = null;//摇杆和背景的父节点

    @property
    max_R: number = 135;//摇杆移动的最大半径

    @property
    speed: number = 10;//角色移动速度
    //不建议太大,1-10最好

    @property
    rotation: number = 0;//角色的旋转角度 不要轻易改

    @property
    vector: cc.Vec2 = cc.v2(0,0);//移动向量

    @property
    is_rotation: boolean = true;//角色是否根据摇杆的方向旋转

    @property
    is_forbidden: boolean = false;//是否禁用摇杆

    onLoad(){
   
   
        //绑定事件
        //因为摇杆很小,如果给摇杆绑定事件玩家将很难控制,摇杆的背景比较大,所以把事件都绑定在背景上是不错的选择
        this.bg.on(cc.Node.EventType.TOUCH_MOVE,this.move,this);//当手指在背景上移动时触发move事件
        this.bg.on(cc.Node.EventType.TOUCH_MOVE,this.move_palyer,this);//当手指在背景上移动时触发move_player事件
        this.bg.on(cc.Node.EventType.TOUCH_END,this.finish,this);//当手指在目标节点区域内离开屏幕时触发finish事件
        this.bg.on(cc.Node.EventType.TOUCH_CANCEL,this.finish,this);//当手指在目标节点区域外离开屏幕时触发finish事件
    }

    update(){
   
   
        let x = this.player.x + this.vector.x;
        let y = this.player.y + this.vector.y;//每帧获取角色的坐标加上移动向量

        this.player.position = cc.v3(x, y);//让角色的坐标每帧为自身的坐标加上移动的向量
        
        //求出角色的旋转角度
        if(this.vector.y < 0){
   
   //当摇杆在原点下方时
            //角度是负的
            this.rotation = (-this.vector.angle(cc.v2(1, 0))) / Math.PI * 180;//根据向量先求出弧度,再求出角度
        }else{
   
   //如果摇杆在原点上方时
            //角度是正的
            this.rotation = (this.vector.angle(cc.v2(1, 0))) / Math.PI * 180;//根据向量先求出弧度,再求出角度
        }
    }

    move(event: cc.Event.EventTouch){
   
   //负责移动摇杆 手指移动时调用
        if(this.is_forbidden == false){
   
   //如果没有禁用摇杆
            let pos = new cc.Vec2(event.getLocationX(), event.getLocationY());//获取触点的坐标
            let pos_0 = this.parent.convertToNodeSpaceAR(pos);//将一个点转换到节点 (局部) 空间坐标系,这个坐标系以锚点为原点。

            //pos_0.mag()是这个触点的长度

            if(pos_0.mag() < this.max_R){
   
   //如果触点长度小于我们规定好的最大半径
                this.joystick.x = pos_0.x;//摇杆的坐标为触点坐标
                this.joystick.y = pos_0.y;
            }else{
   
   //如果不
                let pos = pos_0.normalizeSelf();//将触点归一化
                let x = pos.x * this.max_R;//归一化的触点坐标 × 最大半径
                let y = pos.y * this.max_R;

                this.joystick.x = x;//给摇杆坐标赋值
                this.joystick.y = y;
            }    
        }
    }

    move_palyer(){
   
   //负责移动角色 手指移动时调用
        if(this.is_forbidden == false){
   
   //如果没有禁用摇杆
            let dir = this.joystick.position.normalizeSelf();//dir为摇杆坐标的归一化

            this.vector.x = dir.x * this.speed;//给移动向量赋值
            this.vector.y = dir.y * this.speed;//移动向量为方向 × 速度
            if(this.is_rotation == true){
   
   //如果角色可以旋转
                this.player.angle = this.rotation;//根据摇杆的方向旋转角色
            }
        }
    }

    finish(){
   
   //摇杆弹回原位置
        //摇杆坐标和移动向量都为(0,0)
        this.joystick.position = cc.v3(0, 0);
        this.vector = cc.v2(0, 0);
    }

}

绑定好节点
在这里插入图片描述

原理讲解

每句代码我都写了详细的注释哦

先来实现摇杆的移动
在这里插入图片描述
这就是表现上的内容,在拉动摇杆的时候角色并没有动,只是摇杆在动,先来实现这个

需要给背景绑定事件,其实应该给摇杆绑定事件,因为摇杆很小,如果给摇杆绑定事件玩家将很难控制,摇杆的背景比较大,所以把事件都绑定在背景上是不错的选择
在这里插入图片描述
这就是给背景绑定的事件,当手指在背景上移动时触发

首先获取触点坐标,转化为parent节点局部空间坐标系
我们只希望摇杆在规定好的max_R(最大半径)的范围内,不希望摇杆超出这个范围
所以要判定一下触点的坐标在不在我们制定的最大半径范围内,通过mag获取触点坐标的长度,也就是触点距离原点的长度
在这里插入图片描述
比如我想求点A坐标的长度,求出的结果就是绿色线段的长度



再来实现功能内容(控制角色移动)
在这里插入图片描述
把摇杆的坐标归一化,然后 × 速度,赋值给vector,如果可以旋转还要让角色旋转

update
在这里插入图片描述
根据vector求出夹角弧度,再求出角度,判断角度正负
公式
角度转弧度 π/180×角度
弧度变角度 180/π×弧度




最后一定要在松开摇杆时让摇杆弹回原处
在这里插入图片描述
源码在群里面
Cocos技术交流Q群:1130122408
欢迎进群闲聊、技术交流都欢迎
制作不易,感谢你的观看
Thank You~~





展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部