Created
August 23, 2018 12:06
-
-
Save fleon/f9abc82f1f873cb3b30f8d9628cfeb98 to your computer and use it in GitHub Desktop.
cocos2dx-TouchHelper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function noop() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class Deferred<T = void> { | |
resolve: (value?: T) => void | |
reject: (value?: any) => void | |
promise: Promise<T> | |
constructor() { | |
this.promise = new Promise<T>((resolve, reject) => { | |
this.resolve = resolve | |
this.reject = reject | |
}) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { noop } from 'utils/Common' | |
import Deferred from 'utils/Deferred' | |
export default class Timeout<Data = null> extends Deferred { | |
constructor(private fn: (data?: Data) => any = noop, time: number, private data?: Data) { | |
super() | |
// delay cannot be zero. Minimum delay has to be 1ms. | |
if (!time) time = 1 | |
cc.director.getScheduler() | |
.scheduleCallbackForTarget(this, this.callback, 1e10, 0, time / 1000, false) | |
} | |
callback = () => { | |
this.fn(this.data) | |
this.resolve() | |
this.cancel() | |
} | |
cancel() { | |
cc.director.getScheduler() | |
.unscheduleCallbackForTarget(this, this.callback) | |
} | |
} | |
export function timeout<Data = null>(fn: (data?: Data) => any = noop, time = 1, data?: Data): Timeout<Data> { | |
return new Timeout(fn, time, data) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Timeout, { timeout } from 'utils/Timeout' | |
interface ITouchableNode extends cc.Node { | |
touchBegan?(touch: cc.Touch) | |
touchMoved?(touch: cc.Touch) | |
touchEnded?(touch: cc.Touch) | |
touchCancelled?(touch: cc.Touch) | |
shortPress?(touch: ITouchInfo) | |
mediumPress?(touch: ITouchInfo) | |
longPress?(touch: ITouchInfo) | |
} | |
function getTouchInfo(touch: cc.Touch): ITouchInfo { | |
return { | |
location: touch.getLocation(), | |
startLocation: touch.getStartLocation ? touch.getStartLocation() : cc.p(0, 0), | |
delta: touch.getDelta() | |
} | |
} | |
const touchListeners = new Map<ITouchableNode, cc.EventListener>() | |
const touchListenerObjs = new Map<ITouchableNode, object>() | |
const shortPressTimeouts = [] | |
const mediumPressTimeouts = [] | |
const longPressTimeouts = [] | |
function cancelAllTimeouts() { | |
shortPressTimeouts.forEach(t => t.cancel()) | |
shortPressTimeouts.length = 0 | |
mediumPressTimeouts.forEach(t => t.cancel()) | |
mediumPressTimeouts.length = 0 | |
longPressTimeouts.forEach(t => t.cancel()) | |
longPressTimeouts.length = 0 | |
} | |
export function enableTouch(node: ITouchableNode, swallowTouches = true) { | |
let shortPressTimeout: Timeout | |
let shortPressCalled = false | |
let mediumPressTimeout: Timeout | |
let longPressTimeout: Timeout | |
const listenerObj = { | |
event: cc.EventListener.TOUCH_ONE_BY_ONE, | |
swallowTouches, | |
onTouchBegan: (touch: cc.Touch) => { | |
const touchInfo = getTouchInfo(touch) | |
shortPressCalled = false | |
if (shortPressTimeout) shortPressTimeout.cancel() | |
shortPressTimeout = timeout(() => { | |
if (node.shortPress && !shortPressCalled) | |
node.shortPress(touchInfo) | |
shortPressCalled = true | |
}) | |
if (mediumPressTimeout) mediumPressTimeout.cancel() | |
mediumPressTimeout = timeout(() => { | |
if (node.mediumPress) | |
node.mediumPress(touchInfo) | |
}, 10) | |
mediumPressTimeouts.push(mediumPressTimeout) | |
if (longPressTimeout) longPressTimeout.cancel() | |
longPressTimeout = timeout(() => { | |
if (node.longPress) | |
node.longPress(touchInfo) | |
}, 800) | |
longPressTimeouts.push(longPressTimeout) | |
if (node.touchBegan) | |
return node.touchBegan(touch) | |
}, | |
onTouchMoved: (touch: cc.Touch) => { | |
if (!touch || !touch.getLocation) return | |
const startLocation = touch.getStartLocation ? touch.getStartLocation() : cc.p(0, 0) | |
const location = touch.getLocation() | |
if (!cc.pointEqualToPoint(startLocation, location)) { | |
cancelAllTimeouts() | |
} | |
if (node.touchMoved) | |
return node.touchMoved(touch) | |
}, | |
onTouchEnded: (touch: cc.Touch) => { | |
cancelAllTimeouts() | |
if (!touch || !touch.getLocation) return | |
const startLocation = touch.getStartLocation ? touch.getStartLocation() : cc.p(0, 0) | |
const location = touch.getLocation() | |
if (cc.pointEqualToPoint(startLocation, location) && node.shortPress && !shortPressCalled) | |
node.shortPress(getTouchInfo(touch)) | |
if (node.touchEnded) | |
return node.touchEnded(touch) | |
}, | |
onTouchCancelled: (touch: cc.Touch) => { | |
cancelAllTimeouts() | |
if (!touch || !touch.getLocation) return | |
if (node.touchCancelled) | |
return node.touchCancelled(touch) | |
}, | |
} | |
const listener = cc.EventListener.create(listenerObj) | |
listener.retain() | |
node.retain() | |
cc.eventManager.addListener(listener, node) | |
// need separate maps for listener and the obj so that the listener obj doesn't get | |
// garbage collected unneccessarily | |
touchListeners.set(node, listener) | |
touchListenerObjs.set(node, listenerObj) | |
} | |
export function disableTouch(node: ITouchableNode) { | |
if (!touchListeners.has(node)) return | |
const listener = touchListeners.get(node) | |
cc.eventManager.removeListener(listener) | |
cancelAllTimeouts() | |
touchListeners.delete(node) | |
touchListenerObjs.delete(node) | |
listener.release() | |
node.release() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment