Skip to content
This repository was archived by the owner on Jul 31, 2020. It is now read-only.
Merged
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
123 changes: 123 additions & 0 deletions examples/keyboardControls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* tslint:disable:no-console */
import * as WebSocket from 'ws';

import {
GameClient,
IButton,
IButtonData,
IGridPlacement,
setWebSocket,
} from '../lib';

if (process.argv.length < 3) {
console.log('Usage: node keyboardControls.js <token> <versionId>');
process.exit();
}

// We need to tell the interactive client what type of websocket we are using.
setWebSocket(WebSocket);

// As we're on the Streamer's side we need a "GameClient" instance
const client = new GameClient();

// Log when we're connected to interactive
client.on('open', () => console.log('Connected to interactive'));

// This makes grid placement objects dynamically, to be used for our controls below.
function getGridPlacement(x: number, y: number): IGridPlacement[] {
const size = 10;
return [
{
size: 'large',
width: size,
height: size,
x: x * size,
y: y * size,
},
{
size: 'medium',
width: size,
height: size,
x: x * size,
y: y * size,
},
{
size: 'small',
width: size,
height: size,
x: x * size,
y: y * size,
},
];
}

/**
* These are our controls. The "keyCode" property is the JavaScript key code associated
* with the key that participants will press on their keyboard to trigger the button.
*/
const controls: IButtonData[] = [
{
controlID: 'up',
kind: 'button',
text: 'W',
keyCode: 87,
position: getGridPlacement(1, 0),
},
{
controlID: 'left',
kind: 'button',
text: 'A',
keyCode: 65,
position: getGridPlacement(0, 1),
},
{
controlID: 'down',
kind: 'button',
text: 'S',
keyCode: 83,
position: getGridPlacement(1, 1),
},
{
controlID: 'right',
kind: 'button',
text: 'D',
keyCode: 68,
position: getGridPlacement(2, 1),
},
];

// Opens the connection by passing in our authentication details and a versionId.
client.open({
authToken: process.argv[2],
versionId: parseInt(process.argv[3], 10),
})
.then(() => {
// Creates the controls on the default scene, "default".
return client.createControls({
sceneID: 'default',
controls,
});
})
.then(buttons => {
// Now that our controls are created, we can add some event listeners to each.
buttons.forEach((control: IButton) => {
control.on('keydown', (inputEvent, participant) => {
console.log(`${participant.username} pressed ${inputEvent.input.controlID} with their keyboard.`);
});

control.on('keyup', (inputEvent, participant) => {
console.log(`${participant.username} released ${inputEvent.input.controlID} with their keyboard.`);
});

control.on('mousedown', (inputEvent, participant) => {
console.log(`${participant.username} pressed ${inputEvent.input.controlID} with their mouse.`);
});

control.on('mouseup', (inputEvent, participant) => {
console.log(`${participant.username} released ${inputEvent.input.controlID} with their mouse.`);
});
});

// Controls don't appear unless we tell Interactive that we are ready!
client.ready(true);
});
30 changes: 25 additions & 5 deletions src/state/interfaces/controls/IButton.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IParticipant } from '../';
import { IControl, IControlData, IControlUpdate } from './IControl';
import { IButtonInput, IInputEvent } from './IInput';
import { IButtonKeyboardInput, IButtonMouseInput, IInputEvent } from './IInput';

/**
* Extends the regular control data with additional properties for Buttons
Expand Down Expand Up @@ -69,22 +69,42 @@ export interface IButton extends IControl, IButtonData {
update(changedData: IButtonUpdate): Promise<void>;

/**
* Fired when a participant presses this button.
* Fired when a participant presses this button with their mouse.
*/
on(
event: 'mousedown',
listener: (
inputEvent: IInputEvent<IButtonInput>,
inputEvent: IInputEvent<IButtonMouseInput>,
participant: IParticipant,
) => void,
): this;
/**
* Fired when a participant releases this button.
* Fired when a participant releases this button with their mouse.
*/
on(
event: 'mouseup',
listener: (
inputEvent: IInputEvent<IButtonInput>,
inputEvent: IInputEvent<IButtonMouseInput>,
participant: IParticipant,
) => void,
): this;
/**
* Fired when a participant presses the key associated with this button.
*/
on(
event: 'keydown',
listener: (
inputEvent: IInputEvent<IButtonKeyboardInput>,
participant: IParticipant,
) => void,
): this;
/**
* Fired when a participant releases the key associated with this button.
*/
on(
event: 'keyup',
listener: (
inputEvent: IInputEvent<IButtonKeyboardInput>,
participant: IParticipant,
) => void,
): this;
Expand Down
14 changes: 13 additions & 1 deletion src/state/interfaces/controls/IInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface IInput {
/**
* Extends the base input to include button specific data.
*/
export interface IButtonInput extends IInput {
export interface IButtonMouseInput extends IInput {
/**
* Buttons can emit the mousedown(depressed) or mouseup(released) event.
*/
Expand All @@ -29,6 +29,18 @@ export interface IButtonInput extends IInput {
button: number;
}

/**
* Extends the base input to include button specific data.
*/
export interface IButtonKeyboardInput extends IInput {
/**
* Buttons can emit the keydown(depressed) or keyup(released) event.
*/
event: 'keydown' | 'keyup';
}

export type IButtonInput = IButtonMouseInput | IButtonKeyboardInput;

/**
* Extends the base input to include joystick specific data.
*/
Expand Down