Skip to content

Latest commit

 

History

History
1205 lines (821 loc) · 36.8 KB

documentation.MD

File metadata and controls

1205 lines (821 loc) · 36.8 KB

SpringRoll

The latest version, SpringRoll 2, is a large departure from its predecessor. SpringRoll 2 is less prescriptive and contains only a few guidelines and restrictions. Instead, the framework focuses on utilities to help developers make games more accessible and deployable at scale.

  • Adding Sound (WebAudio)
  • Hardware Rendered Games (via WebGL)
  • Implementing Captions
  • Remote Debugging
  • Responsive Interfaces
  • Game State Management
  • Preloading Assets
  • Browser Cache Control

Browser Support

The primary objective of the framework is to build content which supports WebAudio API and WebGL (with Context2d fallback). We have intentionally avoided support for these browsers:

  • Android stock browser (no WebAudio support or suitable fallback support)
  • Internet Explorer 7/8 (no HTML5 canvas support)

Application Documentation

Table of Contents

ColorFilter

The Color filter allows you to simulate colorblindness.

It has built in support for:

  Protanopia
  Protanomaly
	Deuteranopia
  Deuteranomaly
  Tritanopia
  Tritanomaly
  Achromatopsia
  Achromatomaly

To use it, all you have to do is pass it a element and your desired filter.

import { ColorFilter } from './ColorFilter';

const colorFilter = new ColorFilter();

colorFilter.applyFilter(document.getElementById('your-id'), 'protanopia');

You can change the filter at any time. using changeFilter();

colorFilter.changeFilter('deuteranopia');

applyFilter

Applies the specified filter to the element.

Parameters

changeFilter

Changes the currently applied filter to the element if the color filter has it.

Parameters

Returns any

removeFilter

Removes the filter from the element.

types

Supported filter types.

Returns object Returns an object { name, value } with the colorblindness type: (Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly)

SpeechSynth

SpeechSync makes it easy to convert text to speech.

Setup

Using it is as easy as constructing and passing it a string.

  import { SpeechSynth } from '...';

  const speaker = new SpeechSynth();

  speaker.say('Hello world!');
  • Any additional strings passed to it while it's still playing will be queued and will automatically start playing after finishing the current string, unless canceled.

You can also control what the starting params of the voice are by passing in a params object on construction.

const speaker = new SpeechSynth({voice:0, rate:1, pitch:0, volume:1});

You can also change it any time by changing the properties on the object.

speaker.rate = 10;
speaker.pitch = 2;
speaker.volume  = 0.5;
speaker.voice = 30; //Note this one is browser specific and won't work in all cases
  • If you would like to know what voice options are available for your browser, the class instance contains a reference to all options.
speaker.voiceOptions // [Object]

Parameters

  • params object
    • params.voice number Indicates what voice to use. (optional, default 0)
    • params.rate number The rate at which the text is said. Supports a range from 0.1 to 10. (optional, default 1)
    • params.pitch number Voice Pitch. Supports a pitch from 0 to 2. (optional, default 0)
    • params.volume number Volume. Supports 0 to 1. (optional, default 1)

Properties

  • voicesLoaded boolean voices are loaded async. This is will be set to true when they are loaded.

pause

Pauses the announcer.

resume

Resumes the announcer.

cancel

Pauses the announcer and clears the queue.

say

Causes the announcer to say whatever message is passed to it. If the announcer is already saying something then it will be added to a queue.

Parameters

setVoice

Sets the voice by array index.

Parameters

getVoice

Returns the voice object.

Returns (object | null)

rate

Rate at which text is spoken.

Parameters

rate

Returns rate which text is spoken.

Returns number

pitch

Sets the pitch at which text is spoken.

Parameters

pitch

Returns the pitch at which text is spoken.

Returns number

volume

Sets the current volume of the announcer.

Parameters

volume

Returns the current volume of the announcer.

Returns number

Application

The SpringRoll Application provides the main entrypoint for games. In particular, it provides access to any functionality provided by plugins along with access to any state set or changed by the container.

Usage Example

var application = new springroll.Application();
application.state.ready.subscribe(function(isReady) {
  if(!isReady) {
    return;
  }

  // all plugins have loaded
});

