首页 > 其他分享 >【工具类】Cocos 虚拟摇杆

【工具类】Cocos 虚拟摇杆

时间:2022-09-05 12:01:04浏览次数:80  
标签:node Node Cocos 大圆 cc 摇杆 虚拟 触摸

版本:2.4.10

 

之前用Egret时写过一个虚拟摇杆 Egret虚拟摇杆 ,这里用Cocos实现。

 

一 演示效果

 

二  摇杆原理

和Egret的虚拟摇杆实现原理是一样的

 

 

三 虚拟摇杆实现

1. 使用Math.atan2正切函数获取小圆距离原点的弧度,再用 弧度*180/Math.PI 转成角度。

2. 触摸移动时,小圆移动到触摸位置,小圆不能超出大圆范围,用变量 circleRadius 设置小圆移动范围,这个值一般是大圆半径,但是大小圆图片可能留白较多,所以还是要自己设置。

3. 触摸开始、滑动、结束都会抛出事件,用于处理其它事件。

4. 为了防止多点触摸,需要比较 cc.Event.EventTouch的getID()。

const { ccclass, property, menu } = cc._decorator;


/**
 * 虚拟摇杆
 * @author chenkai 2022.9.5
 */
@ccclass
@menu("framework/Joystick")
export default class Joystick extends cc.Component {
    /**触摸开始 */
    public static START: string = "JoystickEvent_TouchStart";
    /**触摸移动 */
    public static MOVE: string = "JoystickEvent_TouchMove";
    /**触摸结束 */
    public static END: string = "JoystickEvent_TouchEnd";


    /**大圆 */
    @property({ type: cc.Node, tooltip: "大圆" })
    bigCircle: cc.Node = null;
    /**小圆 */
    @property({ type: cc.Node, tooltip: "小圆" })
    smallCircle: cc.Node = null;
    /**小圆移动范围半径 (小圆移动范围在大圆以内,所以小圆移动范围半径约等于大圆的半径)*/
    @property({ type: cc.Integer, tooltip: "小圆移动半径" })
    circleRadius: number = 0;

    /**大圆初始位置 */
    private _bigCircleInitPos: cc.Vec2 = new cc.Vec2(0, 0);
    /**触摸ID,防多点触摸 */
    private _touchID: number = 0;

    onl oad() {
        this._bigCircleInitPos = new cc.Vec2(this.bigCircle.x, this.bigCircle.y);
    }

    onDestroy() {

    }

    /**启动虚拟键盘 */
    public start() {
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    }

    /**停止虚拟键盘 */
    public stop() {
        this.node.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    }

    /**触摸开始 */
    private onTouchStart(e: cc.Event.EventTouch) {
        //触摸点世界坐标转成局部坐标
        let pos = this.node.convertToNodeSpaceAR(e.getLocation());
        this.bigCircle.setPosition(pos);
        this.smallCircle.setPosition(0, 0);
        this._touchID = e.getID();
        this.node.emit(Joystick.START);
    }

    /**触摸移动 */
    private onTouchMove(e: cc.Event.EventTouch) {
        //防多点触摸
        if (this._touchID != e.getID()) {
            return;
        }

        //获取触摸点和虚拟摇杆的距离、弧度
        let location = e.getLocation();                                                         //触摸点当前世界坐标
        let startLocation = e.getStartLocation();                                               //触摸起始点世界坐标
        let dist = cc.Vec2.distance(location, startLocation);                                   //触摸点和大圆距离 (大圆坐标 = 触摸起始点坐标)
        let radian = Math.atan2(location.y - startLocation.y, location.x - startLocation.x);    //触摸点和大圆夹角弧度

        //触摸点在大圆范围内,则小圆位置移动到当前触摸点
        if (dist <= this.circleRadius) {
            let smallPos = this.bigCircle.convertToNodeSpaceAR(location);
            this.smallCircle.setPosition(smallPos);
            //触摸点在圆环范围外,如果小圆移动到当前触摸点就会跑出大圆了,所以小圆位置移动到大圆边缘
        } else {
            this.smallCircle.x = Math.cos(radian) * this.circleRadius;
            this.smallCircle.y = Math.sin(radian) * this.circleRadius;
        }

        //派发移动事件
        this.node.emit(Joystick.MOVE, radian * 180 / Math.PI);
    }

    /**触摸结束 */
    private onTouchEnd(e: cc.Event.EventTouch) {
        //防多点触摸
        if (this._touchID != e.getID()) {
            return;
        }
        //大圆回到起始位置
        this.bigCircle.setPosition(this._bigCircleInitPos);
        //小圆回到原点
        this.smallCircle.setPosition(0, 0);
        //派发触摸结束事件
        this.node.emit(Joystick.END);
    }

