cocos creator 摇杆

80 阅读2分钟

image.png

摇杆.gif

    @property(cc.Node)
    public stick: cc.Node = null; // 摇杆的控制部分

    @property(cc.Node)
    public joystickBackground: cc.Node = null; // 摇杆的背景部分

    private isTouching: boolean = false; // 标记是否正在触摸
    private maxDistance: number = 100; // 摇杆的最大距离(背景半径)

    private startPos: cc.Vec2 = new cc.Vec2(); // 摇杆背景的起始位置
    static direction: cc.Vec2 = new cc.Vec2(0, 0); // 摇杆的方向(x, y)
  • 这里是定义的一些参数,都有注释,很好理解
    onLoad() {
        // 初始化摇杆背景的起始位置
        this.startPos = this.joystickBackground.convertToWorldSpace(cc.Vec2.ZERO);

        this.joystickBackground.active = false;
    }

    start() {        
        // 添加触摸事件监听
        Joystick.TouchScope.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        Joystick.TouchScope.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        Joystick.TouchScope.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        Joystick.TouchScope.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }
  • 在onload里记录摇杆初始位置,用来记录摇杆的偏移,this.joystickBackground.active是用来让摇杆显示和隐藏的,触摸的时候显示,停止触摸隐藏
    // 开始触摸时记录触摸起始点
    onTouchStart(event: cc.Event.EventTouch) {
        this.isTouching = true;

        this.joystickBackground.active = true;

        const touchPos = event.getLocation();

        console.log(touchPos, 'touchPos');
        

        // 将世界坐标转换为摇杆背景的父节点的本地坐标
        const localPos = this.joystickBackground.parent.convertToNodeSpaceAR(touchPos);

        // 更新摇杆背景的本地坐标
        this.joystickBackground.setPosition(localPos);
    }
    // 在触摸移动过程中更新摇杆的位置
    onTouchMove(event: cc.Event.EventTouch | cc.Vec2) {
        if (!this.isTouching) return;

        let touchPos: cc.Vec2;
        if (event instanceof cc.Event.EventTouch) {
            touchPos = event.getLocation();
        } else {
            touchPos = event;
        }
        
        // 计算触摸位置相对于摇杆背景的偏移量
        let offset = touchPos.subtract(this.startPos);
        
        const distance = offset.mag();

        // 限制摇杆的偏移量不能超过最大距离
        if (distance > this.maxDistance) {
            offset = offset.normalize().multiplyScalar(this.maxDistance); // 保证摇杆位置不超过最大距离
        }
        
        // 更新摇杆控制部分的位置
        // this.stick.setPosition(this.startPos.x + offset.x, this.startPos.y + offset.y);
        this.stick.setPosition(offset.x, offset.y);

        // 计算方向,确保方向范围为[-1, 1]
        Joystick.direction = new cc.Vec2(offset.x / this.maxDistance, offset.y / this.maxDistance);
    }
    // 结束触摸时,恢复摇杆到原点
    onTouchEnd(event: cc.Event.EventTouch) {
        this.isTouching = false;

        this.joystickBackground.active = false;

        this.stick.setPosition(0, 0); // 摇杆指针返回原位
        Joystick.direction.set(new cc.Vec2(0, 0)); // 正确的重置方向
    }
  • 上面是触摸过程中的各个事件,开始触摸就确定好摇杆的位置,在触摸过程中记录方向,偏移量,让摇杆可以摇动,结束的时候还原
    // 获取当前的摇杆方向,值范围是 [-1, 1]
    static getDirection() {
        return Joystick.direction;
    }
  • 静态方法getDirection去获取移动的方向,提供给其他节点去使用
        const direction = Joystick.getDirection();
        this.node.setPosition(this.node.position.x + direction.x * this.speed * dt, this.node.position.y + direction.y * this.speed * dt); // 玩家移动
  • 在例如player里的update生命周期这里,根据direction来移动玩家