Features

When an Application is embedded via a SpringRollContainer it can notify the container of it's supported features. To do this in a SpringRoll Application, pass them as an object to the constructor:

var myApp = new springroll.Application({
  captions: false, // whether or not the game has captions
  sound: false, // whether or not the game has any sound
  vo: false, // whether or not the game has a VO
  music: false, // whether or not the game has music
  sfx: false, // whether or not the game has any sound effects
});

Note that if any of vo, music, or sfx are available features, sound will be marked as a feature implicitly. Also, all of these features are marked false by default.

Handling State Change

When certain features are enabled, SpringRoll warns if an associated state change listener is missing. For instance, if sound is enabled as a feature of the game, there must be a subscriber to the soundMuted state:

var myApp = new springroll.Application({
  sound: true
});

myApp.state.sound.subscribe(result => console.log('Is sound muted?', result));

For each possible feature, there is an associated state that can be subscribed to:

var myApp = new springroll.Application({
  captions: true,
  sound: true,
  vo: true,
  music: true,
  sfx: true
});

myApp.state.captionsMuted.subscribe(result => console.log('Are captions muted?', result));
myApp.state.sound.subscribe(result => console.log('Is sound muted?', result));
myApp.state.vo.subscribe(result => console.log('Is VO muted?', result));
myApp.state.music.subscribe(result => console.log('Is music muted?', result));
myApp.state.sfx.subscribe(result => console.log('Is SFX muted?', result));

Lastly, there are two other states available, one that has already been mentioned:

var myApp = new Application();

myApp.state.ready.subscribe(() => {
  console.log('The app is ready. All plugins have finished their setup and preload calls');
});

myApp.state.pause.subscribe(isPaused => {
  console.log('Is the game paused?', isPaused);
});

state

promisify

Converts a callback-based or synchronous function into a promise. This method is used for massaging plugin preload methods before they are executed.

Parameters
  • callback Function A function that takes either a callback, or returns a promise.

Returns any Promise A promise that resolves when the function finishes executing (whether it is asynchronous or not).

validateListeners

Validates that appropriate listeners are added for the features that were enabled in the constructor

  • Throws any Error

_plugins

The list of plugins that are currently registered to run on Applications.

uses

Registers a plugin to be used by applications, sorting it by priority order.

Parameters

Controller

Controller interface class to simplify working with key presses.

It accepts a array of objects that follow this format Object {key: string, down?: function, up?: function}

import { Controller } from ...

const controller = new Controller([
  { key: 'ArrowLeft', down: () => console.log('left arrow pushed down!')},
  { key: 'ArrowDown', down: () => console.log('down arrow pushed down!')},
  { key: 'ArrowRight', down: () => console.log('right arrow pushed down!')},
  { key: 'ArrowUp', down: () => console.log('up arrow pushed down!')},
  { key: 'Enter', down: () => console.log('enter pushed down!')},
  { key: ' ', down: () => console.log('space bar pushed down!'), up: () => console.log('space bar stopped being pushed down!')},
]);
  • Key values can be found here

  • Key values are case insensitive.

The controller will monitor key inputs for you. Call the function when you wish to call the functions that are related to the currently active keys.

controller.update();

If at any time you wish to change the keys currently being watched, you can call the assignButtons function. This follows the same format as the constructor:

controller.assignButtons([
  { key: 'a', down: () => console.log('a pushed down!')},
  { key: 's', down: () => console.log('s pushed down!')},
  { key: 'd', down: () => console.log('d pushed down!')},
  { key: 'w', down: () => console.log('w arrow pushed down!')},
  { key: 'Enter', down: () => console.log('enter pushed down!')},
  { key: ' ', down: () => console.log('space bar pushed down!'), up: () => console.log('space bar stopped being pushed down!')},
]);

Parameters

update

Calls all functions for buttons that are currently set to enabled.

onKeyDown

Called on keyup. Sets flag to 1 if key is being watched.

Parameters

onKeyUp

Called on keyup. Sets flag to 2 if key is being watched.

Parameters

assignButtons

Sets an object of button functions to the controller to be called.

