Skip to content
This repository was archived by the owner on Mar 5, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions SupEngine/SupEngine.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,8 @@ declare namespace SupEngine {
}

class Input {
static maxTouches: number;

exited: boolean;

canvas: HTMLCanvasElement;

mouseButtons: MouseButtonState[];
Expand All @@ -186,7 +185,12 @@ declare namespace SupEngine {
newScrollDelta: number;

touches: TouchState[];
touchesDown: boolean[];
touchesDown: number[];
touchesStarted: number[];
touchesEnded: number[];
touchesMoved: number[];
mouseTouchIdentifier: number;
touchEmulatesMouse: boolean;

keyboardButtons: KeyState[];
keyboardButtonsDown: boolean[];
Expand Down
122 changes: 96 additions & 26 deletions SupEngine/src/Input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ interface TouchState {
isDown: boolean;
wasStarted: boolean;
wasEnded: boolean;
wasMoved: boolean;
position: { x: number; y: number; };
identifier: number;
}

interface GamepadButtonState {
Expand All @@ -45,8 +47,6 @@ interface GamepadAutoRepeat {
}

export default class Input extends EventEmitter {
static maxTouches = 10;

canvas: HTMLCanvasElement;

mouseButtons: MouseButtonState[] = [];
Expand All @@ -58,7 +58,12 @@ export default class Input extends EventEmitter {
newScrollDelta: number;

touches: TouchState[] = [];
touchesDown: boolean[] = [];
touchesDown: number[] = [];
touchesStarted: number[] = [];
touchesEnded: number[] = [];
touchesMoved: number[] = [];
mouseTouchIdentifier: number = null;
touchEmulatesMouse = false;

keyboardButtons: KeyState[] = [];
keyboardButtonsDown: boolean[] = [];
Expand Down Expand Up @@ -193,10 +198,12 @@ export default class Input extends EventEmitter {
this.newMouseDelta.y = 0;

// Touch
for (let i = 0; i < Input.maxTouches; i++) {
this.touches[i] = { isDown: false, wasStarted: false, wasEnded: false, position: { x: 0, y: 0} };
this.touchesDown[i] = false;
}
this.touchesDown = [];
this.touches = [];
this.touchesEnded = [];
this.touchesStarted = [];
this.touchesMoved = [];
this.mouseTouchIdentifier = null;

// Keyboard
for (let i = 0; i <= 255; i++) {
Expand Down Expand Up @@ -371,43 +378,74 @@ export default class Input extends EventEmitter {
private onTouchStart = (event: any) => {
event.preventDefault();

if (this.touchEmulatesMouse && this.mouseTouchIdentifier == null &&
this.touchesDown.length === 0 && event.changedTouches.length > 0) {
// track first touch as mouse
this.mouseTouchIdentifier = event.changedTouches[0].identifier;
}

const rect = event.target.getBoundingClientRect();
const changedTouchesArray: any[] = [];

for (let i = 0; i < event.changedTouches.length; i++) {
const touch = event.changedTouches[i];
this.touches[touch.identifier].position.x = touch.clientX - rect.left;
this.touches[touch.identifier].position.y = touch.clientY - rect.top;
changedTouchesArray.push(event.changedTouches[i]);
}

this.touchesDown[touch.identifier] = true;
changedTouchesArray.forEach(touch => {
const touchInput: TouchState =
{ identifier: touch.identifier, wasStarted: true, wasEnded: false, wasMoved: false, isDown: false, position: { x: touch.clientX - rect.left, y: touch.clientY - rect.top } };

if (touch.identifier === 0) {
this.newMousePosition = { x: touch.clientX - rect.left, y: touch.clientY - rect.top };
this.touches.push(touchInput);

if (this.touchEmulatesMouse && touch.identifier === this.mouseTouchIdentifier) {
this.newMousePosition = touch.position;
this.mouseButtonsDown[0] = true;
}
}
});
};

private onTouchEnd = (event: any) => {
event.preventDefault();

const rect = event.target.getBoundingClientRect();
const touchUpdates: any[] = [];

for (let i = 0; i < event.changedTouches.length; i++) {
const touch = event.changedTouches[i];
this.touchesDown[touch.identifier] = false;
if (touch.identifier === 0) this.mouseButtonsDown[0] = false;
touchUpdates.push(touch);
}

touchUpdates.forEach(touch => {
const touchesToChange = this.touches.filter(t => t.identifier === touch.identifier);
touchesToChange.forEach(t => {
t.wasEnded = true;
t.position.x = touch.clientX - rect.left;
t.position.y = touch.clientY - rect.top;
if (this.touchEmulatesMouse && t.identifier === this.mouseTouchIdentifier) this.mouseButtonsDown[0] = false;
});
});
};

private onTouchMove = (event: any) => {
event.preventDefault();

const rect = event.target.getBoundingClientRect();
const touchUpdates: any[] = [];

for (let i = 0; i < event.changedTouches.length; i++) {
const touch = event.changedTouches[i];
this.touches[touch.identifier].position.x = touch.clientX - rect.left;
this.touches[touch.identifier].position.y = touch.clientY - rect.top;

if (touch.identifier === 0) this.newMousePosition = { x: touch.clientX - rect.left, y: touch.clientY - rect.top };
touchUpdates.push(touch);
}

touchUpdates.forEach(touch => {
const touchesToChange = this.touches.filter(t => t.identifier === touch.identifier);
touchesToChange.forEach(t => {
t.wasMoved = true;
t.position.x = touch.clientX - rect.left;
t.position.y = touch.clientY - rect.top;
if (this.touchEmulatesMouse && t.identifier === this.mouseTouchIdentifier) this.mousePosition = t.position;
});
});
};

// TODO: stop using keyCode when KeyboardEvent.code is supported more widely
Expand Down Expand Up @@ -474,15 +512,47 @@ export default class Input extends EventEmitter {
mouseButton.wasJustReleased = wasDown && !mouseButton.isDown;
}

for (let i = 0; i < this.touches.length; i++) {
const touch = this.touches[i];
const wasDown = touch.isDown;
touch.isDown = this.touchesDown[i];
const touchesToRemove: TouchState[] = [];
this.touchesEnded = [];
this.touchesStarted = [];
this.touchesMoved = [];
this.touchesDown = [];

if(this.touches.length > 0) {
this.touches.forEach(touch => {
touch.wasStarted = touch.wasStarted && !touch.isDown;
touch.isDown = (touch.wasStarted || touch.isDown);

if(touch.isDown){
this.touchesDown.push(touch.identifier);
}

if (touch.wasStarted) {
this.touchesStarted.push(touch.identifier);
}

if(touch.wasMoved){
this.touchesMoved.push(touch.identifier);
}

touch.wasStarted = !wasDown && touch.isDown;
touch.wasEnded = wasDown && !touch.isDown;
if (touch.wasEnded) {
if (touch.isDown) {
this.touchesEnded.push(touch.identifier);
}
else {
touchesToRemove.push(touch);
}
touch.isDown = false;
}
});
}

touchesToRemove.forEach(ti => {
console.log(`Removing touch: ${ti.identifier}`);
const indexToRemove = this.touches.indexOf(ti);
if (indexToRemove > -1) this.touches.splice(indexToRemove, 1);
});

for (let i = 0; i < this.keyboardButtons.length; i++) {
const keyboardButton = this.keyboardButtons[i];
const wasDown = keyboardButton.isDown;
Expand Down
15 changes: 11 additions & 4 deletions plugins/default/typescript/typescriptAPI/Sup.Input.d.ts.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,17 @@ declare namespace Sup {
function wasMouseButtonJustPressed(button: number): boolean;
function wasMouseButtonJustReleased(button: number): boolean;

function getTouchPosition(index: number): Math.Vector2;
function isTouchDown(index: number): boolean;
function wasTouchStarted(index: number): boolean;
function wasTouchEnded(index: number): boolean;
function setTouchEmulatesMouse(emulate: boolean);
function getTouchPosition(identifier: number): Math.Vector2;
function isTouchDown(identifier?: number): boolean;
function wasTouchJustStarted(identifier?: number): boolean;
function wasTouchJustEnded(identifier?: number): boolean;
function wasTouchJustMoved(identifier?: number): boolean;
function getTouchesStarted(): number[];
function getTouchesEnded(): number[];
function getTouchesMoved(): number[];
function getTouchesDown(): number[];

function vibrate(pattern: number|number[]): void;

// Valid key names (based on window.KeyEvent.DOM_VK_*):
Expand Down
57 changes: 46 additions & 11 deletions plugins/default/typescript/typescriptAPI/Sup.Input.ts.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,60 @@ namespace Sup {
return player.gameInstance.input.mouseButtons[button].wasJustReleased;
}

export function setTouchEmulatesMouse(emulate: boolean) {
player.gameInstance.input.touchEmulatesMouse = emulate;
}

export function getTouchPosition(index) {
var position = player.gameInstance.input.touches[index].position;
export function getTouchPosition(identifier: number): Math.Vector2 {
let activeTouches = player.gameInstance.input.touches.filter(t=>t.identifier === identifier);
if(activeTouches.length === 0) throw new Error("Invalid touch identifier");
//default to first touch - more than one touch is actually an error...
let position = activeTouches[0].position;
return new Math.Vector2(position.x / player.canvas.clientWidth * 2 - 1, (position.y / player.canvas.clientHeight * 2 - 1) * -1);
}

export function isTouchDown(index) {
if (player.gameInstance.input.touches[index] == null) { throw new Error("Invalid touch index"); }
return player.gameInstance.input.touches[index].isDown;
export function isTouchDown(identifier?: number): boolean {
if(identifier != null)
return player.gameInstance.input.touchesDown.indexOf(identifier) > -1;
else
return player.gameInstance.input.touchesDown.length > 0;
}

export function wasTouchJustStarted(identifier?: number): boolean {
if(identifier != null)
return player.gameInstance.input.touchesStarted.indexOf(identifier) > -1;
else
return player.gameInstance.input.touchesStarted.length > 0;
}

export function wasTouchJustEnded(identifier?: number): boolean {
if(identifier != null)
return player.gameInstance.input.touchesEnded.indexOf(identifier) > -1;
else
return player.gameInstance.input.touchesEnded.length > 0;
}

export function wasTouchJustMoved(identifier?: number): boolean {
if(identifier != null)
return player.gameInstance.input.touchesMoved.indexOf(identifier) > -1;
else
return player.gameInstance.input.touchesMoved.length > 0;
}

export function getTouchesStarted(): number[] {
return player.gameInstance.input.touchesStarted;
}

export function getTouchesEnded(): number[] {
return player.gameInstance.input.touchesEnded;
}

export function wasTouchStarted(index) {
if (player.gameInstance.input.touches[index] == null) { throw new Error("Invalid touch index"); }
return player.gameInstance.input.touches[index].wasStarted;
export function getTouchesMoved(): number[] {
return player.gameInstance.input.touchesMoved;
}

export function wasTouchEnded(index) {
if (player.gameInstance.input.touches[index] == null) { throw new Error("Invalid touch index"); }
return player.gameInstance.input.touches[index].wasEnded;
export function getTouchesDown(): number[] {
return player.gameInstance.input.touchesDown;
}

export function vibrate(pattern) { window.navigator.vibrate(pattern); }
Expand Down