    /**触摸结束,在虚拟摇杆之外的位置松开手指 */
    private onTouchCancel(e: cc.Event.EventTouch) {
        this.onTouchEnd(e);
    }

}

  

四 实际使用

joystick是挂组件Joystick.ts的节点,这个节点的高宽就是触摸范围。

bigCircle是大圆

smallCircle是小圆

angleLab是角度文本

 

 

 

const { ccclass, property } = cc._decorator;

@ccclass
export default class MainScene extends cc.Component {

    @property({ type: Joystick, tooltip: "虚拟摇杆" })
    joystick: Joystick = null;
    @property({ type: cc.Label, tooltip: "角度文本" })
    angleLab: cc.Label = null;

    onl oad() {
        this.joystick.node.on(Joystick.START, () => {
            console.log("触摸开始");
        });
        this.joystick.node.on(Joystick.MOVE, (angle: number) => {
            this.angleLab.string = "角度:" + Math.round(angle);
        });
        this.joystick.node.on(Joystick.END, () => {
            console.log("触摸结束");
            this.angleLab.string = "角度:" + 0;
        });
        this.joystick.start();

    }
}

  

 

搜索

复制

标签:node,Node,Cocos,大圆,cc,摇杆,虚拟,触摸
From: https://www.cnblogs.com/gamedaybyday/p/16657623.html

相关文章

  • 【日常分享】Windows10操作系统下虚拟机VMware打开后蓝屏的问题的一种解决方案(PAGE_FA
    【日常分享】Windows10操作系统下虚拟机VMware打开后蓝屏的问题的一种解决方案(PAGE_FAULT_IN_NONPAGED_AREA)一、问题最近想学习Linux操作系统,于是装了虚拟机VMwarework......
  • 虚拟机常用配置
    虚拟机常用配置准备工作镜像文件:CentOS-7-x86_64-Everything-2207-02.isoSSH客户端:MobaXterm宿主机:Win10虚拟机载体:VmwareWorkstationPro16软件源配置CentOS7......
  • 虚拟机常用配置
    虚拟机常用配置准备工作镜像文件:CentOS-7-x86_64-Everything-2207-02.isoSSH客户端:MobaXterm宿主机:Win10虚拟机载体:VmwareWorkstationPro16软件源配置CentOS7......
  • 在hyper-v虚拟机中安装并配置linux
    虽然都是自己写的,还是贴个原文链接吧,如果文章里的图片错乱了,可能就是我贴错了,去看原文吧。⚠多图警告WSL2真香?WSL2相比于WSL1前者更类似于虚拟机,配合上WindoesTermi......
  • 基于win10电脑的虚拟机安装(CentOS)
    基于win10电脑的虚拟机安装(CentOS)此文记录笔者安装CentOS的全过程。(因为重装了电脑,原来的Ubuntu没了,重新装一个CentOS系统学习Linux)目录一、下载CentOS二、CentO......
  • H3C云计算和虚拟化概念
    1、云计算虚拟化基本概念1.1虚拟化虚拟化使用软件定义的方式重新划分IT资源,可以实现IT资源的动态分配、灵活调度、跨域共享,提高IT资源利用率,使IT资源能够真正成为社会基......
  • 关于windows11 家庭版 无法关闭内核DMA和基于虚拟化安全的问题(AR40报错)
    系统版本:windows11家庭版,出厂自带的windows11家庭版(预装)CPU是inter的11代我忘记具体型号了(另一台也是inter12代的I7出现过)问题概述:在关闭了hyper-v后和手动关闭了内核......
  • 使用VMware Workstation创建的虚拟机无法连接网络解决方法
    引言:最近打开虚拟机老是连接不上网络,在网上找这前两个方法试还是一直不行,最后才知道忘记重启DHCPservice和NATservice1、查看虚拟机的设置,确保虚拟机网络连接的方式勾选......
  • 如何安装配置VM虚拟机
    1.准备材料虚拟机安装程序虚拟机激活码 2.跟随安装向导进行安装同意协议条款可更改安装位置,添加控制台工具取消了更新和体验计划添加快捷方式开始安装,耐心......
  • 虚拟机中CentOS7 配置网卡
    基于vm16pro虚拟机Linux系统:centos7.6l 开启网卡安装完成系统后发现网卡默认没有开启,无法链接网络。vi/etc/sysconfig/network-scripts/ifcfg-ens33   ifc......