Cocos Creator Joystick虚拟摇杆
程序员文章站
2024-02-15 09:35:58
...
UI设计部分
代码部分
import {Vec2Pool} from "../../Common/Pools/Vec2Pool";
const {ccclass, property} = cc._decorator;
@ccclass
export class Joystick extends cc.Component {
@property(cc.Integer)
anglePreDirQuadrant:number = 23;//每个象限的大小
@property(cc.Node)
fixedPoint:cc.Node;
@property(cc.Node)
movePoint:cc.Node;
@property({default:100})
movePointMoveRadius:number=100;
private touchID:number;//触摸事件ID(多点触控)
private touchArea:cc.Vec2;//触摸区域大小
private fixedPointMoveCenterPos:cc.Vec2;//固定点移动中心
private fixedPointMoveRadius:number;//固定点移动半径
private movePointMoveCenterPos:cc.Vec2;//移动点移动中心
private joystickInputDir:cc.Vec2;
onLoad() {
let nodeSize = this.node.getContentSize()
this.touchArea = new cc.Vec2(nodeSize.width,nodeSize.height)
//固定点位置范围
this.fixedPointMoveCenterPos = this.touchArea.divƒ)
this.fixedPointMoveRadius = this.touchArea.x/2 - this.movePointMoveRadius;
this.node.on(cc.Node.EventType.TOUCH_START, function (event:cc.Event.EventTouch) {
if (this.touchID==-1){
//触摸位置
let touchStartPos = event.getLocation()
let _pos = new cc.Vec2(touchStartPos.x,touchStartPos.y)
_pos.subSelf(this.node.position)
//控制位置
let pos = this.clampPos(_pos,this.fixedPointMoveCenterPos,this.fixedPointMoveRadius)
this.movePointMoveCenterPos = pos;
//设置固定点位置
this.setFixedPointPos(pos)
this.setMovePointPos(pos)
this.touchID = event.getID()
}
}, this)
this.node.on(cc.Node.EventType.TOUCH_MOVE, function (event:cc.Event.EventTouch) {
if (this.touchID==event.getID()){
//触摸位置
let nowPos = event.getLocation()
let _pos = new cc.Vec2(nowPos.x,nowPos.y)
_pos.subSelf(this.node.position)
//控制位置
let pos = this.clampPos(_pos,this.movePointMoveCenterPos,this.movePointMoveRadius)
//设置固定点位置
this.setMovePointPos(pos)
}
}, this)
this.node.on(cc.Node.EventType.TOUCH_END, function (event) {
this.init()
}, this)
this.node.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
this.init()
}, this)
this.init()
}
/**
* 初始化
*/
init(){
this.touchID = -1;
this.joystickInputDir = new cc.Vec2()
this.setFixedPointPos(this.fixedPointMoveCenterPos)
this.setMovePointPos(this.fixedPointMoveCenterPos)
}
/**
* 设置固定点位置
*/
public setFixedPointPos(pos:cc.Vec2){
this.fixedPoint.setPosition(pos)
}
/**
* 获取固定点位置
*/
public getFixedPointPos(){
return this.fixedPoint.getPosition()
}
/**
* 设置移动点位置
*/
public setMovePointPos(pos:cc.Vec2){
this.movePoint.setPosition(pos)
}
/**
* 获取移动点位置
*/
public getMovePointPos(){
return this.movePoint.getPosition()
}
/**
* 圆形限制,防止溢出
* @param pos 需要固定位置
* @param centerPos 限制中心位置
* @param radius 限制半径
*/
public clampPos(pos:cc.Vec2,centerPos:cc.Vec2,radius:number):cc.Vec2{
let dpos = pos.sub(centerPos)
if (dpos.mag()>radius){
return dpos.normalize().mul(radius).add(centerPos)
}else{
return pos;
}
}
/**
* 获取摇杆输入方向
*/
public getInputDir():cc.Vec2{
let dir = this.movePoint.getPosition().sub(this.fixedPoint.getPosition())
if (dir.mag()>0){
dir.normalizeSelf()
}
return dir;
}
/**
* 获取摇杆象限输入方向(轴)
*/
public getInputQuadrantDir():cc.Vec2{
return this.getVec2ByQuadrant(this.getDirQuadrant(this.getInputDir()))
}
/**
* 获取方向所在象限
* @param vec 方向
*/
public getDirQuadrant(vec:cc.Vec2):number{
let dirQuadrant:number = null;
if (vec.mag()>0){
//非零向量
dirQuadrant = Math.floor(this.getAngleByVec2(vec)/this.anglePreDirQuadrant)
}
//console.log(this.getAngleByVec2(vec),dirQuadrant)
return dirQuadrant;
}
/**
* 二维方向获取角度
* @param vec 方向
*/
public getAngleByVec2(vec:cc.Vec2):number{
return -Math.atan2(vec.y,vec.x)*鳴/Math.PI) + this.anglePreDirQuadrant/2;//this.anglePreDirQuadrant/2 用于旋转坐标系
}
/**
* 角度获取二位方向
* @param angle
*/
public getVec2ByAngle(angle:number):cc.Vec2
{
let dir:cc.Vec2=new cc.Vec2()
let rad:number = (this.anglePreDirQuadrant/2-angle)*(Math.PI/180)//this.anglePreDirQuadrant/2 用于旋转坐标系
dir.x=Math.cos(rad)
dir.y=Math.sin(rad)
return dir.normalizeSelf()
}
/**
* 根据方向象限获取角度
* @param dirQuadrant
*/
public getVec2ByQuadrant(dirQuadrant:number):cc.Vec2{
if (dirQuadrant!=null){
let angle:number = dirQuadrant*this.anglePreDirQuadrant;
//获取象限的中心轴向
angle+=this.anglePreDirQuadrant/2;
return this.getVec2ByAngle(angle)
}else{
return cc.Vec2.ZERO;
}
}
}
getInputQuadrantDir()函数作用及实现
作用:摇杆模拟n向轴效果,有些游戏中并不需要使用万向轴,譬如马里奥只需要简单4向轴作为摇杆即可。
实现:黑色为坐标轴,红色为象限的角平分线,当坐标落在1、2区块时,方向确定在这两个区块的角平分线,再根据玩家的习惯将坐标轴旋转,得到最终的效果.