123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- const { ccclass, property } = cc._decorator;
- /**
- * 方向类型
- */
- export enum DirectionType {
- FOUR,
- EIGHT,
- ALL,
- }
- /**
- * 速度类型
- */
- export enum SpeedType {
- STOP,
- NORMAL,
- FAST,
- }
- /**
- * 摇杆类型
- */
- export enum JoystickType {
- FIXED,
- FOLLOW,
- }
- /**
- * 摇杆类
- */
- @ccclass
- export default class Joystick_mag extends cc.Component {
- @property({
- type: cc.Node,
- displayName: "Dot",
- tooltip: "摇杆操纵点",
- })
- dot = null;
- @property({
- type: cc.Node,
- displayName: "Ring",
- tooltip: "摇杆背景节点",
- })
- ring = null;
- @property({
- type: cc.Enum(JoystickType),
- displayName: "Touch Type",
- tooltip: "触摸类型",
- })
- joystickType = JoystickType.FIXED;
- @property({
- type: cc.Enum(DirectionType),
- displayName: "Direction Type",
- tooltip: "方向类型",
- })
- directionType = DirectionType.ALL;
- @property({
- type: cc.Node,
- tooltip: "摇杆所在位置",
- })
- _stickPos = null;
- @property({
- type: cc.Node,
- tooltip: "触摸位置",
- })
- _touchLocation = null;
- @property({
- tooltip: "半径",
- })
- _radius = 0;
- /**
- * 事件回调
- */
- private callback:(speedType:SpeedType,moveVec?:cc.Vec2)=>void = undefined;
- onLoad() {
- this._radius = this.ring.width / 2;
- this._initTouchEvent();
- // hide joystick when follow
- if (this.joystickType === JoystickType.FOLLOW) {
- this.node.opacity = 0;
- }
- cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyPressed, this);
- cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyReleased, this);
- }
- /**
- * 改变摇杆类型
- * @param type
- */
- _onSetJoystickType(type: JoystickType) {
- this.joystickType = type;
- this.node.opacity = type === JoystickType.FIXED ? 255 : 0;
- }
- /**
- * 初始化触摸事件
- */
- _initTouchEvent() {
- // set the size of joystick node to control scale
- this.node.on(cc.Node.EventType.TOUCH_START, this._touchStartEvent, this);
- this.node.on(cc.Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);
- this.node.on(cc.Node.EventType.TOUCH_END, this._touchEndEvent, this);
- this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
- }
- /**
- * 触摸开始回调函数
- * @param event
- */
- _touchStartEvent(event: cc.Event.EventTouch) {
- const touchPos = this.node.convertToNodeSpaceAR(event.getLocation());
- if (this.joystickType === JoystickType.FIXED) {
- this._stickPos = this.ring.getPosition();
- // 触摸点与圆圈中心的距离
- const distance = touchPos.sub(this.ring.getPosition()).mag();
- // 手指在圆圈内触摸,控杆跟随触摸点
- this._radius > distance && this.dot.setPosition(touchPos);
- } else if (this.joystickType === JoystickType.FOLLOW) {
- // 记录摇杆位置,给 touch move 使用
- this._stickPos = touchPos;
- this.node.opacity = 255;
- this._touchLocation = event.getLocation();
- // 更改摇杆的位置
- this.ring.setPosition(touchPos);
- this.dot.setPosition(touchPos);
- }
- }
- /**
- * 触摸移动回调函数
- * @param event
- */
- _touchMoveEvent(event: cc.Event.EventTouch) {
- // 如果 touch start 位置和 touch move 相同,禁止移动
- if (
- this.joystickType === JoystickType.FOLLOW &&
- this._touchLocation === event.getLocation()
- ) {
- return false;
- }
- // 以圆圈为锚点获取触摸坐标
- const touchPos = this.ring.convertToNodeSpaceAR(event.getLocation());
- const distance = touchPos.mag();
- // 由于摇杆的 postion 是以父节点为锚点,所以定位要加上 touch start 时的位置
- const posX = this._stickPos.x + touchPos.x;
- const posY = this._stickPos.y + touchPos.y;
- // 归一化
- const p = cc.v2(posX, posY).sub(this.ring.getPosition()).normalize();
- let speedType;
- if (this._radius > distance) {
- this.dot.setPosition(cc.v2(posX, posY));
- speedType = SpeedType.NORMAL;
- } else {
- // 控杆永远保持在圈内,并在圈内跟随触摸更新角度
- const x = this._stickPos.x + p.x * this._radius;
- const y = this._stickPos.y + p.y * this._radius;
- this.dot.setPosition(cc.v2(x, y));
- speedType = SpeedType.FAST;
- }
- if(this.callback != undefined){
- if(p.x == 0 && p.y == 0){
- this.callback(SpeedType.STOP)
- }else{
- this.callback(speedType,p)
- }
-
- }
- }
- /**
- * 触摸结束回调函数
- * @param event
- */
- _touchEndEvent(event: cc.Event.EventTouch) {
- this.dot.setPosition(this.ring.getPosition());
- if (this.joystickType === JoystickType.FOLLOW) {
- this.node.opacity = 0;
- }
- if(this.callback != undefined){
- this.callback(SpeedType.STOP)
- }
- }
- public stop(){
- this._touchEndEvent(null)
- }
-
- public setListen(callback:(speedType:SpeedType,moveVec?:cc.Vec2)=>void){
- this.callback = callback;
- }
- private keyDir = cc.v2(0,0)
- private onKeyPressed(event) {
- let keyCode = event.keyCode;
- switch(keyCode) {
- case cc.macro.KEY.w:
- case cc.macro.KEY.up:
- this.keyDir.y = 1;
- break;
- case cc.macro.KEY.s:
- case cc.macro.KEY.down:
- this.keyDir.y = -1;
- break;
- case cc.macro.KEY.a:
- case cc.macro.KEY.left:
- this.keyDir.x = -1;
- break;
- case cc.macro.KEY.d:
- case cc.macro.KEY.right:
- this.keyDir.x = 1;
- break;
- }
- if(this.callback){
- let dmg = this.keyDir.normalize()
- if(dmg.x == 0 && dmg.y == 0){
- this.callback(SpeedType.STOP)
- }else{
- this.callback(SpeedType.FAST,dmg)
- }
-
- }
- }
- private onKeyReleased(event) {
- let keyCode = event.keyCode;
- switch(keyCode) {
- case cc.macro.KEY.w:
- case cc.macro.KEY.up:
- this.keyDir.y = 0;
- break;
- case cc.macro.KEY.s:
- case cc.macro.KEY.down:
- this.keyDir.y = 0;
- break;
- case cc.macro.KEY.a:
- case cc.macro.KEY.left:
- this.keyDir.x = 0;
- break;
- case cc.macro.KEY.d:
- case cc.macro.KEY.right:
- this.keyDir.x = 0;
- break;
- }
-
- if(this.callback){
- let dmg = this.keyDir.normalize()
- if(dmg.x == 0 && dmg.y == 0){
- this.callback(SpeedType.STOP)
- }else{
- this.callback(SpeedType.FAST,dmg)
- }
-
- }
- }
- }
|