Cocos Creator 虚拟摇杆

版本:2.3.4

参考:

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

和原文的区别

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

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

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

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

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

虚拟摇杆代码

1// Learn TypeScript: 2// - https://docs.cocos.com/creator/manual/en/scripting/typescript.html 3// Learn Attribute: 4// - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html 5// Learn life-cycle callbacks: 6// - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html 7 8const {ccclass, property} = cc._decorator; 9 10@ccclass 11export default class JoyStick extends cc.Component { 12 13 @property(cc.Node) 14 panel:cc.Node = null; //大圆 15 16 @property(cc.Node) 17 btn:cc.Node = null; //小圆 18 19 @property(cc.Integer) 20 private panelWidth:number = 130; //去掉透明区域的大圆宽度 21 22 private panelInitPos:cc.Vec2; //大圆初始位置 23 private touchID:number; //触摸ID 24 25 26 public dir:cc.Vec3 = new cc.Vec3(0,0,0); //移动方向 27 public angle:number = 0; //弧度(角度) 28 public moving:boolean = false; //是否正在移动 29 30 onLoad(){ 31 this.panelInitPos = new cc.Vec2(this.panel.x, this.panel.y); 32 } 33 34 start () { 35 this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this); 36 this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this); 37 this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this); 38 this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this); 39 } 40 41 public stop(){ 42 this.node.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this); 43 this.node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this); 44 this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this); 45 this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this); 46 47 this.moving = false; 48 } 49 50 private onTouchStart(e:cc.Touch){ 51 console.log("start"); 52 //触摸点世界坐标转成局部坐标 53 let pos = this.node.convertToNodeSpaceAR(e.getLocation()); 54 this.panel.setPosition(pos); 55 this.btn.setPosition(0,0); 56 this.touchID = e.getID(); 57 } 58 59 private count = 1; 60 private onTouchMove(e:cc.Touch){ 61 console.log("move"); 62 if(this.touchID != e.getID()){ 63 return; 64 } 65 //小圆移动 66 let posDelta = e.getDelta(); 67 this.btn.x += posDelta.x; 68 this.btn.y += posDelta.y; 69 70 //将小圆限制大圆范围内 71 let ratio = this.btn.position.mag() / this.panelWidth; 72 if (ratio > 1) { 73 this.btn.setPosition(this.btn.position.div(ratio)); 74 } 75 76 //获取向量归一化 77 this.dir = this.btn.position.normalizeSelf(); 78 //获取弧度 79 this.angle = Math.atan2(this.btn.y, this.btn.x); 80 //正在移动 81 this.moving = true; 82 } 83 84 private onTouchEnd(e:cc.Touch){ 85 console.log("end"); 86 if(this.touchID != e.getID()){ 87 return; 88 } 89 this.panel.setPosition(this.panelInitPos); 90 this.btn.setPosition(0,0); 91 this.moving = false; 92 } 93 94 private onTouchCancel(e:cc.Touch){ 95 console.log("cancel"); 96 if(this.touchID != e.getID()){ 97 return; 98 } 99 this.panel.setPosition(this.panelInitPos); 100 this.btn.setPosition(0,0); 101 this.moving = false; 102 } 103 104 onDestroy(){ 105 this.stop(); 106 } 107 108}

实际操作

1@ccclass 2export default class Helloworld extends cc.Component { 3 4 //虚拟摇杆Area 5 @property(cc.Node) 6 joyStickArea:cc.Node = null; 7 //虚拟摇杆代码 8 joyStick:JoyStick; 9 //角色 10 @property(cc.Node) 11 role:cc.Node = null; 12 //速度 13 speed:cc.Vec2 = new cc.Vec2(5,5); 14 15 onLoad(){ 16 this.joyStick = this.joyStickArea.getComponent(JoyStick); 17 } 18 19 start() { 20 21 } 22 23 update(){ 24 if(this.joyStick.moving){ 25 //根据角度移动 26 // this.role.x += Math.cos(this.joyStick.angle)*this.speed.x; 27 // this.role.y += Math.sin(this.joyStick.angle)*this.speed.y; 28 //根据向量移动 29 this.role.x += this.joyStick.dir.x*this.speed.x; 30 this.role.y += this.joyStick.dir.y*this.speed.y; 31 } 32 } 33}

演示效果

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )