diff --git a/cocos/input/input.ts b/cocos/input/input.ts index 3cc5c2d3899..adf42999aea 100644 --- a/cocos/input/input.ts +++ b/cocos/input/input.ts @@ -25,10 +25,10 @@ */ import { EDITOR_NOT_IN_PREVIEW, NATIVE } from 'internal:constants'; -import { TouchInputSource, MouseInputSource, KeyboardInputSource, AccelerometerInputSource, GamepadInputDevice, HandleInputDevice, HMDInputDevice, HandheldInputDevice } from 'pal/input'; +import { AccelerometerInputSource, GamepadInputDevice, HMDInputDevice, HandheldInputDevice, HandleInputDevice, KeyboardInputSource, MouseInputSource, TouchInputSource } from 'pal/input'; import { touchManager } from '../../pal/input/touch-manager'; -import { sys, EventTarget, error } from '../core'; -import { Event, EventAcceleration, EventGamepad, EventHandle, EventHandheld, EventHMD, EventKeyboard, EventMouse, EventTouch, Touch } from './types'; +import { EventTarget, error, sys } from '../core'; +import { Event, EventAcceleration, EventGamepad, EventHMD, EventHandheld, EventHandle, EventKeyboard, EventMouse, EventTouch, Touch } from './types'; import { InputEventType } from './types/event-enum'; export enum EventDispatcherPriority { @@ -62,7 +62,7 @@ class InputEventDispatcher implements IEventDispatcher { } } -const pointerEventTypeMap: Record = { +const pointerEventTypeMap: Record = { [InputEventType.MOUSE_DOWN]: InputEventType.TOUCH_START, [InputEventType.MOUSE_MOVE]: InputEventType.TOUCH_MOVE, [InputEventType.MOUSE_UP]: InputEventType.TOUCH_END, @@ -160,28 +160,40 @@ export class Input { /** * This should be a private method, but it's exposed for Editor Only. */ - private _dispatchMouseDownEvent (nativeMouseEvent: any): void { this._mouseInput.dispatchMouseDownEvent?.(nativeMouseEvent); } + private _dispatchMouseDownEvent (nativeMouseEvent: any): void { + this._mouseInput.dispatchMouseDownEvent?.(nativeMouseEvent); + } /** * This should be a private method, but it's exposed for Editor Only. */ - private _dispatchMouseMoveEvent (nativeMouseEvent: any): void { this._mouseInput.dispatchMouseMoveEvent?.(nativeMouseEvent); } + private _dispatchMouseMoveEvent (nativeMouseEvent: any): void { + this._mouseInput.dispatchMouseMoveEvent?.(nativeMouseEvent); + } /** * This should be a private method, but it's exposed for Editor Only. */ - private _dispatchMouseUpEvent (nativeMouseEvent: any): void { this._mouseInput.dispatchMouseUpEvent?.(nativeMouseEvent); } + private _dispatchMouseUpEvent (nativeMouseEvent: any): void { + this._mouseInput.dispatchMouseUpEvent?.(nativeMouseEvent); + } /** * This should be a private method, but it's exposed for Editor Only. */ - private _dispatchMouseScrollEvent (nativeMouseEvent: any): void { this._mouseInput.dispatchScrollEvent?.(nativeMouseEvent); } + private _dispatchMouseScrollEvent (nativeMouseEvent: any): void { + this._mouseInput.dispatchScrollEvent?.(nativeMouseEvent); + } /** * This should be a private method, but it's exposed for Editor Only. */ - private _dispatchKeyboardDownEvent (nativeKeyboardEvent: any): void { this._keyboardInput.dispatchKeyboardDownEvent?.(nativeKeyboardEvent); } + private _dispatchKeyboardDownEvent (nativeKeyboardEvent: any): void { + this._keyboardInput.dispatchKeyboardDownEvent?.(nativeKeyboardEvent); + } /** * This should be a private method, but it's exposed for Editor Only. */ - private _dispatchKeyboardUpEvent (nativeKeyboardEvent: any): void { this._keyboardInput.dispatchKeyboardUpEvent?.(nativeKeyboardEvent); } + private _dispatchKeyboardUpEvent (nativeKeyboardEvent: any): void { + this._keyboardInput.dispatchKeyboardUpEvent?.(nativeKeyboardEvent); + } /** * @en @@ -229,6 +241,42 @@ export class Input { } this._eventTarget.off(eventType, callback, target); } + + /** + * @en + * Get touch object by touch ID. + * @zh + * 通过 touch ID 获取 touch对象。 + * @param touchID + * @param clone - Whether to clone touch object + * @returns + */ + public getTouch (touchID: number, clone?: boolean): Touch | undefined { + const touch = touchManager._touchMap.get(touchID); + return touch ? (clone === false ? touch : touchManager._cloneTouch(touch)) : undefined; + } + + /** + * @en + * Get all the current touches objects as array. + * @zh + * 获取当前 所有touch对象 的数组。 + * @param clone - Whether to clone touch object + */ + public getAllTouches (clone?: boolean): Touch[] { + return touchManager.getAllTouches(clone); + } + + /** + * @en + * Get the number of touches. + * @zh + * 获取当前 touch 对象的数量。 + */ + public getTouchCount (): number { + return touchManager._touchMap.size; + } + /** * @en * Sets whether to enable the accelerometer event listener or not. @@ -304,10 +352,18 @@ export class Input { private _registerEvent (): void { if (sys.hasFeature(sys.Feature.INPUT_TOUCH)) { const eventTouchList = this._eventTouchList; - this._touchInput.on(InputEventType.TOUCH_START, (event): void => { this._dispatchOrPushEventTouch(event, eventTouchList); }); - this._touchInput.on(InputEventType.TOUCH_MOVE, (event): void => { this._dispatchOrPushEventTouch(event, eventTouchList); }); - this._touchInput.on(InputEventType.TOUCH_END, (event): void => { this._dispatchOrPushEventTouch(event, eventTouchList); }); - this._touchInput.on(InputEventType.TOUCH_CANCEL, (event): void => { this._dispatchOrPushEventTouch(event, eventTouchList); }); + this._touchInput.on(InputEventType.TOUCH_START, (event): void => { + this._dispatchOrPushEventTouch(event, eventTouchList); + }); + this._touchInput.on(InputEventType.TOUCH_MOVE, (event): void => { + this._dispatchOrPushEventTouch(event, eventTouchList); + }); + this._touchInput.on(InputEventType.TOUCH_END, (event): void => { + this._dispatchOrPushEventTouch(event, eventTouchList); + }); + this._touchInput.on(InputEventType.TOUCH_CANCEL, (event): void => { + this._dispatchOrPushEventTouch(event, eventTouchList); + }); } if (sys.hasFeature(sys.Feature.EVENT_MOUSE)) { @@ -328,42 +384,66 @@ export class Input { this._simulateEventTouch(event); this._dispatchOrPushEvent(event, eventMouseList); }); - this._mouseInput.on(InputEventType.MOUSE_WHEEL, (event): void => { this._dispatchOrPushEvent(event, eventMouseList); }); + this._mouseInput.on(InputEventType.MOUSE_WHEEL, (event): void => { + this._dispatchOrPushEvent(event, eventMouseList); + }); } if (sys.hasFeature(sys.Feature.EVENT_KEYBOARD)) { const eventKeyboardList = this._eventKeyboardList; - this._keyboardInput.on(InputEventType.KEY_DOWN, (event): void => { this._dispatchOrPushEvent(event, eventKeyboardList); }); - this._keyboardInput.on(InputEventType.KEY_PRESSING, (event): void => { this._dispatchOrPushEvent(event, eventKeyboardList); }); - this._keyboardInput.on(InputEventType.KEY_UP, (event): void => { this._dispatchOrPushEvent(event, eventKeyboardList); }); + this._keyboardInput.on(InputEventType.KEY_DOWN, (event): void => { + this._dispatchOrPushEvent(event, eventKeyboardList); + }); + this._keyboardInput.on(InputEventType.KEY_PRESSING, (event): void => { + this._dispatchOrPushEvent(event, eventKeyboardList); + }); + this._keyboardInput.on(InputEventType.KEY_UP, (event): void => { + this._dispatchOrPushEvent(event, eventKeyboardList); + }); } if (sys.hasFeature(sys.Feature.EVENT_ACCELEROMETER)) { const eventAccelerationList = this._eventAccelerationList; - this._accelerometerInput.on(InputEventType.DEVICEMOTION, (event): void => { this._dispatchOrPushEvent(event, eventAccelerationList); }); + this._accelerometerInput.on(InputEventType.DEVICEMOTION, (event): void => { + this._dispatchOrPushEvent(event, eventAccelerationList); + }); } if (sys.hasFeature(sys.Feature.EVENT_GAMEPAD)) { const eventGamepadList = this._eventGamepadList; - GamepadInputDevice._on(InputEventType.GAMEPAD_CHANGE, (event): void => { this._dispatchOrPushEvent(event, eventGamepadList); }); - GamepadInputDevice._on(InputEventType.GAMEPAD_INPUT, (event): void => { this._dispatchOrPushEvent(event, eventGamepadList); }); - GamepadInputDevice._on(InputEventType.HANDLE_POSE_INPUT, (event): void => { this._dispatchOrPushEvent(event, eventGamepadList); }); + GamepadInputDevice._on(InputEventType.GAMEPAD_CHANGE, (event): void => { + this._dispatchOrPushEvent(event, eventGamepadList); + }); + GamepadInputDevice._on(InputEventType.GAMEPAD_INPUT, (event): void => { + this._dispatchOrPushEvent(event, eventGamepadList); + }); + GamepadInputDevice._on(InputEventType.HANDLE_POSE_INPUT, (event): void => { + this._dispatchOrPushEvent(event, eventGamepadList); + }); } if (sys.hasFeature(sys.Feature.EVENT_HANDLE)) { const eventHandleList = this._eventHandleList; - this._handleInput._on(InputEventType.HANDLE_INPUT, (event): void => { this._dispatchOrPushEvent(event, eventHandleList); }); - this._handleInput._on(InputEventType.HANDLE_POSE_INPUT, (event): void => { this._dispatchOrPushEvent(event, eventHandleList); }); + this._handleInput._on(InputEventType.HANDLE_INPUT, (event): void => { + this._dispatchOrPushEvent(event, eventHandleList); + }); + this._handleInput._on(InputEventType.HANDLE_POSE_INPUT, (event): void => { + this._dispatchOrPushEvent(event, eventHandleList); + }); } if (sys.hasFeature(sys.Feature.EVENT_HMD)) { const eventHMDList = this._eventHMDList; - this._hmdInput._on(InputEventType.HMD_POSE_INPUT, (event): void => { this._dispatchOrPushEvent(event, eventHMDList); }); + this._hmdInput._on(InputEventType.HMD_POSE_INPUT, (event): void => { + this._dispatchOrPushEvent(event, eventHMDList); + }); } if (sys.hasFeature(sys.Feature.EVENT_HANDHELD)) { const eventHandheldList = this._eventHandheldList; - this._handheldInput._on(InputEventType.HANDHELD_POSE_INPUT, (event): void => { this._dispatchOrPushEvent(event, eventHandheldList); }); + this._handheldInput._on(InputEventType.HANDHELD_POSE_INPUT, (event): void => { + this._dispatchOrPushEvent(event, eventHandheldList); + }); } } diff --git a/pal/input/touch-manager.ts b/pal/input/touch-manager.ts index 6c4ec9a4bc2..d237b274c81 100644 --- a/pal/input/touch-manager.ts +++ b/pal/input/touch-manager.ts @@ -22,9 +22,10 @@ THE SOFTWARE. */ +import { Vec2 } from '../../cocos/core/math/vec2'; +import { log } from '../../cocos/core/platform/debug'; import { macro } from '../../cocos/core/platform/macro'; import { Touch } from '../../cocos/input/types'; -import { Vec2 } from '../../cocos/core/math/vec2'; const tempVec2 = new Vec2(); @@ -32,7 +33,7 @@ class TouchManager { /** * A map from touch ID to touch object. */ - private _touchMap: Map; + public _touchMap: Map; private readonly _maxTouches = 8; constructor () { @@ -44,7 +45,7 @@ class TouchManager { * @param touch * @returns */ - private _cloneTouch (touch: Touch): Touch { + public _cloneTouch (touch: Touch): Touch { const touchID = touch.getID(); touch.getStartLocation(tempVec2); const clonedTouch = new Touch(tempVec2.x, tempVec2.y, touchID); @@ -68,18 +69,18 @@ class TouchManager { */ private _createTouch (touchID: number, x: number, y: number): Touch | undefined { if (this._touchMap.has(touchID)) { - console.log('Cannot create the same touch object.'); + log('Cannot create the same touch object.'); return undefined; } const checkResult = this._checkTouchMapSizeMoreThanMax(touchID); if (checkResult) { - console.log('The touches is more than MAX_TOUCHES.'); // TODO: logID 2300 + log('The touches is more than MAX_TOUCHES.'); // TODO: logID 2300 return undefined; } const touch = new Touch(x, y, touchID); this._touchMap.set(touchID, touch); this._updateTouch(touch, x, y); - return this._cloneTouch(touch); + return touch; } /** @@ -99,26 +100,25 @@ class TouchManager { * @param touchID * @returns */ - public getTouch (touchID: number, x: number, y: number): Touch | undefined { + public getTouch (touchID: number, x: number, y: number, clone?: boolean): Touch | undefined { let touch = this._touchMap.get(touchID); if (!touch) { touch = this._createTouch(touchID, x, y); } else { this._updateTouch(touch, x, y); } - return touch ? this._cloneTouch(touch) : undefined; + return touch ? (clone === false ? touch : this._cloneTouch(touch)) : undefined; } /** * Get all the current touches objects. * @returns */ - public getAllTouches (): Touch[] { + public getAllTouches (clone?: boolean): Touch[] { const touches: Touch[] = []; this._touchMap.forEach((touch) => { if (touch) { - const clonedTouch = this._cloneTouch(touch); - touches.push(clonedTouch); + touches.push(clone === false ? touch : this._cloneTouch(touch)); } }); return touches; @@ -148,7 +148,7 @@ class TouchManager { const now = performance.now(); this._touchMap.forEach((touch) => { if (now - touch.lastModified > macro.TOUCH_TIMEOUT) { - console.log(`The touches is more than MAX_TOUCHES, release touch id ${touch.getID()}.`); + log(`The touches is more than MAX_TOUCHES, release touch id ${touch.getID()}.`); // TODO: need to handle touch cancel event when exceed the max number of touches ? this.releaseTouch(touch.getID()); }