Cocos Creator 虚拟摇杆

Stella981
• 阅读 1014

版本:2.3.4

参考:

【持续更新】Cocos Creator源码分享——针对游戏中的各种功能

和原文的区别

1. 监听事件不使用字符串。例如"touchstart",使用cc.Node.EventType.TOUCH_START。因为使用字符串容易拼错。

2. 增加触摸响应区域。因为常规游戏中,虚拟摇杆可响应范围不仅仅是虚拟摇杆图片范围,而是一个可根据策划需求调整的范围,例如今天500x400,明天觉得600x400,只需要修改代码,不需要重新制作图片了。

3. 防止多点触摸。增加了touchID的判断,防止多个手指触摸导致的问题。例如一个手指在操作摇杆,另一个手指不小心在触摸区域点击了一下,导致触发了touch_end,使摇杆失效。

4. 增加了小圆移动范围设置。原来文章用大圆图片的高宽限制小圆的移动范围。但是大圆图片可能有透明区域,所以这里小圆的移动范围在代码里手动设置。

UI如下图,为了方便area用绿色显示,实际使用去掉就行了。

Cocos Creator 虚拟摇杆

虚拟摇杆代码

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class JoyStick extends cc.Component {

    @property(cc.Node)
    panel:cc.Node = null;   //大圆

    @property(cc.Node)
    btn:cc.Node = null;     //小圆

    @property(cc.Integer)
    private panelWidth:number = 130;    //去掉透明区域的大圆宽度

    private panelInitPos:cc.Vec2; //大圆初始位置
    private touchID:number;    //触摸ID


    public dir:cc.Vec3 = new cc.Vec3(0,0,0);  //移动方向
    public angle:number = 0;   //弧度(角度)
    public moving:boolean = false; //是否正在移动

    onLoad(){
        this.panelInitPos =  new cc.Vec2(this.panel.x, this.panel.y);
    }

    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);

        this.moving = false;
    }

    private onTouchStart(e:cc.Touch){
        console.log("start");
        //触摸点世界坐标转成局部坐标
        let pos = this.node.convertToNodeSpaceAR(e.getLocation());
        this.panel.setPosition(pos);
        this.btn.setPosition(0,0);
        this.touchID = e.getID();
    }

    private count = 1;
    private onTouchMove(e:cc.Touch){
        console.log("move");
        if(this.touchID != e.getID()){
            return;
        }
        //小圆移动
        let posDelta = e.getDelta();
        this.btn.x += posDelta.x;
        this.btn.y += posDelta.y;

        //将小圆限制大圆范围内
        let ratio = this.btn.position.mag() / this.panelWidth;
        if (ratio > 1) {
            this.btn.setPosition(this.btn.position.div(ratio));
        }

        //获取向量归一化
        this.dir = this.btn.position.normalizeSelf();
        //获取弧度
        this.angle = Math.atan2(this.btn.y, this.btn.x);
        //正在移动
        this.moving = true;
    }

    private onTouchEnd(e:cc.Touch){
        console.log("end");
        if(this.touchID != e.getID()){
            return;
        }
        this.panel.setPosition(this.panelInitPos);
        this.btn.setPosition(0,0);
        this.moving = false;
    }

    private onTouchCancel(e:cc.Touch){
        console.log("cancel");
        if(this.touchID != e.getID()){
            return;
        }
        this.panel.setPosition(this.panelInitPos);
        this.btn.setPosition(0,0);
        this.moving = false;
    }

    onDestroy(){
        this.stop();
    }

}

实际操作

@ccclass
export default class Helloworld extends cc.Component {

    //虚拟摇杆Area
    @property(cc.Node)
    joyStickArea:cc.Node = null;
    //虚拟摇杆代码
    joyStick:JoyStick;
    //角色
    @property(cc.Node)
    role:cc.Node = null;
    //速度
    speed:cc.Vec2 = new cc.Vec2(5,5);

    onLoad(){
        this.joyStick = this.joyStickArea.getComponent(JoyStick);
    }

    start() {
       
    }

    update(){
        if(this.joyStick.moving){
            //根据角度移动
            // this.role.x += Math.cos(this.joyStick.angle)*this.speed.x;
            // this.role.y += Math.sin(this.joyStick.angle)*this.speed.y;
            //根据向量移动
            this.role.x += this.joyStick.dir.x*this.speed.x;
            this.role.y += this.joyStick.dir.y*this.speed.y;
        }
    }
}

演示效果

Cocos Creator 虚拟摇杆

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这