Options
All
  • Public
  • Public/Protected
  • All
Menu
Unrail Engine logo

Unrail Engine

npm version npm downloads

Unrail Engine is a modern and lightweight 2D game engine written in Typescript during a train ride.

This engine is not only for games, its modules can be used independently. For instance, the render module and the interface one can be used for an animated project.

The renderer is based on the OffscreenCanvas API (currently not supported by Safari & Firefox). The render process is done in a DedicatedWorker which threads the process and speed up the operation ands adapts to the devicePixelRatio.

Examples can be found at /test.
The engine is written using test driven development. Currently there is no test automatisation but the aim is to develop E2E efficient tests.

I - Getting Started
II - Documentation
III - Examples

Getting Started

Installation

Via <script>

To import the engine, you can include the script in your index.html file :

<!-- Production minified ~10kB gzipped -->
<script type="module" src="./unrail-engine.es.js" defer></script> 

Then import it like a regular moduel in your .js file :

import { /* Stuff you need */ } from './unrail-engine/dist/unrail-engine.es.js'

Via NPM:

npm i --save unrail-engine

and import it as an ES module : (the types are included in the package)

import { /* Stuff you need */ } from 'unrail-engine'

Starting a game

The UnrailEngine entry point is the Game object. With this object, all the modules will be instantiated and will work properly. All the objects have to be imported first.

import { Game } from 'unrail-engine'

let game = new Game('Game name')

Then you can register a main loop which will be called the right amout of time to respecct the fps limitation (which can be set by the game.setFPS(fpsNumber) method - default is 60fps)

function update(deltaTime) {
    // Do the update & render job here
}

game.setMainLoop(update)

Then just call game.start() and there you go.

Documentation

The full documentation is available here.

All the entities are built around two methods : update and render. The update method is used to handle the logic of the entity and the render method aims at doing the rendering job and should only use the Renderer static methods.

// main.ts
const { width, height } = getWindowDimensions() 
const env = new Env(width, height) // Create an environment for the game
const game = new Game('Game Name', env)

game.setMainLoop(() => env.update()) // register a main loop
game.start()

Event System

The event system is usefull to communicate between differente classes or objects.
Native events are handled by the system.
The keydown management ideo comes from keydrown and eliminate the delay when long pressing a key.

import { Event } from 'unrail-engine'

// Key Events
Event.onKeyDown('ArrowLeft', e => callback(e)) // While key is down
Event.onKeyPressed('<keyCode>', e => callback(e)) // Fired once

// Custom Events
Event.emit('custom-event-name', params)
Event.on('custom-event-name', callback)

Renderer

The UnrailEngine currently supports 2 render methods : (WebGL rendering is planned)

  • The Renderer object is a classic optimized canvas 2D renderer.
  • The OffscreenRenderer uses the OffscreenCanvas API and web worker to run in a different thread.
    Both renderer uses the same methods name so switching from one to another is as simple as replacing an import alias.
    // Choose one or another
    import { Renderer } from 'unrail-engine'                      // to use the regular renderer
    import { OffscreenRenderer as Renderer } from 'unrail-engine' // to use the multithreaded renderer for better performances
    
// Canvas2DContext options from : https://developer.mozilla.org/fr/docs/Web/API/CanvasRenderingContext2D
let style: StyleObject = { 
    strokeStyle?: string,
    lineWidth?: number,
    lineJoin?: CanvasLineJoin,
    fillStyle?: string,
    globalAlpha?: number,
    globalCompositeOperation?: string
}

// Create a canvas & init the Renderer
Renderer.create()               // To create a canvas with the dimension of the window
Renderer.create(width, height)  // To create a canvas with custom dimensions
Renderer.createFromCanvas('#canvas')  // To create a Renderer from an existing canvas

// Renderer is a static class. Here are the different methods
Renderer.clear()
Renderer.rect(x, y, width, height, style?)
Renderer.line(x1, y1, x2, y2, style?)
Renderer.poly(pointArray, style?)
Renderer.circle(x, y, radius, style?)
Renderer.point(x, y, style?)
Renderer.rectSprite(x, y, width, height, texture)
Renderer.circleSprite(x, y, radius, texture)
Renderer.tint(color, x, y, width, height)      // tint a rect width a color

Interface

