123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- import { _decorator, Node, EventTouch, Touch, Component, UITransform, Input, EventKeyboard, KeyCode, v2, Vec3, input, Scene, director, EventMouse, macro, view, screen, isValid } from 'cc';
- import { EasyControllerEvent } from './EasyController';
- const { ccclass, property } = _decorator;
- /****
- * split screen into three parts.
- * ---------------------------------------------
- * |
- * 1.camera rotation zone |
- * |
- *----------------------------------------------|
- * | |
- * 2.movement ctrl zone | 3.camera rotation zone|
- * | |
- * ----------------------------------------------
- *
- * multi-touch for camera zoom.
- * */
- @ccclass('tgxUIJoystick')
- export class UIJoystick extends Component {
- private static _inst: UIJoystick = null;
- public static get inst(): UIJoystick {
- return this._inst;
- }
- private _ctrlRoot: UITransform = null;
- private _ctrlPointer: Node = null;
- private _buttons: Node = null;
- private _cameraSensitivity: number = 0.1;
- private _distanceOfTwoTouchPoint: number = 0;
- private _movementTouch: Touch = null;
- private _cameraTouchA: Touch = null;
- private _cameraTouchB: Touch = null;
- private _fullscreen:UITransform = null;
- private _key2buttonMap = {};
- protected onLoad(): void {
- UIJoystick._inst = this;
- this._key2buttonMap[KeyCode.KEY_J] = 'btn_slot_0';
- this._key2buttonMap[KeyCode.KEY_K] = 'btn_slot_1';
- this._key2buttonMap[KeyCode.KEY_L] = 'btn_slot_2';
- this._key2buttonMap[KeyCode.KEY_U] = 'btn_slot_3';
- this._key2buttonMap[KeyCode.KEY_I] = 'btn_slot_4';
- let checkerCamera = this.node.getChildByName('checker_camera').getComponent(UITransform);
- checkerCamera.node.on(Input.EventType.TOUCH_START, this.onTouchStart_CameraCtrl, this);
- checkerCamera.node.on(Input.EventType.TOUCH_MOVE, this.onTouchMove_CameraCtrl, this);
- checkerCamera.node.on(Input.EventType.TOUCH_END, this.onTouchUp_CameraCtrl, this);
- checkerCamera.node.on(Input.EventType.TOUCH_CANCEL, this.onTouchUp_CameraCtrl, this);
- let checkerMovement = this.node.getChildByName('checker_movement').getComponent(UITransform);
- checkerMovement.node.on(Input.EventType.TOUCH_START, this.onTouchStart_Movement, this);
- checkerMovement.node.on(Input.EventType.TOUCH_MOVE, this.onTouchMove_Movement, this);
- checkerMovement.node.on(Input.EventType.TOUCH_END, this.onTouchUp_Movement, this);
- checkerMovement.node.on(Input.EventType.TOUCH_CANCEL, this.onTouchUp_Movement, this);
- this._fullscreen = this.node.getComponent(UITransform);
- this._ctrlRoot = this.node.getChildByName('ctrl').getComponent(UITransform);
- this._ctrlRoot.node.active = false;
- this._ctrlPointer = this._ctrlRoot.node.getChildByName('pointer');
- this._buttons = this.node.getChildByName('buttons');
- input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
- input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
- input.on(Input.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
- }
- onDestroy() {
- input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
- input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
- input.off(Input.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
- UIJoystick._inst = null;
- }
- cleanKeyMap() {
- this._key2buttonMap = {};
- }
- bindKeyToButton(keyCode: KeyCode, btnName: string) {
- this._key2buttonMap[keyCode] = btnName;
- }
- setButtonVisible(btnName: string, visible: boolean) {
- let node = this._buttons?.getChildByName(btnName);
- if (node) {
- node.active = visible;
- }
- }
- getButtonByName(btnName: string): Node {
- return this._buttons.getChildByName(btnName);
- }
- onTouchStart_Movement(event: EventTouch) {
- let touches = event.getTouches();
- for (let i = 0; i < touches.length; ++i) {
- let touch = touches[i];
- let x = touch.getUILocationX();
- let y = touch.getUILocationY();
- if (!this._movementTouch) {
- //we sub halfWidth,halfHeight here.
- //because, the touch event use left bottom as zero point(0,0), ui node use the center of screen as zero point(0,0)
- //this._ctrlRoot.setPosition(x - halfWidth, y - halfHeight, 0);
- let halfWidth = this._fullscreen.width / 2;
- let halfHeight = this._fullscreen.height / 2;
- this._ctrlRoot.node.active = true;
- this._ctrlRoot.node.setPosition(x - halfWidth, y - halfHeight, 0);
- this._ctrlPointer.setPosition(0, 0, 0);
- this._movementTouch = touch;
- }
- }
- }
- onTouchMove_Movement(event: EventTouch) {
- let touches = event.getTouches();
- for (let i = 0; i < touches.length; ++i) {
- let touch = touches[i];
- if (this._movementTouch && touch.getID() == this._movementTouch.getID()) {
- let halfWidth = this._fullscreen.width / 2;
- let halfHeight = this._fullscreen.height / 2;
- let x = touch.getUILocationX();
- let y = touch.getUILocationY();
- let pos = this._ctrlRoot.node.position;
- let ox = x - halfWidth - pos.x;
- let oy = y - halfHeight - pos.y;
- let len = Math.sqrt(ox * ox + oy * oy);
- if (len <= 0) {
- return;
- }
- let dirX = ox / len;
- let dirY = oy / len;
- let radius = this._ctrlRoot.width / 2;
- if (len > radius) {
- len = radius;
- ox = dirX * radius;
- oy = dirY * radius;
- }
- this._ctrlPointer.setPosition(ox, oy, 0);
- // degree 0 ~ 360 based on x axis.
- let degree = Math.atan(dirY / dirX) / Math.PI * 180;
- if (dirX < 0) {
- degree += 180;
- }
- else {
- degree += 360;
- }
- this.emitEvent(EasyControllerEvent.MOVEMENT, degree, len / radius);
- }
- }
- }
- onTouchUp_Movement(event: EventTouch) {
- let touches = event.getTouches();
- for (let i = 0; i < touches.length; ++i) {
- let touch = touches[i];
- if (this._movementTouch && touch.getID() == this._movementTouch.getID()) {
- this.emitEvent(EasyControllerEvent.MOVEMENT_STOP);
- this._movementTouch = null;
- this._ctrlRoot.node.active = false;
- }
- }
- }
- private getDistOfTwoTouchPoints(): number {
- let touchA = this._cameraTouchA;
- let touchB = this._cameraTouchB;
- if (!touchA || !touchB) {
- return 0;
- }
- let dx = touchA.getLocationX() - touchB.getLocationX();
- let dy = touchB.getLocationY() - touchB.getLocationY();
- return Math.sqrt(dx * dx + dy * dy);
- }
- private onTouchStart_CameraCtrl(event: EventTouch) {
- this.emitEvent(EasyControllerEvent.SCREEN_TOUCH_START, event);
- let touches = event.getAllTouches();
- this._cameraTouchA = null;
- this._cameraTouchB = null;
- for (let i = touches.length - 1; i >= 0; i--) {
- let touch = touches[i];
- if (this._movementTouch && touch.getID() == this._movementTouch.getID()) {
- continue;
- }
- if (this._cameraTouchA == null) {
- this._cameraTouchA = touches[i];
- }
- else if (this._cameraTouchB == null) {
- this._cameraTouchB = touches[i];
- break;
- }
- }
- this._distanceOfTwoTouchPoint = this.getDistOfTwoTouchPoints();
- }
- private onTouchMove_CameraCtrl(event: EventTouch) {
- let touches = event.getTouches();
- for (let i = 0; i < touches.length; ++i) {
- let touch = touches[i];
- let touchID = touch.getID();
- //two touches, do camera zoom.
- if (this._cameraTouchA && this._cameraTouchB) {
- console.log(touchID, this._cameraTouchA.getID(), this._cameraTouchB.getID());
- let needZoom = false;
- if (touchID == this._cameraTouchA.getID()) {
- this._cameraTouchA = touch;
- needZoom = true;
- }
- if (touchID == this._cameraTouchB.getID()) {
- this._cameraTouchB = touch;
- needZoom = true;
- }
- if (needZoom) {
- let newDist = this.getDistOfTwoTouchPoints();
- let delta = this._distanceOfTwoTouchPoint - newDist;
- this.emitEvent(EasyControllerEvent.CAMERA_ZOOM, delta);
- this._distanceOfTwoTouchPoint = newDist;
- }
- }
- //only one touch, do camera rotate.
- else if (this._cameraTouchA && touchID == this._cameraTouchA.getID()) {
- let dt = touch.getDelta();
- let rx = dt.y * this._cameraSensitivity;
- let ry = -dt.x * this._cameraSensitivity;
- this.emitEvent(EasyControllerEvent.CAMERA_ROTATE, rx, ry);
- }
- }
- }
- private onTouchUp_CameraCtrl(event: EventTouch) {
- this.emitEvent(EasyControllerEvent.SCREEN_TOUCH_END, event);
- let touches = event.getAllTouches();
- let hasTouchA = false;
- let hasTouchB = false;
- for (let i = 0; i < touches.length; ++i) {
- let touch = touches[i];
- let touchID = touch.getID();
- if (this._cameraTouchA && touchID == this._cameraTouchA.getID()) {
- hasTouchA = true;
- }
- else if (this._cameraTouchB && touchID == this._cameraTouchB.getID()) {
- hasTouchB = true;
- }
- }
- if (!hasTouchA) {
- this._cameraTouchA = null;
- }
- if (!hasTouchB) {
- this._cameraTouchB = null;
- }
- }
- private _keys = [];
- private _degree: number = 0;
- onKeyDown(event: EventKeyboard) {
- let keyCode = event.keyCode;
- if (keyCode == KeyCode.KEY_A || keyCode == KeyCode.KEY_S || keyCode == KeyCode.KEY_D || keyCode == KeyCode.KEY_W) {
- if (this._keys.indexOf(keyCode) == -1) {
- this._keys.push(keyCode);
- this.updateDirection();
- }
- }
- else {
- let btnName = this._key2buttonMap[keyCode];
- if (btnName) {
- this.emitEvent(EasyControllerEvent.BUTTON, btnName);
- }
- }
- }
- onKeyUp(event: EventKeyboard) {
- let keyCode = event.keyCode;
- if (keyCode == KeyCode.KEY_A || keyCode == KeyCode.KEY_S || keyCode == KeyCode.KEY_D || keyCode == KeyCode.KEY_W) {
- let index = this._keys.indexOf(keyCode);
- if (index != -1) {
- this._keys.splice(index, 1);
- this.updateDirection();
- }
- }
- }
- onMouseWheel(event: EventMouse) {
- let delta = event.getScrollY() * 0.1;
- //console.log(delta);
- this.emitEvent(EasyControllerEvent.CAMERA_ZOOM, delta);
- }
- onButtonSlot(event) {
- let btnName = event.target.name;
- this.emitEvent(EasyControllerEvent.BUTTON, btnName);
- }
- private _key2dirMap = null;
- updateDirection() {
- if (this._key2dirMap == null) {
- this._key2dirMap = {};
- this._key2dirMap[0] = -1;
- this._key2dirMap[KeyCode.KEY_A] = 180;
- this._key2dirMap[KeyCode.KEY_D] = 0;
- this._key2dirMap[KeyCode.KEY_W] = 90;
- this._key2dirMap[KeyCode.KEY_S] = 270;
- this._key2dirMap[KeyCode.KEY_A * 1000 + KeyCode.KEY_W] = this._key2dirMap[KeyCode.KEY_W * 1000 + KeyCode.KEY_A] = 135;
- this._key2dirMap[KeyCode.KEY_D * 1000 + KeyCode.KEY_W] = this._key2dirMap[KeyCode.KEY_W * 1000 + KeyCode.KEY_D] = 45;
- this._key2dirMap[KeyCode.KEY_A * 1000 + KeyCode.KEY_S] = this._key2dirMap[KeyCode.KEY_S * 1000 + KeyCode.KEY_A] = 225;
- this._key2dirMap[KeyCode.KEY_D * 1000 + KeyCode.KEY_S] = this._key2dirMap[KeyCode.KEY_S * 1000 + KeyCode.KEY_D] = 315;
- this._key2dirMap[KeyCode.KEY_A * 1000 + KeyCode.KEY_D] = this._key2dirMap[KeyCode.KEY_D];
- this._key2dirMap[KeyCode.KEY_D * 1000 + KeyCode.KEY_A] = this._key2dirMap[KeyCode.KEY_A];
- this._key2dirMap[KeyCode.KEY_W * 1000 + KeyCode.KEY_S] = this._key2dirMap[KeyCode.KEY_S];
- this._key2dirMap[KeyCode.KEY_S * 1000 + KeyCode.KEY_W] = this._key2dirMap[KeyCode.KEY_W];
- }
- let keyCode0 = this._keys[this._keys.length - 1] || 0;
- let keyCode1 = this._keys[this._keys.length - 2] || 0;
- this._degree = this._key2dirMap[keyCode1 * 1000 + keyCode0];
- if (this._degree == null || this._degree < 0) {
- this.emitEvent(EasyControllerEvent.MOVEMENT_STOP);
- }
- else {
- this.emitEvent(EasyControllerEvent.MOVEMENT, this._degree, 1.0);
- }
- }
- private emitEvent(type: string, arg0?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any) {
- director.emit(type, arg0, arg1, arg2, arg3, arg4);
- }
- }
|