Ⅰ, 三角函數
node
ox1/ox = oy1/oy (類似三角形)ide
/** * 獲取方向弧度 */ public getRadian(): number { if( this.dir.x == 0 && this.dir.y == 0){ return 0; } let radian: number = Math.atan2( this.dir.y ,this.dir.x ); if( radian >= 0 ) return radian; return 2*Math.PI + radian; } /** * 獲取方向角度 */ public getAngle(): number{ let angle: number = this.getRadian()/ Math.PI * 180; if( angle >= 0 ) return angle; return 360 + angle; }
場景設計以下圖, 能夠看到要把stick限制在bg內須要用到類似三角形的原理, 部分代碼以下:函數
let screenPos: Vec2 = e.getLocation();//獲取屏幕座標(stick所在的) let pos: Vec3 = (this.node.getComponent(UITransform) as UITransform).convertToNodeSpaceAR( v3( screenPos.x, screenPos.y, 0 ));//轉joystick和bg同樣 let len: number = Vec2.len( v2(pos.x,pos.y) );//求模 this.dir.x = pos.x / len;//cos x this.dir.y = pos.y / len;//sin y if( len > this.maxR ){ pos.x = pos.x * this.maxR/len; pos.y = pos.y * this.maxR/len; }else if( len < this.minR && this.minR > 0){ pos.x = pos.x * this.minR/len; pos.y = pos.y * this.minR/len; } this.stick.setPosition( pos.x,pos.y);
import { _decorator, Component, Node, log, EventTouch, Vec2, UITransform, Vec3, v3, v2 } from 'cc'; const { ccclass, property } = _decorator; @ccclass('JoyStickCtr') export class JoyStickCtr extends Component { @property( { type: Node } ) // @ts-ignore private stick: Node; @property private maxR: number = 128;//最大移動半徑 @property private minR: number = 20;//最小移動半徑 //@ts-ignore private dir: Vec2; onEnable(){ this.listener( true ); } onDisable(){ this.listener( false ); } private listener( isAdd: boolean ): void { if( isAdd ) { this.stick.on( Node.EventType.TOUCH_START, this.onTouchHandler, this); this.stick.on( Node.EventType.TOUCH_MOVE, this.onTouchHandler, this); this.stick.on( Node.EventType.TOUCH_END, this.onTouchHandler, this); this.stick.on( Node.EventType.TOUCH_CANCEL, this.onTouchHandler, this); }else{ this.stick.off( Node.EventType.TOUCH_START, this.onTouchHandler, this); this.stick.off( Node.EventType.TOUCH_MOVE, this.onTouchHandler, this); this.stick.off( Node.EventType.TOUCH_END, this.onTouchHandler, this); this.stick.off( Node.EventType.TOUCH_CANCEL, this.onTouchHandler, this); } } private onTouchHandler( e : EventTouch): void{ switch (e.type){ case Node.EventType.TOUCH_START: break; case Node.EventType.TOUCH_MOVE: let screenPos: Vec2 = e.getLocation();//獲取屏幕座標(stick所在的) let pos: Vec3 = (this.node.getComponent(UITransform) as UITransform).convertToNodeSpaceAR( v3( screenPos.x, screenPos.y, 0 ));//轉joystick和bg同樣 let len: number = Vec2.len( v2(pos.x,pos.y) );//求模 this.dir.x = pos.x / len;//cos x this.dir.y = pos.y / len;//sin y if( len > this.maxR ){ pos.x = pos.x * this.maxR/len; pos.y = pos.y * this.maxR/len; }else if( len < this.minR && this.minR > 0){ pos.x = pos.x * this.minR/len; pos.y = pos.y * this.minR/len; } this.stick.setPosition( pos.x,pos.y); break; case Node.EventType.TOUCH_END: case Node.EventType.TOUCH_CANCEL: this.stick.setPosition(0,0); this.dir.x = this.dir.y = 0; break; } } /** * 獲取方向向量 */ public getDir(): Vec2{ return this.dir; } /** * 獲取方向弧度(0~2PI) */ public getRadian(): number { if( this.dir.x == 0 && this.dir.y == 0){ return 0; } let radian: number = Math.atan2( this.dir.y ,this.dir.x ); if( radian >= 0 ) return radian; return 2*Math.PI + radian; } /** * 獲取方向角度(0~360) */ public getAngle(): number{ let angle: number = this.getRadian()/ Math.PI * 180; if( angle >= 0 ) return angle; return 360 + angle; } start () { this.dir = v2(0,0); // this.listener( true ); } // update (deltaTime: number) { // // [4] // } }
注: 使用Cocos Creator 3.0.1 引擎this