Parameters

Key

Represents a single key on the keyboard and the functions related to it.

Parameters

  • key string What this object represents.
  • down function Function to be called while the key is held down. (optional, default ()=>{})
  • up function Function to be called when the key is lifted up. (optional, default ()=>{})

Properties

  • state (0 | 1 | 2) The current state of the key. 0 = inactive, 1 = active, 2 = to be set to inactive.
  • key string The name of the key we are targeting.
  • actions object
    • actions.down function Function to be called while the key is held down.
    • actions.up function Function to be called when the key is lifted up.

updateState

Updates the internal state of the key. Accepts a range between 0-2. Will set key state to 0 if nothing is passed.

Parameters
  • state (0 | 1 | 2) (optional, default 0)

action

Calls the relevant action for the current state of the key.

state

Returns the current state of the key.

Returns number

Debugger

Type: object

Simplifies logging events to the console for debugging purposes.

Parameters

  • params Object Options
    • params.emitEnabled boolean If this should emit events to the window. (optional, default false)
    • params.minLevel ("GENERAL" | "DEBUG" | "INFO" | "WARN" | "ERROR") The starting log level for the logger. (optional, default 'GENERAL')

Properties

params

Returns the params of the debugger.

Returns DebuggerParams

minLevel

Sets the logging level of the debugger.

Parameters

Returns void

emit

If emitting is enabled for this instance, then it will dispatch an event on the window.

Parameters
  • eventName string Name of the event (optional, default 'Debugger')

LEVEL

Returns logging levels.

Returns object

log

Console logs all supplied arguments if the log level is low enough for them to be logged.

Parameters
  • type ("log" | "general" | "warn" | "error" | "debug" | "info") minimum level for this log to run at (optional, default 'log')
  • args Array<any> Arguments you wish to log.

assert

Will throw if statement is false.

Parameters
  • isTrue boolean The expression to evaluate.

isEnabled

Returns a boolean indicating if the debugger has been enabled or not.

Returns boolean

enable

Disables or enables all debugger instances.

Parameters

Returns void

paramKey

Returns the global params key.

Caption

update

Updates content based on time passed. This should be called every frame that the caption is active.

Parameters
  • deltaTime Number Time in seconds since last frame.

updateState

Handles calling callbacks and updating caption's current state.

Parameters

isFinished

Checks if caption has completed.

Returns Boolean

start

Sets time and line index of caption.

Parameters
  • time Number Time in milliseconds. (optional, default 0)
  • beginCallback (optional, default ()=>{})
  • endCallback (optional, default ()=>{})

CaptionFactory

Collection of functions for creating

The CaptionPlayer object provides a simplified way to handle playing captions in your game.

Initializing

In order to play a caption you'll first need to initialize a captions player and an object for rendering your captions.

  import { CaptionPlayer, CaptionFactory } from 'springroll/localization'

  // Start and end times are in Milliseconds
  const captionData = {
    "welcome":[
      {
        "content": "This is the first line"
        "start":0,
        "end": 1200
      },
      {
        "content": "This is the second line"
        "start":1300,
        "end": 2400
      }
    ],
    "other":[
      {
        "content": "this caption only has on line"
        "start":0,
        "end": 3000
      }
    ]
  }

  const captionsElement = document.getElementById("captions");
  const captionMap = CaptionFactory.createCaptionMap(captionData);
  const captionPlayer = new CaptionPlayer(captionMap, {
    start:() => {
      captionsElement.style.visibility = "visible";
    },
    lineBegin:(line) => {
      captionsElement.innerHTML = line.content;
    },
    lineEnd:() => {
      captionsElement.innerHTML = '';
    },
    stop:() => {
      captionsElement.style.visibility = "hidden";
    }
  });

Each line in a caption must have a start and end time, if you want to have a delay between lines you should add time to the start of the next line. It's not recommended to use a line with an empty content.

If line B's start time is before line A's end time, then A will finish before B starts.

A caption renderer can have the following callbacks.

Name Time
start() Called when CaptionPlayer.start() is called
stop() Called when CaptionPlayer.stop() is called or when caption is finished
lineBegin(line) Called at the beginning of each line after CaptionPlayer.start()
lineEnd() Called at the end of each line, called before CaptionPlayer.stop()

