phaser4-rex-plugins
Version:
204 lines (179 loc) • 6.1 kB
JavaScript
import OnePointerTracer from "../onepointertracer/OnePointerTracer.js";
import FSM from '../../../fsm.js';
const GetValue = Phaser.Utils.Objects.GetValue;
const DistanceBetween = Phaser.Math.Distance.Between;
class Tap extends OnePointerTracer {
constructor(gameObject, config) {
super(gameObject, config);
var self = this;
var stateConfig = {
states: {
IDLE: {
enter: function () {
self.stop();
self.tapsCount = 0;
self.x = 0;
self.y = 0;
self.worldX = 0;
self.worldY = 0;
self.lastPointer = undefined;
},
exit: function () {
var pointer = self.lastPointer;
self.x = pointer.x;
self.y = pointer.y;
self.worldX = pointer.worldX;
self.worldY = pointer.worldY;
}
},
BEGIN: {
enter: function () {
self.start();
self.tapsCount = 0;
self.emit('tappingstart', self, self.gameObject, self.lastPointer);
},
},
RECOGNIZED: {
enter: function () {
self.start();
self.emit('tap', self, self.gameObject, self.lastPointer);
self.emit(`${self.tapsCount}tap`, self, self.gameObject, self.lastPointer);
},
}
},
init: function () {
this.state = IDLE;
},
eventEmitter: false,
}
this.setRecongizedStateObject(new FSM(stateConfig));
}
resetFromJSON(o) {
super.resetFromJSON(o);
this.setHoldTime(GetValue(o, 'time', 250)); // min-hold-time of Press is 251
this.setTapInterval(GetValue(o, 'tapInterval', 200));
this.setDragThreshold(GetValue(o, 'threshold', 9));
this.setTapOffset(GetValue(o, 'tapOffset', 10));
var taps = GetValue(o, 'taps', undefined);
if (taps !== undefined) {
this.setTaps(taps);
} else {
this.setMaxTaps(GetValue(o, 'maxTaps', undefined));
this.setMinTaps(GetValue(o, 'minTaps', undefined));
}
return this;
}
onDragStart() {
switch (this.state) {
case IDLE:
this.state = BEGIN;
break;
case BEGIN:
var pointer = this.lastPointer;
var tapsOffset = DistanceBetween(
pointer.upX,
pointer.upY,
pointer.x,
pointer.y);
if (tapsOffset > this.tapOffset) { // Can't recognize next level, restart here
this.state = RECOGNIZED;
this.state = BEGIN;
}
break;
case RECOGNIZED:
this.state = BEGIN;
break;
}
}
onDragEnd() {
if (this.state === BEGIN) {
this.tapsCount++; // Try recognize next level
this.emit('tapping', this, this.gameObject, this.lastPointer);
if ((this.maxTaps !== undefined) && (this.tapsCount === this.maxTaps)) { // Reach to maxTaps, stop here
this.state = RECOGNIZED;
}
}
}
onDrag() {
if (this.state === IDLE) {
return;
}
if (this.pointer.getDistance() > this.dragThreshold) { // Cancel
this.state = IDLE;
}
}
preUpdate(time, delta) {
if ((!this.isRunning) || (!this.enable)) {
return;
}
if (this.state === BEGIN) {
var pointer = this.lastPointer;
if (pointer.isDown) {
var holdTime = time - pointer.downTime;
if (holdTime > this.holdTime) {
this.state = IDLE;
}
} else { // isUp
var releasedTime = time - pointer.upTime;
if (releasedTime > this.tapInterval) {
if ((this.minTaps === undefined) || (this.tapsCount >= this.minTaps)) {
this.state = RECOGNIZED;
} else {
this.state = IDLE;
}
}
}
}
}
postUpdate(time, delta) {
if ((!this.isRunning) || (!this.enable)) {
return;
}
// Clear RECOGNIZED after update()
if (this.state === RECOGNIZED) {
this.state = IDLE;
}
}
get isTapping() {
return (this.state === RECOGNIZED);
}
// Backward compatible
get isTapped() {
return this.isTapping;
}
setHoldTime(time) {
this.holdTime = time; // ms
return this;
}
setTapInterval(time) {
this.tapInterval = time; // ms
return this;
}
setDragThreshold(distance) {
this.dragThreshold = distance;
return this;
}
setTapOffset(distance) {
this.tapOffset = distance;
return this;
}
setMaxTaps(taps) {
this.maxTaps = taps;
return this;
}
setMinTaps(taps) {
this.minTaps = taps;
return this;
}
setTaps(minTaps, maxTaps) {
if (maxTaps === undefined) {
maxTaps = minTaps;
}
this.setMinTaps(minTaps).setMaxTaps(maxTaps);
return this;
}
}
const IDLE = 'IDLE';
const BEGIN = 'BEGIN';
const RECOGNIZED = 'RECOGNIZED';
export default Tap;