基于cocos creator 3.4 实现虚拟摇杆
·
项目结构如下图:

1.说明:为了测试方便我都把两个脚本挂载到了Canvas上了。加了三个精灵组件一个dayuan(大圆),就是大浅蓝色的,作为摇杆盘,一个xiaoyuan(小圆)就是深蓝色的作为摇杆,还有一个feidie(飞碟)作为被控制的角色。其中xiaoyuan精灵节点时dayuan的子节点。
2.把下面两个脚本组件都挂在到Canvas上
摇杆代码Joystick.ts
import { _decorator, Component, Node, Vec3, Touch, UITransform, v3 } from 'cc';
const { ccclass, property } = _decorator;
/**
* Predefined variables
* Name = JoyStick
* DateTime = Mon Jun 20 2022 14:42:05 GMT+0800 (中国标准时间)
* Author = fangfan001
* FileBasename = JoyStick.ts
* FileBasenameNoExtension = JoyStick
* URL = db://assets/scripts/JoyStick.ts
* ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
*
*/
@ccclass('JoyStick')
export class JoyStick extends Component {
//大圆
@property(Node)
panel: Node = null;
//小圆
@property(Node)
btn: Node = null;
//小圆在大圆中移动的限制距离
private panelWidth: number = 100;
//大圆初始位置
private panelInitPos: Vec3;
//触摸ID
private touchID: number;
//用于保存移动方向向量
public dir: Vec3 = new Vec3(0, 0, 0);
//保存弧度(角度)
public angle: number = 0;
//是否正在移动
public moving: boolean = false;
onLoad() {
//初始化大圆的为止
this.panelInitPos = new Vec3(-250, -150, 0);
}
start() {
this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
}
public stop() {
this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
this.moving = false;
this.enabled = false;
}
private onTouchStart(e: Touch) {
//触摸点世界坐标转成局部坐标
let uiTransform = this.node.getComponent(UITransform);
let p = new Vec3(e.getLocation().x, e.getLocation().y, 0);
let pos = new Vec3();
uiTransform.convertToNodeSpaceAR(p, pos);
//当触摸时设置大圆和小圆的显示位置
this.panel.setPosition(pos);
this.btn.setPosition(new Vec3(0, 0, 0));
this.touchID = e.getID();
this.moving = false;
this.enabled = true;
}
private onTouchMove(e: Touch) {
if (this.touchID != e.getID()) {
return;
}
//小圆移动,改变小圆实时位置
let posDelta = e.getDelta();
console.log("posDelta", this.btn.getPosition());
let x = this.btn.getPosition().x + posDelta.x;
let y = this.btn.getPosition().y + posDelta.y;
//console.log("posDelta",x,y);
this.btn.setPosition(new Vec3(x, y, 0));
//正在移动
this.moving = true;
}
update() {
if (this.moving) {
//将小圆限制大圆范围内
console.log("this.btn.position", this.btn.position);
let ratio = this.btn.position.length() / this.panelWidth;
let xbi = this.btn.position.x / this.btn.position.length();
let ybi = this.btn.position.y / this.btn.position.length();
console.log("ratio", this.btn.position.length());
if (ratio > 1) {
this.btn.setPosition(new Vec3(xbi * this.panelWidth, ybi * this.panelWidth, 0));
}
//保存向量方向
this.dir = new Vec3(xbi, ybi, 0);
console.log("this.dir", this.dir);
//获取弧度
this.angle = Math.atan2(this.btn.getPosition().y, this.btn.getPosition().x);
}
}
private onTouchEnd(e: Touch) {
//还原大圆和小圆位置
if (this.touchID != e.getID()) {
return;
}
this.panel.setPosition(this.panelInitPos);
this.btn.setPosition(new Vec3(0, 0, 0));
this.moving = false;
this.enabled = false;
}
private onTouchCancel(e: Touch) {
if (this.touchID != e.getID()) {
return;
}
this.panel.setPosition(this.panelInitPos);
this.btn.setPosition(0, 0);
this.moving = false;
this.enabled = false;
}
onDestroy() {
this.stop();
}
}
初始化代码组件:
yaogan.ts
import { _decorator, Component, Node, Vec3 } from 'cc';
const { ccclass, property } = _decorator;
//import { JoyStick } from './JoyStick';
/**
* Predefined variables
* Name = yaogan
* DateTime = Mon Jun 20 2022 10:20:08 GMT+0800 (中国标准时间)
* Author = fangfan001
* FileBasename = yaogan.ts
* FileBasenameNoExtension = yaogan
* URL = db://assets/scripts/yaogan.ts
* ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
*
*/
@ccclass('yaogan')
export class yaogan extends Component {
//虚拟摇杆组件
joyStick: any = null;
//角色
@property(Node)
role: Node = null;
//速度
speed: Vec3 = new Vec3(6, 6, 0);
onLoad() {
this.joyStick = this.node.getComponent("JoyStick");
}
start() {
}
update() {
if (this.joyStick.moving) {
//根据角度移动
let x = this.role.getPosition().x + Math.cos(this.joyStick.angle) * this.speed.x;
let y = this.role.getPosition().y + Math.sin(this.joyStick.angle) * this.speed.y;
//根据向量移动
// let x = this.role.getPosition().x+this.joyStick.dir.x*this.speed.x;
// let y = this.role.getPosition().y+this.joyStick.dir.y*this.speed.y;
this.role.setPosition(new Vec3(x, y, 0));
}
}
}
3.将组件代码挂载后,将精灵节点拖到对应的节点框,保存场景后运行即可
4.如果谁有更好的实现虚拟摇杆的方法,请给我留言,给我传授传授经验。谢谢抱拳
更多推荐
所有评论(0)