Updating

The caption player needs to be updated regularly in order for it to function properly. It's recommended to call update on every frame for the most accurate timing.

  // DeltaTime is the time passed in SECONDS since the last update call.
  captionPlayer.update(deltaTime);

Playing a caption

To start playing a caption, you call start. You can pass a start time in as an optional parameter.

  captionPlayer.start('welcome');
  captionPlayer.start('welcome', 1200);

Note: the CaptionPlayer can only play one caption at a time

Stopping a caption

Captions automatically stop when the time passed is greater than the end time. You can manually stop them if you need to.

  captionPlayer.stop();

Example:

class HTMLCaptionRenderer
{
  constructor(element)
  {
    this.element = element;
  }

  start() => {
    element.style.visibility = "visible";
  }

  lineBegin(line) => {
    element.innerHTML = line.content;
  }

  lineEnd() => {
    element.innerHTML = '';
  }

  stop() => {
    element.style.visibility = "hidden";
  }
}

class YourGame
{
  preload()
  {
    this.loader.load('assets/captions.json', 'captionData');
  }

  start()
  {
    const captionsElement = document.getElementById("captions");
    const captionMap = CaptionFactory.createCaptionMap(this.cache.getJSON('captionData'));
    this.captionPlayer = new CaptionPlayer(captionMap, new HTMLCaptionRenderer(captionsElement));

    this.captionPlayer.start('example');
  }

  update()
  {
    this.captionPlayer.update(this.Time.DeltaTime * this.Time.scale);
  }
}

createCaptionMap

Creates a new Object<String, Caption>.

Parameters

Returns Object

createCaption

Creates a new Caption from JSON data.

Parameters

Returns Caption new Caption

createLine

Creates a new TimedLine from JSON data.

Parameters

Returns TimedLine new TimedLine;

CaptionPlayer

Object used to render caption.

Parameters

  • captions
  • renderer

update

Updates any currently playing caption. This should be called every frame.

Parameters
  • deltaTime Number Time passed in seconds since last update call.

start

Starts playing a caption.

Parameters
  • name String Name of caption.
  • time number Atart time in milliseconds. (optional, default 0)

Returns boolean True if caption started.

stop

Stops any caption currently playing.

CaptionPlayer

CaptionPlayer is used to start, stop and update captions. It applies the content of an active caption to a given CaptionRenderer.

update

Updates any currently playing caption. This should be called every frame.

Parameters
  • deltaTime Number Time passed in seconds since last update call.

start

Starts playing a caption.

Parameters
  • name String Name of caption.
  • time number Atart time in milliseconds. (optional, default 0)

Returns boolean True if caption started.

stop

Stops any caption currently playing.

milliToSec

Parameters

  • time

TimedLine

setContent

Sets line's content. Removes HTML formatting for text.

Parameters
  • content any

Returns void @memberof TimedLine

Localizer.Options

Type: {language: string, fallback: string}

Localizer

The localizer object provides a layer above your file loader to help with loading localized files.

Initializing

In order to use the localizer you'll have to provide a config with a default locale, as well as all the locales you wish to use.

import { Localizer } from 'springroll/localization';

const config = {
  "default":"en",
  "locales":
  {
    "en": { "path": "assets/en/" },
    "fr": { "path": "assets/fr/" },
    "fr-ca": { "path": "assets/fr-CA/" }
  }
}

const localizer = new Localizer(config);

The localizer will automatically look for the browser's language and use it. A fallback locale will also be set from default in the config. The fallback is used automatically if a specified language can't be found in locales.

An options object can also be provided to manually set the target and fallback languages.

const localizer = new Localizer(config, { language:'fr', fallback:'en'});

Loading a File

localizer.resolve() Returns an object that contains the resolved path.

let result = localizer.resolve('vo/welcome.mp3');
loader.load(result.path, 'welcome');

This will load a file relative to the current locale, for example if the browser language was set to French-Canadian, the path supplied to the load function would look like: assets/fr-CA/vo/welcome.mp3.