import { Interface } from 'unrail-engine'

let value = 'some value'

Interface.addItem(() => `Value : ${value}`, position, { CSSproperties })
// position is a string : 'top-left', 'top-right', 'bottom-left', 'bottom-right' or 'custom'
// CSSproperties is an object containing { css-attribute: value }

// Example :
Interface.addItem(() => `Iteration : ${i++}`, 'top-left', { color: '#999' })

Animation

The Unrail Engine comes with a built-in animation system. To use it, simply declare a new Animation :

import { Easing } from 'unrail-engine'
const options = { autostart?: true, loop?: false }
const animation = new Animation(from, to, duration, Easing.linear, options) // duration in ms
Event.onClick(() => animation.start())

The default easing function is linear, but others are available in the Easing object. To specify an easing function, you can pass the function in the animation constructor or simply its name if the fonction belong to the Easing object.

The available methods of the animation class are :

  • .start() to begin the animation
  • .pause() to stop the animation
  • .resume() to resume the animation
  • .reset() to reset the animation to its initial state
  • .toggle() to toggle the animation state (pause if the state is play and the inverse)
  • .isRunning returns true if the animation is running, else false

Examples


2021 © Dorian Beauchesne

Index

Type aliases

Point

Point: Vector2

Tuple

Tuple: [number, number]

Variables

Const Config

Config: {} = {}

Type declaration

Const Easing

Easing: { easeIn: (t: any) => number; easeInBack: (t: any) => number; easeInOut: (t: any) => number; easeInOutBack: (t: any) => number; easeOut: (t: any) => number; easeOutBack: (t: any) => number; linear: (t: any) => any; smoothStep: (t: any) => number; smootherStep: (t: any) => number } = ...

Type declaration

  • easeIn: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • easeInBack: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • easeInOut: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • easeInOutBack: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • easeOut: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • easeOutBack: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • linear: (t: any) => any
      • (t: any): any
      • Parameters

        • t: any

        Returns any

  • smoothStep: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

  • smootherStep: (t: any) => number
      • (t: any): number
      • Parameters

        • t: any

        Returns number

Const OffscreenRenderer

OffscreenRenderer: typeof OffscreenRenderer | typeof Renderer = ...

Point

Point: typeof Vector2

Const VERSION

VERSION: string = ...

Const V_NULL

V_NULL: Vector2 = ...

Const V_UNIT

V_UNIT: Vector2 = ...

Functions

ApiIsSupported

  • ApiIsSupported(APIname: string): boolean

Random

Random:

adaptCanvasToDevicePixelRatio

  • adaptCanvasToDevicePixelRatio(canvas: HTMLCanvasElement, width?: number, height?: number, ratio?: number): void
  • Parameters

    • canvas: HTMLCanvasElement
    • Optional width: number
    • Optional height: number
    • Optional ratio: number

    Returns void

blink

  • blink(el: string, className: string, interval?: number): void
  • Parameters

    • el: string
    • className: string
    • interval: number = 300

    Returns void

clamp

  • clamp(min: number, x: number, max: number): number

createCanvas

  • createCanvas(w: number, h: number, ratio?: number, preventRightClick?: boolean): HTMLCanvasElement
  • Parameters

    • w: number
    • h: number
    • Optional ratio: number
    • Optional preventRightClick: boolean

    Returns HTMLCanvasElement

getCanvasDimensions

  • getCanvasDimensions(canvas: HTMLCanvasElement): SizeObject

getWindowDimensions

hashObject

  • hashObject(obj: object): string

inRange

  • inRange(x: number, min: number, max: number): boolean

insertCanvas

  • insertCanvas(canvas: HTMLCanvasElement, el: string): void

isWorker

  • isWorker(): boolean

now

  • now(): number

setCanvasDimensions

  • setCanvasDimensions(canvas: HTMLCanvasElement, width: number, height: number, pixelRatio?: number): void
  • Parameters

    • canvas: HTMLCanvasElement
    • width: number
    • height: number
    • Optional pixelRatio: number

    Returns void

windowIsLoaded

  • windowIsLoaded(): boolean

Legend

  • Constructor
  • Property
  • Method
  • Inherited property
  • Inherited method
  • Private property
  • Private method
  • Property
  • Static method

Generated using TypeDoc