You can also provide an options object to override the target and fallback languages for only a single load event.

let result = localizer.resolve('vo/welcome.mp3', { language: 'es-ES', fallback: 'en' });
loader.load(result.path, 'welcome');

If the language or fallback are not found in the locales, then it will load with the default fallback. For example: if 'es-ES' is not found, the load function will try 'es' if that isn't found, it will use the fallback language 'en'.

Result also contains the language key of the language used.

let result = localizer.resolve('vo/welcome.mp3', { language: 'es-ES', fallback: 'en' })
console.log(result.language); // 'en'

Example:

class YourGame
{
	init()
		this.localizer = new Localizer(this.localizerConfig);
	}

	preload()
	{
		// load all your localized files.
		let result = this.localizer.resolve('vo/welcome.mp3')
		this.loader.load(result.path, 'welcome');

		result = this.localizer.resolve('local.json')
		this.loader.load(result.path, 'local');
		//...

		// Any non localized files don't have to go though the localizer.
		this.loader.load('assets/images/Foo.png', 'fooSprite');
		//...
	}

	start()
	{
		//Do things with loaded files;
		let welcome = new Sound('welcome');
		welcome.play();
		//...
	}
}

resolve

Parameters
  • path
  • options any (optional, default {})
  • Path string

Returns Promise

setPrimaryLocale

Parameters

Returns boolean True if language is set.

setFallbackLocale

Parameters

Returns boolean True if fallback is set.

getLocaleKey

Parameters

Returns string

getBrowserLanguages

Returns Array<string> An array of browser languages.

ApplicationPlugin

Represents a single plugin for applications. Allows developers to inject code in the start up process of an application providing new features to the application.

import { ApplicationPlugin } from 'springroll/plugins/ApplicationPlugin';

export default class CustomPlugin extends ApplicationPlugin {
  constructor() {
    let priority = 20;
    super(priority);
  }

  setup() {
    // custom synchronous code. `this` is bound to the current Application
    this.customContent = {};
  }

  preload() {
    // custom asynchronous code. Expected to return a Promise.
    return fetch(someApiEndpoint)
      .then(response => response.json())
      .then(json => this.customContent = json);
  }
}

Once you've created a plugin, you'll need to register it before instantiating the application:

import { Application } from 'springroll';
import CustomPlugin from './CustomPlugin';

Application.uses(new CustomPlugin());

const myApp = new Application();
myApp.on('init', function() {
  console.log('Ready!');
});

setup

A setup method for the plugin. This method is ran synchronously in the constructor of the Application.

preload

A preload method for the plugin which allows for asynchronous setup tasks. Either takes a callback as first parameter, or should return a Promise indicating that loading is finished.

Parameters
  • callback (Function | undefined) A callback to call when finished (or no parameter at all).

Returns (Promise | undefined) If defined, treated as promise indicating when the plugin is finished loading.

ScaleManager

Simplifies listening to resize events by passing the relevant data to a provided callback.

Parameters

  • callback Function (optional, default undefined)

Properties

enable

Enables the scale manager listener. Will not be enabled if a callback is not supplied.

Parameters
  • callback Function The function to be called on resize events. (optional, default undefined)

disable

Disables the scale manager.

Property

A class for representing changeable/subscribable properties.

notifyChange

Notifies all subscribers to the property of a new value.

subscribe

Adds a subscriber to this property.

Parameters
  • callback
  • Function callback The callback to call whenever the property changes.

unsubscribe

Unsubscribes a listener from this property.

Parameters
  • callback
  • Function callback The callback to unsubscribe.

hasListeners

Whether or not this property has any subscribed listeners

Returns any Boolean True if this property has at least one subscriber

StateManager

A class for managing a group of subscribable properties together. Allows for the registration of new properties.

For example:

var manager = new StateManager();
manager.addField('paused', false);
manager.paused.subscribe(function(newValue) {
  console.log('New value is ', newValue);
})

manager.paused = true;

addField

Adds a new subscribable field field to the state manager. Throws an error if the field already exists.

Parameters
  • name String The name of the field.
  • initialValue Any The initial value of the property.

Returns any Property The newly created property.