From 8dff724af4750b1fe72fd9f478a0689b47d087a8 Mon Sep 17 00:00:00 2001 From: Frank Force Date: Mon, 29 Jan 2024 11:40:37 -0600 Subject: [PATCH] rebuild docs --- docs/Audio.html | 2 +- docs/Color.html | 2 +- docs/Debug.html | 2 +- docs/Draw.html | 2 +- docs/Engine.html | 2 +- docs/EngineObject.html | 2 +- docs/FontImage.html | 2 +- docs/Input.html | 2 +- docs/Medal.html | 2 +- docs/Medals.html | 2 +- docs/Music.html | 2 +- docs/Newgrounds.html | 2 +- docs/Particle.html | 2 +- docs/ParticleEmitter.html | 2 +- docs/Random.html | 2 +- docs/RandomGenerator.html | 2 +- docs/Settings.html | 2 +- docs/Sound.html | 2 +- docs/SoundWave.html | 6 +- docs/TileCollision.html | 2 +- docs/TileLayer.html | 2 +- docs/TileLayerData.html | 2 +- docs/Timer.html | 2 +- docs/Utilities.html | 2 +- docs/Vector2.html | 2 +- docs/WebGL.html | 2 +- docs/data/search.json | 2 +- docs/engine.js.html | 21 ++++--- docs/engineAudio.js.html | 112 +++++++++++++++++++++-------------- docs/engineDebug.js.html | 10 +++- docs/engineDraw.js.html | 10 ++-- docs/engineExport.js.html | 4 +- docs/engineInput.js.html | 36 +++++++---- docs/engineMedals.js.html | 4 +- docs/engineObject.js.html | 4 +- docs/engineParticles.js.html | 4 +- docs/engineSettings.js.html | 4 +- docs/engineTileLayer.js.html | 4 +- docs/engineUtilities.js.html | 4 +- docs/engineWebGL.js.html | 90 ++++++++++++++-------------- docs/examples/screenshot.jpg | Bin 227698 -> 166544 bytes docs/index.html | 4 +- 42 files changed, 207 insertions(+), 162 deletions(-) diff --git a/docs/Audio.html b/docs/Audio.html index dac32695..61f8657f 100644 --- a/docs/Audio.html +++ b/docs/Audio.html @@ -1,3 +1,3 @@ Namespace: Audio
On this page

Audio

LittleJS Audio System

  • ZzFX Sound Effects - ZzFX Sound Effect Generator
  • ZzFXM Music - ZzFXM Music System
  • Caches sounds and music for fast playback
  • Can attenuate and apply stereo panning to sounds
  • Ability to play mp3, ogg, and wave files
  • Speech synthesis functions

Members

(static) audioContext

Audio context used by the engine

(static, constant) zzfxR

Sample rate used for all ZzFX sounds

Default Value
  • 44100

Methods

(static) getNoteFrequency(semitoneOffset, rootNoteFrequencyopt) → {Number}

Get frequency of a note on a musical scale

Parameters:
NameTypeAttributesDefaultDescription
semitoneOffsetNumber

How many semitones away from the root note

rootNoteFrequencyNumber<optional>
220

Frequency at semitone offset 0

Returns:
  • The frequency of the note
Type: 
Number

(static) playAudioFile(url, volumeopt, loopopt) → {HTMLAudioElement}

Play an mp3 or wav audio from a local file or url

Parameters:
NameTypeAttributesDefaultDescription
urlString

Location of sound file to play

volumeNumber<optional>
1

How much to scale volume by

loopBoolean<optional>
1

True if the music should loop when it reaches the end

Returns:
  • The audio element for this sound
Type: 
HTMLAudioElement

(static) playSamples(sampleChannels, volumeopt, rateopt, panopt, loopopt) → {AudioBufferSourceNode}

Play cached audio samples with given settings

Parameters:
NameTypeAttributesDefaultDescription
sampleChannelsArray

Array of arrays of samples to play (for stereo playback)

volumeNumber<optional>
1

How much to scale volume by

rateNumber<optional>
1

The playback rate to use

panNumber<optional>
0

How much to apply stereo panning

loopBoolean<optional>
0

True if the sound should loop when it reaches the end

Returns:
  • The audio node of the sound played
Type: 
AudioBufferSourceNode

(static) speak(text, languageopt, volumeopt, rateopt, pitchopt) → {SpeechSynthesisUtterance}

Speak text with passed in settings

Parameters:
NameTypeAttributesDefaultDescription
textString

The text to speak

languageString<optional>

The language/accent to use (examples: en, it, ru, ja, zh)

volumeNumber<optional>
1

How much to scale volume by

rateNumber<optional>
1

How quickly to speak

pitchNumber<optional>
1

How much to change the pitch by

Returns:
  • The utterance that was spoken
Type: 
SpeechSynthesisUtterance

(static) speakStop()

Stop all queued speech

(static) zzfx(…zzfxSound) → {AudioBufferSourceNode}

Generate and play a ZzFX sound

Create sounds using the ZzFX Sound Designer.

Parameters:
NameTypeAttributesDescription
zzfxSoundArray<repeatable>

Array of ZzFX parameters, ex. [.5,.5]

Returns:
  • The audio node of the sound played
Type: 
AudioBufferSourceNode

(static) zzfxG(volumeopt, randomnessopt, frequencyopt, attackopt, sustainopt, releaseopt, shapeopt, shapeCurveopt, slideopt, deltaSlideopt, pitchJumpopt, pitchJumpTimeopt, repeatTimeopt, noiseopt, modulationopt, bitCrushopt, delayopt, sustainVolumeopt, decayopt, tremoloopt) → {Array}

Generate samples for a ZzFX sound

Parameters:
NameTypeAttributesDefaultDescription
volumeNumber<optional>
1

Volume scale (percent)

randomnessNumber<optional>
.05

How much to randomize frequency (percent Hz)

frequencyNumber<optional>
220

Frequency of sound (Hz)

attackNumber<optional>
0

Attack time, how fast sound starts (seconds)

sustainNumber<optional>
0

Sustain time, how long sound holds (seconds)

releaseNumber<optional>
.1

Release time, how fast sound fades out (seconds)

shapeNumber<optional>
0

Shape of the sound wave

shapeCurveNumber<optional>
1

Squarenes of wave (0=square, 1=normal, 2=pointy)

slideNumber<optional>
0

How much to slide frequency (kHz/s)

deltaSlideNumber<optional>
0

How much to change slide (kHz/s/s)

pitchJumpNumber<optional>
0

Frequency of pitch jump (Hz)

pitchJumpTimeNumber<optional>
0

Time of pitch jump (seconds)

repeatTimeNumber<optional>
0

Resets some parameters periodically (seconds)

noiseNumber<optional>
0

How much random noise to add (percent)

modulationNumber<optional>
0

Frequency of modulation wave, negative flips phase (Hz)

bitCrushNumber<optional>
0

Resamples at a lower frequency in (samples*100)

delayNumber<optional>
0

Overlap sound with itself for reverb and flanger effects (seconds)

sustainVolumeNumber<optional>
1

Volume level for sustain (percent)

decayNumber<optional>
0

Decay time, how long to reach sustain after attack (seconds)

tremoloNumber<optional>
0

Trembling effect, rate controlled by repeat time (precent)

Returns:
  • Array of audio samples
Type: 
Array

(static) zzfxM(instruments, patterns, sequence, BPMopt) → {Array}

Generate samples for a ZzFM song with given parameters

Parameters:
NameTypeAttributesDefaultDescription
instrumentsArray

Array of ZzFX sound paramaters

patternsArray

Array of pattern data

sequenceArray

Array of pattern indexes

BPMNumber<optional>
125

Playback speed of the song in BPM

Returns:
  • Left and right channel sample data
Type: 
Array
\ No newline at end of file +
On this page

Audio

LittleJS Audio System

  • ZzFX Sound Effects - ZzFX Sound Effect Generator
  • ZzFXM Music - ZzFXM Music System
  • Caches sounds and music for fast playback
  • Can attenuate and apply stereo panning to sounds
  • Ability to play mp3, ogg, and wave files
  • Speech synthesis functions

Members

(static) audioContext

Audio context used by the engine

(static, constant) zzfxR

Sample rate used for all ZzFX sounds

Default Value
  • 44100

Methods

(static) getNoteFrequency(semitoneOffset, rootNoteFrequencyopt) → {Number}

Get frequency of a note on a musical scale

Parameters:
NameTypeAttributesDefaultDescription
semitoneOffsetNumber

How many semitones away from the root note

rootNoteFrequencyNumber<optional>
220

Frequency at semitone offset 0

Returns:
  • The frequency of the note
Type: 
Number

(static) playAudioFile(url, volumeopt, loopopt) → {HTMLAudioElement}

Play an mp3, ogg, or wav audio from a local file or url

Parameters:
NameTypeAttributesDefaultDescription
urlString

Location of sound file to play

volumeNumber<optional>
1

How much to scale volume by

loopBoolean<optional>
1

True if the music should loop

Returns:
  • The audio element for this sound
Type: 
HTMLAudioElement

(static) playSamples(sampleChannels, volumeopt, rateopt, panopt, loopopt, sampleRateopt) → {AudioBufferSourceNode}

Play cached audio samples with given settings

Parameters:
NameTypeAttributesDefaultDescription
sampleChannelsArray

Array of arrays of samples to play (for stereo playback)

volumeNumber<optional>
1

How much to scale volume by

rateNumber<optional>
1

The playback rate to use

panNumber<optional>
0

How much to apply stereo panning

loopBoolean<optional>
0

True if the sound should loop when it reaches the end

sampleRateNumber<optional>
44100

Sample rate for the sound

Returns:
  • The audio node of the sound played
Type: 
AudioBufferSourceNode

(static) speak(text, languageopt, volumeopt, rateopt, pitchopt) → {SpeechSynthesisUtterance}

Speak text with passed in settings

Parameters:
NameTypeAttributesDefaultDescription
textString

The text to speak

languageString<optional>

The language/accent to use (examples: en, it, ru, ja, zh)

volumeNumber<optional>
1

How much to scale volume by

rateNumber<optional>
1

How quickly to speak

pitchNumber<optional>
1

How much to change the pitch by

Returns:
  • The utterance that was spoken
Type: 
SpeechSynthesisUtterance

(static) speakStop()

Stop all queued speech

(static) zzfx(…zzfxSound) → {AudioBufferSourceNode}

Generate and play a ZzFX sound

Create sounds using the ZzFX Sound Designer.

Parameters:
NameTypeAttributesDescription
zzfxSoundArray<repeatable>

Array of ZzFX parameters, ex. [.5,.5]

Returns:
  • The audio node of the sound played
Type: 
AudioBufferSourceNode

(static) zzfxG(volumeopt, randomnessopt, frequencyopt, attackopt, sustainopt, releaseopt, shapeopt, shapeCurveopt, slideopt, deltaSlideopt, pitchJumpopt, pitchJumpTimeopt, repeatTimeopt, noiseopt, modulationopt, bitCrushopt, delayopt, sustainVolumeopt, decayopt, tremoloopt) → {Array}

Generate samples for a ZzFX sound

Parameters:
NameTypeAttributesDefaultDescription
volumeNumber<optional>
1

Volume scale (percent)

randomnessNumber<optional>
.05

How much to randomize frequency (percent Hz)

frequencyNumber<optional>
220

Frequency of sound (Hz)

attackNumber<optional>
0

Attack time, how fast sound starts (seconds)

sustainNumber<optional>
0

Sustain time, how long sound holds (seconds)

releaseNumber<optional>
.1

Release time, how fast sound fades out (seconds)

shapeNumber<optional>
0

Shape of the sound wave

shapeCurveNumber<optional>
1

Squarenes of wave (0=square, 1=normal, 2=pointy)

slideNumber<optional>
0

How much to slide frequency (kHz/s)

deltaSlideNumber<optional>
0

How much to change slide (kHz/s/s)

pitchJumpNumber<optional>
0

Frequency of pitch jump (Hz)

pitchJumpTimeNumber<optional>
0

Time of pitch jump (seconds)

repeatTimeNumber<optional>
0

Resets some parameters periodically (seconds)

noiseNumber<optional>
0

How much random noise to add (percent)

modulationNumber<optional>
0

Frequency of modulation wave, negative flips phase (Hz)

bitCrushNumber<optional>
0

Resamples at a lower frequency in (samples*100)

delayNumber<optional>
0

Overlap sound with itself for reverb and flanger effects (seconds)

sustainVolumeNumber<optional>
1

Volume level for sustain (percent)

decayNumber<optional>
0

Decay time, how long to reach sustain after attack (seconds)

tremoloNumber<optional>
0

Trembling effect, rate controlled by repeat time (precent)

Returns:
  • Array of audio samples
Type: 
Array

(static) zzfxM(instruments, patterns, sequence, BPMopt) → {Array}

Generate samples for a ZzFM song with given parameters

Parameters:
NameTypeAttributesDefaultDescription
instrumentsArray

Array of ZzFX sound paramaters

patternsArray

Array of pattern data

sequenceArray

Array of pattern indexes

BPMNumber<optional>
125

Playback speed of the song in BPM

Returns:
  • Left and right channel sample data
Type: 
Array
\ No newline at end of file diff --git a/docs/Color.html b/docs/Color.html index d6039f18..8397a187 100644 --- a/docs/Color.html +++ b/docs/Color.html @@ -1,3 +1,3 @@ Class: Color
On this page

Color

Color object (red, green, blue, alpha) with some helpful functions

Constructor

new Color(ropt, gopt, bopt, aopt)

Create a color with the rgba components passed in, white by default

Parameters:
NameTypeAttributesDefaultDescription
rNumber<optional>
1

red

gNumber<optional>
1

green

bNumber<optional>
1

blue

aNumber<optional>
1

alpha

Example
let a = new Color;              // white
let b = new Color(1, 0, 0);     // red
let c = new Color(0, 0, 0, 0);  // transparent black
let d = RGB(0, 0, 1);           // blue using rgb color
let e = HSL(.3, 1, .5);         // green using hsl color

Members

a

Properties
TypeDescription
Number

Alpha

b

Properties
TypeDescription
Number

Blue

g

Properties
TypeDescription
Number

Green

r

Properties
TypeDescription
Number

Red

Methods

add(c) → {Color}

Returns a copy of this color plus the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

clamp() → {Color}

Returns a copy of this color clamped to the valid range between 0 and 1

Returns:
Type: 
Color

copy() → {Color}

Returns a new color that is a copy of this

Returns:
Type: 
Color

divide(c) → {Color}

Returns a copy of this color divided by the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

getHSLA() → {Array}

Returns this color expressed in hsla format

Returns:
Type: 
Array

lerp(c, percent) → {Color}

Returns a new color that is p percent between this and the color passed in

Parameters:
NameTypeDescription
cColor

other color

percentNumber
Returns:
Type: 
Color

multiply(c) → {Color}

Returns a copy of this color times the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

mutate(amountopt, alphaAmountopt) → {Color}

Returns a new color that has each component randomly adjusted

Parameters:
NameTypeAttributesDefaultDescription
amountNumber<optional>
.05
alphaAmountNumber<optional>
0
Returns:
Type: 
Color

rgbaInt() → {Number}

Returns this color expressed as 32 bit RGBA value

Returns:
Type: 
Number

scale(scale, alphaScaleopt) → {Color}

Returns a copy of this color scaled by the value passed in, alpha can be scaled separately

Parameters:
NameTypeAttributesDefaultDescription
scaleNumber
alphaScaleNumber<optional>
scale
Returns:
Type: 
Color

setHSLA(hopt, sopt, lopt, aopt) → {Color}

Sets this color given a hue, saturation, lightness, and alpha

Parameters:
NameTypeAttributesDefaultDescription
hNumber<optional>
0

hue

sNumber<optional>
0

saturation

lNumber<optional>
1

lightness

aNumber<optional>
1

alpha

Returns:
Type: 
Color

setHex(hex) → {Color}

Set this color from a hex code

Parameters:
NameTypeDescription
hexString

html hex code

Returns:
Type: 
Color

subtract(c) → {Color}

Returns a copy of this color minus the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

toString(useAlphaopt) → {String}

Returns this color expressed as a hex color code

Parameters:
NameTypeAttributesDefaultDescription
useAlphaBoolean<optional>
1

if alpha should be included in result

Returns:
Type: 
String
\ No newline at end of file +
On this page

Color

Color object (red, green, blue, alpha) with some helpful functions

Constructor

new Color(ropt, gopt, bopt, aopt)

Create a color with the rgba components passed in, white by default

Parameters:
NameTypeAttributesDefaultDescription
rNumber<optional>
1

red

gNumber<optional>
1

green

bNumber<optional>
1

blue

aNumber<optional>
1

alpha

Example
let a = new Color;              // white
let b = new Color(1, 0, 0);     // red
let c = new Color(0, 0, 0, 0);  // transparent black
let d = RGB(0, 0, 1);           // blue using rgb color
let e = HSL(.3, 1, .5);         // green using hsl color

Members

a

Properties
TypeDescription
Number

Alpha

b

Properties
TypeDescription
Number

Blue

g

Properties
TypeDescription
Number

Green

r

Properties
TypeDescription
Number

Red

Methods

add(c) → {Color}

Returns a copy of this color plus the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

clamp() → {Color}

Returns a copy of this color clamped to the valid range between 0 and 1

Returns:
Type: 
Color

copy() → {Color}

Returns a new color that is a copy of this

Returns:
Type: 
Color

divide(c) → {Color}

Returns a copy of this color divided by the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

getHSLA() → {Array}

Returns this color expressed in hsla format

Returns:
Type: 
Array

lerp(c, percent) → {Color}

Returns a new color that is p percent between this and the color passed in

Parameters:
NameTypeDescription
cColor

other color

percentNumber
Returns:
Type: 
Color

multiply(c) → {Color}

Returns a copy of this color times the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

mutate(amountopt, alphaAmountopt) → {Color}

Returns a new color that has each component randomly adjusted

Parameters:
NameTypeAttributesDefaultDescription
amountNumber<optional>
.05
alphaAmountNumber<optional>
0
Returns:
Type: 
Color

rgbaInt() → {Number}

Returns this color expressed as 32 bit RGBA value

Returns:
Type: 
Number

scale(scale, alphaScaleopt) → {Color}

Returns a copy of this color scaled by the value passed in, alpha can be scaled separately

Parameters:
NameTypeAttributesDefaultDescription
scaleNumber
alphaScaleNumber<optional>
scale
Returns:
Type: 
Color

setHSLA(hopt, sopt, lopt, aopt) → {Color}

Sets this color given a hue, saturation, lightness, and alpha

Parameters:
NameTypeAttributesDefaultDescription
hNumber<optional>
0

hue

sNumber<optional>
0

saturation

lNumber<optional>
1

lightness

aNumber<optional>
1

alpha

Returns:
Type: 
Color

setHex(hex) → {Color}

Set this color from a hex code

Parameters:
NameTypeDescription
hexString

html hex code

Returns:
Type: 
Color

subtract(c) → {Color}

Returns a copy of this color minus the color passed in

Parameters:
NameTypeDescription
cColor

other color

Returns:
Type: 
Color

toString(useAlphaopt) → {String}

Returns this color expressed as a hex color code

Parameters:
NameTypeAttributesDefaultDescription
useAlphaBoolean<optional>
1

if alpha should be included in result

Returns:
Type: 
String
\ No newline at end of file diff --git a/docs/Debug.html b/docs/Debug.html index bfe59c81..a94e8ba2 100644 --- a/docs/Debug.html +++ b/docs/Debug.html @@ -1,3 +1,3 @@ Namespace: Debug
On this page

Debug

LittleJS Debug System

  • Press Esc to show debug overlay with mouse pick
  • Number keys toggle debug functions
  • +/- apply time scale
  • Debug primitive rendering
  • Save a 2d canvas as a png image

Members

(static, constant) debug :Boolean

True if debug is enabled

Type:
  • Boolean
Default Value
  • 1

(static) debugKey :Boolean

Key code used to toggle debug mode, Esc by default

Type:
  • Boolean
Default Value
  • 27

(static, constant) debugPointSize :Number

Size to render debug points by default

Type:
  • Number
Default Value
  • 0.5

(static, constant) enableAsserts :Boolean

True if asserts are enaled

Type:
  • Boolean
Default Value
  • 1

(static) showWatermark :Boolean

True if watermark with FPS should be shown, false in release builds

Type:
  • Boolean
Default Value
  • 1

Methods

(static) ASSERT(assertion, output)

Asserts if the experssion is false, does not do anything in release builds

Parameters:
NameTypeDescription
assertionBoolean
outputObject

(static) debugAABB(posA, sizeA, posB, sizeB, coloropt)

Draw a debug axis aligned bounding box in world space

Parameters:
NameTypeAttributesDefaultDescription
posAVector2
sizeAVector2
posBVector2
sizeBVector2
colorString<optional>
'#fff'

(static) debugCircle(pos, radiusopt, coloropt, timeopt, fillopt)

Draw a debug circle in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
radiusNumber<optional>
0
colorString<optional>
'#fff'
timeNumber<optional>
0
fillBoolean<optional>
false

(static) debugClear()

Clear all debug primitives in the list

(static) debugLine(posA, posB, coloropt, thicknessopt, timeopt)

Draw a debug line in world space

Parameters:
NameTypeAttributesDefaultDescription
posAVector2
posBVector2
colorString<optional>
'#fff'
thicknessNumber<optional>
.1
timeNumber<optional>
0

(static) debugPoint(pos, coloropt, timeopt, angleopt)

Draw a debug point in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
colorString<optional>
'#fff'
timeNumber<optional>
0
angleNumber<optional>
0

(static) debugRect(pos, sizeopt, coloropt, timeopt, angleopt, fillopt)

Draw a debug rectangle in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2()
colorString<optional>
'#fff'
timeNumber<optional>
0
angleNumber<optional>
0
fillBoolean<optional>
false

(static) debugSaveCanvas(canvas, filenameopt, typeopt)

Save a canvas to disk

Parameters:
NameTypeAttributesDefaultDescription
canvasHTMLCanvasElement
filenameString<optional>
typeString<optional>
'image/png'

(static) debugSaveDataURL(dataURL, filename)

Save a data url to disk

Parameters:
NameTypeDescription
dataURLString
filenameString

(static) debugSaveText(text, filenameopt, typeopt)

Save a text file to disk

Parameters:
NameTypeAttributesDefaultDescription
textString
filenameString<optional>
typeString<optional>
'text/plain'

(static) debugText(text, pos, sizeopt, coloropt, timeopt, angleopt, fontopt)

Draw a debug axis aligned bounding box in world space

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
sizeNumber<optional>
1
colorString<optional>
'#fff'
timeNumber<optional>
0
angleNumber<optional>
0
fontString<optional>
'monospace'

(static) setDebugKey(key)

Set key code used to toggle debug mode, Esc by default

Parameters:
NameTypeDescription
keyNumber

(static) setShowWatermark(show)

Set if watermark with FPS should be shown

Parameters:
NameTypeDescription
showBoolean
\ No newline at end of file +
On this page

Debug

LittleJS Debug System

  • Press Esc to show debug overlay with mouse pick
  • Number keys toggle debug functions
  • +/- apply time scale
  • Debug primitive rendering
  • Save a 2d canvas as a png image

Members

(static, constant) debug :Boolean

True if debug is enabled

Type:
  • Boolean
Default Value
  • 1

(static) debugKey :Boolean

Key code used to toggle debug mode, Esc by default

Type:
  • Boolean
Default Value
  • 27

(static, constant) debugPointSize :Number

Size to render debug points by default

Type:
  • Number
Default Value
  • 0.5

(static, constant) enableAsserts :Boolean

True if asserts are enaled

Type:
  • Boolean
Default Value
  • 1

(static) showWatermark :Boolean

True if watermark with FPS should be shown, false in release builds

Type:
  • Boolean
Default Value
  • 1

Methods

(static) ASSERT(assertion, output)

Asserts if the experssion is false, does not do anything in release builds

Parameters:
NameTypeDescription
assertionBoolean
outputObject

(static) debugAABB(posA, sizeA, posB, sizeB, coloropt)

Draw a debug axis aligned bounding box in world space

Parameters:
NameTypeAttributesDefaultDescription
posAVector2
sizeAVector2
posBVector2
sizeBVector2
colorString<optional>
'#fff'

(static) debugCircle(pos, radiusopt, coloropt, timeopt, fillopt)

Draw a debug circle in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
radiusNumber<optional>
0
colorString<optional>
'#fff'
timeNumber<optional>
0
fillBoolean<optional>
false

(static) debugClear()

Clear all debug primitives in the list

(static) debugLine(posA, posB, coloropt, thicknessopt, timeopt)

Draw a debug line in world space

Parameters:
NameTypeAttributesDefaultDescription
posAVector2
posBVector2
colorString<optional>
'#fff'
thicknessNumber<optional>
.1
timeNumber<optional>
0

(static) debugPoint(pos, coloropt, timeopt, angleopt)

Draw a debug point in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
colorString<optional>
'#fff'
timeNumber<optional>
0
angleNumber<optional>
0

(static) debugRect(pos, sizeopt, coloropt, timeopt, angleopt, fillopt)

Draw a debug rectangle in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2()
colorString<optional>
'#fff'
timeNumber<optional>
0
angleNumber<optional>
0
fillBoolean<optional>
false

(static) debugSaveCanvas(canvas, filenameopt, typeopt)

Save a canvas to disk

Parameters:
NameTypeAttributesDefaultDescription
canvasHTMLCanvasElement
filenameString<optional>
typeString<optional>
'image/png'

(static) debugSaveDataURL(dataURL, filename)

Save a data url to disk

Parameters:
NameTypeDescription
dataURLString
filenameString

(static) debugSaveText(text, filenameopt, typeopt)

Save a text file to disk

Parameters:
NameTypeAttributesDefaultDescription
textString
filenameString<optional>
typeString<optional>
'text/plain'

(static) debugText(text, pos, sizeopt, coloropt, timeopt, angleopt, fontopt)

Draw a debug axis aligned bounding box in world space

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
sizeNumber<optional>
1
colorString<optional>
'#fff'
timeNumber<optional>
0
angleNumber<optional>
0
fontString<optional>
'monospace'

(static) setDebugKey(key)

Set key code used to toggle debug mode, Esc by default

Parameters:
NameTypeDescription
keyNumber

(static) setShowWatermark(show)

Set if watermark with FPS should be shown

Parameters:
NameTypeDescription
showBoolean
\ No newline at end of file diff --git a/docs/Draw.html b/docs/Draw.html index 15877456..41766eaa 100644 --- a/docs/Draw.html +++ b/docs/Draw.html @@ -1,3 +1,3 @@ Namespace: Draw
On this page

Draw

LittleJS Drawing System

  • Hybrid system with both Canvas2D and WebGL available
  • Super fast tile sheet rendering with WebGL
  • Can apply rotation, mirror, color and additive color
  • Font rendering system with built in engine font
  • Many useful utility functions

LittleJS uses a hybrid rendering solution with the best of both Canvas2D and WebGL. There are 3 canvas/contexts available to draw to... mainCanvas - 2D background canvas, non WebGL stuff like tile layers are drawn here. glCanvas - Used by the accelerated WebGL batch rendering system. overlayCanvas - Another 2D canvas that appears on top of the other 2 canvases.

The WebGL rendering system is very fast with some caveats...

  • Switching blend modes (additive) or textures causes another draw call which is expensive in excess
  • Group additive rendering together using renderOrder to mitigate this issue

The LittleJS rendering solution is intentionally simple, feel free to adjust it for your needs!

Members

(static) mainCanvas :HTMLCanvasElement

The primary 2D canvas visible to the user

Type:
  • HTMLCanvasElement

(static) mainCanvasSize :Vector2

The size of the main canvas (and other secondary canvases)

Type:

(static) mainContext :CanvasRenderingContext2D

2d context for mainCanvas

Type:
  • CanvasRenderingContext2D

(static) overlayCanvas :HTMLCanvasElement

A canvas that appears on top of everything the same size as mainCanvas

Type:
  • HTMLCanvasElement

(static) overlayContext :CanvasRenderingContext2D

2d context for overlayCanvas

Type:
  • CanvasRenderingContext2D

(static, constant) tileImage :CanvasImageSource

Tile sheet for batch rendering system

Type:
  • CanvasImageSource

Methods

(static) drawCanvas2D(pos, size, angle, mirror, drawFunction, contextopt, screenSpaceopt)

Draw directly to a 2d canvas context in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2
angleNumber
mirrorBoolean
drawFunctionfunction
contextCanvasRenderingContext2D<optional>
mainContext
screenSpaceBoolean<optional>
0

(static) drawLine(posA, posB, thicknessopt, coloropt, useWebGLopt, screenSpaceopt)

Draw colored line between two points

Parameters:
NameTypeAttributesDefaultDescription
posAVector2
posBVector2
thicknessNumber<optional>
.1
colorColor<optional>
Color()
useWebGLBoolean<optional>
glEnable
screenSpaceBoolean<optional>
0

(static) drawPoly(points, coloropt, useWebGLopt, screenSpaceopt)

Draw colored polygon using passed in points

Parameters:
NameTypeAttributesDefaultDescription
pointsArray

Array of Vector2 points

colorColor<optional>
Color()
useWebGLBoolean<optional>
glEnable
screenSpaceBoolean<optional>
0

(static) drawRect(pos, sizeopt, coloropt, angleopt, useWebGLopt, screenSpaceopt)

Draw colored rect centered on pos

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
colorColor<optional>
Color()
angleNumber<optional>
0
useWebGLBoolean<optional>
glEnable
screenSpaceBoolean<optional>
0

(static) drawText(text, pos, sizeopt, coloropt, lineWidthopt, lineColoropt, textAlignopt, fontopt, contextopt)

Draw text on overlay canvas in world space Automatically splits new lines into rows

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
sizeNumber<optional>
1
colorColor<optional>
Color()
lineWidthNumber<optional>
0
lineColorColor<optional>
Color(0,0,0)
textAlignString<optional>
'center'
fontString<optional>
fontDefault
contextCanvasRenderingContext2D<optional>
overlayContext

(static) drawTextScreen(text, pos, sizeopt, coloropt, lineWidthopt, lineColoropt, textAlignopt, fontopt, contextopt)

Draw text on overlay canvas in screen space Automatically splits new lines into rows

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
sizeNumber<optional>
1
colorColor<optional>
Color()
lineWidthNumber<optional>
0
lineColorColor<optional>
Color(0,0,0)
textAlignString<optional>
'center'
fontString<optional>
fontDefault
contextCanvasRenderingContext2D<optional>
overlayContext

(static) drawTile(pos, sizeopt, tileIndexopt, tileSizeopt, coloropt, angleopt, mirroropt, additiveColoropt, useWebGLopt, screenSpaceopt)

Draw textured tile centered in world space, with color applied if using WebGL

Parameters:
NameTypeAttributesDefaultDescription
posVector2

Center of the tile in world space

sizeVector2<optional>
Vector2(1,1)

Size of the tile in world space

tileIndexNumber<optional>
-1

Tile index to use, negative is untextured

tileSizeVector2<optional>
tileSizeDefault

Tile size in source pixels

colorColor<optional>
Color()

Color to modulate with

angleNumber<optional>
0

Angle to rotate by

mirrorBoolean<optional>
0

If true image is flipped along the Y axis

additiveColorColor<optional>
Color(0,0,0,0)

Additive color to be applied

useWebGLBoolean<optional>
glEnable

Use accelerated WebGL rendering

screenSpaceBoolean<optional>
0

If true the pos and size are in screen space

(static) isFullscreen() → {Boolean}

Returns true if fullscreen mode is active

Returns:
Type: 
Boolean

(static) screenToWorld(screenPos) → {Vector2}

Convert from screen to world space coordinates

Parameters:
NameTypeDescription
screenPosVector2
Returns:
Type: 
Vector2

(static) setBlendMode(additiveopt, useWebGLopt)

Enable normal or additive blend mode

Parameters:
NameTypeAttributesDefaultDescription
additiveBoolean<optional>
0
useWebGLBoolean<optional>
glEnable

(static) toggleFullscreen()

Toggle fullsceen mode

(static) worldToScreen(worldPos) → {Vector2}

Convert from world to screen space coordinates

Parameters:
NameTypeDescription
worldPosVector2
Returns:
Type: 
Vector2
\ No newline at end of file +
On this page

Draw

LittleJS Drawing System

  • Hybrid system with both Canvas2D and WebGL available
  • Super fast tile sheet rendering with WebGL
  • Can apply rotation, mirror, color and additive color
  • Font rendering system with built in engine font
  • Many useful utility functions

LittleJS uses a hybrid rendering solution with the best of both Canvas2D and WebGL. There are 3 canvas/contexts available to draw to... mainCanvas - 2D background canvas, non WebGL stuff like tile layers are drawn here. glCanvas - Used by the accelerated WebGL batch rendering system. overlayCanvas - Another 2D canvas that appears on top of the other 2 canvases.

The WebGL rendering system is very fast with some caveats...

  • Switching blend modes (additive) or textures causes another draw call which is expensive in excess
  • Group additive rendering together using renderOrder to mitigate this issue

The LittleJS rendering solution is intentionally simple, feel free to adjust it for your needs!

Members

(static) mainCanvas :HTMLCanvasElement

The primary 2D canvas visible to the user

Type:
  • HTMLCanvasElement

(static) mainCanvasSize :Vector2

The size of the main canvas (and other secondary canvases)

Type:

(static) mainContext :CanvasRenderingContext2D

2d context for mainCanvas

Type:
  • CanvasRenderingContext2D

(static) overlayCanvas :HTMLCanvasElement

A canvas that appears on top of everything the same size as mainCanvas

Type:
  • HTMLCanvasElement

(static) overlayContext :CanvasRenderingContext2D

2d context for overlayCanvas

Type:
  • CanvasRenderingContext2D

(static, constant) tileImage :CanvasImageSource

Tile sheet for batch rendering system

Type:
  • CanvasImageSource

Methods

(static) drawCanvas2D(pos, size, angle, mirror, drawFunction, contextopt, screenSpaceopt)

Draw directly to a 2d canvas context in world space

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2
angleNumber
mirrorBoolean
drawFunctionfunction
contextCanvasRenderingContext2D<optional>
mainContext
screenSpaceBoolean<optional>
0

(static) drawLine(posA, posB, thicknessopt, coloropt, useWebGLopt, screenSpaceopt)

Draw colored line between two points

Parameters:
NameTypeAttributesDefaultDescription
posAVector2
posBVector2
thicknessNumber<optional>
.1
colorColor<optional>
Color()
useWebGLBoolean<optional>
glEnable
screenSpaceBoolean<optional>
0

(static) drawPoly(points, coloropt, useWebGLopt, screenSpaceopt)

Draw colored polygon using passed in points

Parameters:
NameTypeAttributesDefaultDescription
pointsArray

Array of Vector2 points

colorColor<optional>
Color()
useWebGLBoolean<optional>
glEnable
screenSpaceBoolean<optional>
0

(static) drawRect(pos, sizeopt, coloropt, angleopt, useWebGLopt, screenSpaceopt)

Draw colored rect centered on pos

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
colorColor<optional>
Color()
angleNumber<optional>
0
useWebGLBoolean<optional>
glEnable
screenSpaceBoolean<optional>
0

(static) drawText(text, pos, sizeopt, coloropt, lineWidthopt, lineColoropt, textAlignopt, fontopt, contextopt)

Draw text on overlay canvas in world space Automatically splits new lines into rows

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
sizeNumber<optional>
1
colorColor<optional>
Color()
lineWidthNumber<optional>
0
lineColorColor<optional>
Color(0,0,0)
textAlignString<optional>
'center'
fontString<optional>
fontDefault
contextCanvasRenderingContext2D<optional>
overlayContext

(static) drawTextScreen(text, pos, sizeopt, coloropt, lineWidthopt, lineColoropt, textAlignopt, fontopt, contextopt)

Draw text on overlay canvas in screen space Automatically splits new lines into rows

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
sizeNumber<optional>
1
colorColor<optional>
Color()
lineWidthNumber<optional>
0
lineColorColor<optional>
Color(0,0,0)
textAlignString<optional>
'center'
fontString<optional>
fontDefault
contextCanvasRenderingContext2D<optional>
overlayContext

(static) drawTile(pos, sizeopt, tileIndexopt, tileSizeopt, coloropt, angleopt, mirroropt, additiveColoropt, useWebGLopt, screenSpaceopt)

Draw textured tile centered in world space, with color applied if using WebGL

Parameters:
NameTypeAttributesDefaultDescription
posVector2

Center of the tile in world space

sizeVector2<optional>
Vector2(1,1)

Size of the tile in world space

tileIndexNumber<optional>
-1

Tile index to use, negative is untextured

tileSizeVector2<optional>
tileSizeDefault

Tile size in source pixels

colorColor<optional>
Color()

Color to modulate with

angleNumber<optional>
0

Angle to rotate by

mirrorBoolean<optional>
0

If true image is flipped along the Y axis

additiveColorColor<optional>
Color(0,0,0,0)

Additive color to be applied

useWebGLBoolean<optional>
glEnable

Use accelerated WebGL rendering

screenSpaceBoolean<optional>
0

If true the pos and size are in screen space

(static) isFullscreen() → {Boolean}

Returns true if fullscreen mode is active

Returns:
Type: 
Boolean

(static) screenToWorld(screenPos) → {Vector2}

Convert from screen to world space coordinates

Parameters:
NameTypeDescription
screenPosVector2
Returns:
Type: 
Vector2

(static) setBlendMode(additiveopt, useWebGLopt)

Enable normal or additive blend mode

Parameters:
NameTypeAttributesDefaultDescription
additiveBoolean<optional>
0
useWebGLBoolean<optional>
glEnable

(static) toggleFullscreen()

Toggle fullsceen mode

(static) worldToScreen(worldPos) → {Vector2}

Convert from world to screen space coordinates

Parameters:
NameTypeDescription
worldPosVector2
Returns:
Type: 
Vector2
\ No newline at end of file diff --git a/docs/Engine.html b/docs/Engine.html index eb5fe310..8e235106 100644 --- a/docs/Engine.html +++ b/docs/Engine.html @@ -1,3 +1,3 @@ Namespace: Engine
On this page

Engine

LittleJS - The Tiny JavaScript Game Engine That Can! MIT License - Copyright 2021 Frank Force

Engine Features

  • Object oriented system with base class engine object
  • Base class object handles update, physics, collision, rendering, etc
  • Engine helper classes and functions like Vector2, Color, and Timer
  • Super fast rendering system for tile sheets
  • Sound effects audio with zzfx and music with zzfxm
  • Input processing system with gamepad and touchscreen support
  • Tile layer rendering and collision system
  • Particle effect system
  • Medal system tracks and displays achievements
  • Debug tools and debug rendering system
  • Post processing effects
  • Call engineInit() to start it up!

Members

(static, constant) engineName :String

Name of engine

Type:
  • String
Default Value
  • LittleJS

(static) engineObjects :Array

Array containing all engine objects

Type:
  • Array

(static) engineObjectsCollide :Array

Array containing only objects that are set to collide with other objects this frame (for optimization)

Type:
  • Array

(static, constant) engineVersion :String

Version of engine

Type:
  • String
Default Value
  • 1.7.12

(static) frame :Number

Current update frame, used to calculate time

Type:
  • Number

(static, constant) frameRate :Number

Frames per second to update objects

Type:
  • Number
Default Value
  • 60

(static) paused :Boolean

Is the game paused? Causes time and objects to not be updated

Type:
  • Boolean
Default Value
  • 0

(static) time :Number

Current engine time since start in seconds, derived from frame

Type:
  • Number

(static, constant) timeDelta :Number

How many seconds each frame lasts, engine uses a fixed time step

Type:
  • Number
Default Value
  • 1/60

(static) timeReal :Number

Actual clock time since start in seconds (not affected by pause or frame rate clamping)

Type:
  • Number

Methods

(static) engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, tileImageSourceopt)

Start up LittleJS engine with your callback functions

Parameters:
NameTypeAttributesDescription
gameInitfunction

Called once after the engine starts up, setup the game

gameUpdatefunction

Called every frame at 60 frames per second, handle input and update the game state

gameUpdatePostfunction

Called after physics and objects are updated, setup camera and prepare for render

gameRenderfunction

Called before objects are rendered, draw any background effects that appear behind objects

gameRenderPostfunction

Called after objects are rendered, draw effects or hud that appear above all objects

tileImageSourceString<optional>

Tile image to use, everything starts when the image is finished loading

(static) engineObjectsCallback(posopt, sizeopt, callbackFunctionopt, objectsopt)

Triggers a callback for each object within a given area

Parameters:
NameTypeAttributesDefaultDescription
posVector2<optional>

Center of test area

sizeNumber<optional>

Radius of circle if float, rectangle size if Vector2

callbackFunctionfunction<optional>

Calls this function on every object that passes the test

objectsArray<optional>
engineObjects

List of objects to check

(static) engineObjectsDestroy()

Destroy and remove all objects

(static) engineObjectsUpdate()

Update each engine object, remove destroyed objects, and update time

(static) setPaused(paused)

Set if game is paused

Parameters:
NameTypeDescription
pausedBoolean
\ No newline at end of file +
On this page

Engine

LittleJS - The Tiny JavaScript Game Engine That Can! MIT License - Copyright 2021 Frank Force

Engine Features

  • Object oriented system with base class engine object
  • Base class object handles update, physics, collision, rendering, etc
  • Engine helper classes and functions like Vector2, Color, and Timer
  • Super fast rendering system for tile sheets
  • Sound effects audio with zzfx and music with zzfxm
  • Input processing system with gamepad and touchscreen support
  • Tile layer rendering and collision system
  • Particle effect system
  • Medal system tracks and displays achievements
  • Debug tools and debug rendering system
  • Post processing effects
  • Call engineInit() to start it up!

Members

(static, constant) engineName :String

Name of engine

Type:
  • String
Default Value
  • LittleJS

(static) engineObjects :Array

Array containing all engine objects

Type:
  • Array

(static) engineObjectsCollide :Array

Array containing only objects that are set to collide with other objects this frame (for optimization)

Type:
  • Array

(static, constant) engineVersion :String

Version of engine

Type:
  • String
Default Value
  • 1.7.21

(static) frame :Number

Current update frame, used to calculate time

Type:
  • Number

(static, constant) frameRate :Number

Frames per second to update objects

Type:
  • Number
Default Value
  • 60

(static) paused :Boolean

Is the game paused? Causes time and objects to not be updated

Type:
  • Boolean
Default Value
  • 0

(static) time :Number

Current engine time since start in seconds, derived from frame

Type:
  • Number

(static, constant) timeDelta :Number

How many seconds each frame lasts, engine uses a fixed time step

Type:
  • Number
Default Value
  • 1/60

(static) timeReal :Number

Actual clock time since start in seconds (not affected by pause or frame rate clamping)

Type:
  • Number

Methods

(static) engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, tileImageSourceopt)

Start up LittleJS engine with your callback functions

Parameters:
NameTypeAttributesDescription
gameInitfunction

Called once after the engine starts up, setup the game

gameUpdatefunction

Called every frame at 60 frames per second, handle input and update the game state

gameUpdatePostfunction

Called after physics and objects are updated, setup camera and prepare for render

gameRenderfunction

Called before objects are rendered, draw any background effects that appear behind objects

gameRenderPostfunction

Called after objects are rendered, draw effects or hud that appear above all objects

tileImageSourceString<optional>

Tile image to use, everything starts when the image is finished loading

(static) engineObjectsCallback(posopt, sizeopt, callbackFunctionopt, objectsopt)

Triggers a callback for each object within a given area

Parameters:
NameTypeAttributesDefaultDescription
posVector2<optional>

Center of test area

sizeNumber<optional>

Radius of circle if float, rectangle size if Vector2

callbackFunctionfunction<optional>

Calls this function on every object that passes the test

objectsArray<optional>
engineObjects

List of objects to check

(static) engineObjectsDestroy()

Destroy and remove all objects

(static) engineObjectsUpdate()

Update each engine object, remove destroyed objects, and update time

(static) setPaused(paused)

Set if game is paused

Parameters:
NameTypeDescription
pausedBoolean
\ No newline at end of file diff --git a/docs/EngineObject.html b/docs/EngineObject.html index 67ae16a4..3e010760 100644 --- a/docs/EngineObject.html +++ b/docs/EngineObject.html @@ -1,3 +1,3 @@ Class: EngineObject
On this page

EngineObject

LittleJS Object Base Object Class

  • Top level object class used by the engine
  • Automatically adds self to object list
  • Will be updated and rendered each frame
  • Renders as a sprite from a tilesheet by default
  • Can have color and addtive color applied
  • 2D Physics and collision system
  • Sorted by renderOrder
  • Objects can have children attached
  • Parents are updated before children, and set child transform
  • Call destroy() to get rid of objects

The physics system used by objects is simple and fast with some caveats...

  • Collision uses the axis aligned size, the object's rotation angle is only for rendering
  • Objects are guaranteed to not intersect tile collision from physics
  • If an object starts or is moved inside tile collision, it will not collide with that tile
  • Collision for objects can be set to be solid to block other objects
  • Objects may get pushed into overlapping other solid objects, if so they will push away
  • Solid objects are more performance intensive and should be used sparingly

Constructor

new EngineObject(positionopt, sizeopt, tileIndexopt, tileSizeopt, angleopt, coloropt, renderOrderopt)

Create an engine object and adds it to the list of objects

Parameters:
NameTypeAttributesDefaultDescription
positionVector2<optional>
Vector2()

World space position of the object

sizeVector2<optional>
Vector2(1,1)

World space size of the object

tileIndexNumber<optional>
-1

Tile to use to render object (-1 is untextured)

tileSizeVector2<optional>
tileSizeDefault

Size of tile in source pixels

angleNumber<optional>
0

Angle the object is rotated by

colorColor<optional>
Color()

Color to apply to tile when rendered

renderOrderNumber<optional>
0

Objects sorted by renderOrder before being rendered

Example
// create an engine object, normally you would first extend the class with your own
const pos = vec2(2,3);
const object = new EngineObject(pos); 

Members

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
NameTypeAttributesDefaultDescription
angleDampingNumber<optional>
objectDefaultAngleDamping

How much to slow down rotation each frame (0-1)

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

color

Properties
TypeDescription
Color

Color to apply when rendered

damping

Properties
NameTypeAttributesDefaultDescription
dampingNumber<optional>
objectDefaultDamping

How much to slow down velocity each frame (0-1)

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
NameTypeAttributesDefaultDescription
gravityScaleNumber<optional>
1

How much to scale gravity by for this object

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

pos

Properties
TypeDescription
Vector2

World space position of the object

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

size

Properties
TypeDescription
Vector2

World space width and height of the object

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the object transform and physics, called automatically by engine once each frame

\ No newline at end of file +
On this page

EngineObject

LittleJS Object Base Object Class

  • Top level object class used by the engine
  • Automatically adds self to object list
  • Will be updated and rendered each frame
  • Renders as a sprite from a tilesheet by default
  • Can have color and addtive color applied
  • 2D Physics and collision system
  • Sorted by renderOrder
  • Objects can have children attached
  • Parents are updated before children, and set child transform
  • Call destroy() to get rid of objects

The physics system used by objects is simple and fast with some caveats...

  • Collision uses the axis aligned size, the object's rotation angle is only for rendering
  • Objects are guaranteed to not intersect tile collision from physics
  • If an object starts or is moved inside tile collision, it will not collide with that tile
  • Collision for objects can be set to be solid to block other objects
  • Objects may get pushed into overlapping other solid objects, if so they will push away
  • Solid objects are more performance intensive and should be used sparingly

Constructor

new EngineObject(positionopt, sizeopt, tileIndexopt, tileSizeopt, angleopt, coloropt, renderOrderopt)

Create an engine object and adds it to the list of objects

Parameters:
NameTypeAttributesDefaultDescription
positionVector2<optional>
Vector2()

World space position of the object

sizeVector2<optional>
Vector2(1,1)

World space size of the object

tileIndexNumber<optional>
-1

Tile to use to render object (-1 is untextured)

tileSizeVector2<optional>
tileSizeDefault

Size of tile in source pixels

angleNumber<optional>
0

Angle the object is rotated by

colorColor<optional>
Color()

Color to apply to tile when rendered

renderOrderNumber<optional>
0

Objects sorted by renderOrder before being rendered

Example
// create an engine object, normally you would first extend the class with your own
const pos = vec2(2,3);
const object = new EngineObject(pos); 

Members

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
NameTypeAttributesDefaultDescription
angleDampingNumber<optional>
objectDefaultAngleDamping

How much to slow down rotation each frame (0-1)

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

color

Properties
TypeDescription
Color

Color to apply when rendered

damping

Properties
NameTypeAttributesDefaultDescription
dampingNumber<optional>
objectDefaultDamping

How much to slow down velocity each frame (0-1)

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
NameTypeAttributesDefaultDescription
gravityScaleNumber<optional>
1

How much to scale gravity by for this object

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

pos

Properties
TypeDescription
Vector2

World space position of the object

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

size

Properties
TypeDescription
Vector2

World space width and height of the object

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the object transform and physics, called automatically by engine once each frame

\ No newline at end of file diff --git a/docs/FontImage.html b/docs/FontImage.html index ca217a3d..6e5100e8 100644 --- a/docs/FontImage.html +++ b/docs/FontImage.html @@ -1,3 +1,3 @@ Class: FontImage
On this page

FontImage

Font Image Object - Draw text on a 2D canvas by using characters in an image

  • 96 characters (from space to tilde) are stored in an image
  • Uses a default 8x8 font if none is supplied
  • You can also use fonts from the main tile sheet

Constructor

new FontImage(imageopt, tileSizeopt, paddingSizeopt, startTileIndexopt, contextopt)

Create an image font

Parameters:
NameTypeAttributesDefaultDescription
imageHTMLImageElement<optional>

Image for the font, if undefined default font is used

tileSizeVector2<optional>
vec2(8)

Size of the font source tiles

paddingSizeVector2<optional>
vec2(0,1)

How much extra space to add between characters

startTileIndexNumber<optional>
0

Tile index in image where font starts

contextCanvasRenderingContext2D<optional>
overlayContext

context to draw to

Example
// use built in font
const font = new ImageFont;

// draw text
font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));

Methods

drawText(text, pos, scaleopt, centeropt)

Draw text in world space using the image font

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
scaleNumber<optional>
.25
centerBoolean<optional>

drawTextScreen(text, pos, scaleopt, centeropt)

Draw text in screen space using the image font

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
scaleNumber<optional>
4
centerBoolean<optional>
\ No newline at end of file +
On this page

FontImage

Font Image Object - Draw text on a 2D canvas by using characters in an image

  • 96 characters (from space to tilde) are stored in an image
  • Uses a default 8x8 font if none is supplied
  • You can also use fonts from the main tile sheet

Constructor

new FontImage(imageopt, tileSizeopt, paddingSizeopt, startTileIndexopt, contextopt)

Create an image font

Parameters:
NameTypeAttributesDefaultDescription
imageHTMLImageElement<optional>

Image for the font, if undefined default font is used

tileSizeVector2<optional>
vec2(8)

Size of the font source tiles

paddingSizeVector2<optional>
vec2(0,1)

How much extra space to add between characters

startTileIndexNumber<optional>
0

Tile index in image where font starts

contextCanvasRenderingContext2D<optional>
overlayContext

context to draw to

Example
// use built in font
const font = new ImageFont;

// draw text
font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));

Methods

drawText(text, pos, scaleopt, centeropt)

Draw text in world space using the image font

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
scaleNumber<optional>
.25
centerBoolean<optional>

drawTextScreen(text, pos, scaleopt, centeropt)

Draw text in screen space using the image font

Parameters:
NameTypeAttributesDefaultDescription
textString
posVector2
scaleNumber<optional>
4
centerBoolean<optional>
\ No newline at end of file diff --git a/docs/Input.html b/docs/Input.html index 65db6bc8..4baba75d 100644 --- a/docs/Input.html +++ b/docs/Input.html @@ -1,3 +1,3 @@ Namespace: Input
On this page

Input

LittleJS Input System

  • Tracks keyboard down, pressed, and released
  • Tracks mouse buttons, position, and wheel
  • Tracks multiple analog gamepads
  • Virtual gamepad for touch devices

Members

(static, constant) isTouchDevice

True if a touch device has been detected

(static) isUsingGamepad :Boolean

Returns true if user is using gamepad (has more recently pressed a gamepad button)

Type:
  • Boolean

(static) mousePos :Vector2

Mouse pos in world space

Type:

(static) mousePosScreen :Vector2

Mouse pos in screen space

Type:

(static) mouseWheel :Number

Mouse wheel delta this frame

Type:
  • Number

(static) preventDefaultInput :Boolean

Prevents input continuing to the default browser handling (false by default)

Type:
  • Boolean

Methods

(static) clearInput()

Clears all input

(static) gamepadIsDown(button, gamepadopt) → {Boolean}

Returns true if gamepad button is down

Parameters:
NameTypeAttributesDefaultDescription
buttonNumber
gamepadNumber<optional>
0
Returns:
Type: 
Boolean

(static) gamepadStick(stick, gamepadopt) → {Vector2}

Returns gamepad stick value

Parameters:
NameTypeAttributesDefaultDescription
stickNumber
gamepadNumber<optional>
0
Returns:
Type: 
Vector2

(static) gamepadWasPressed(button, gamepadopt) → {Boolean}

Returns true if gamepad button was pressed

Parameters:
NameTypeAttributesDefaultDescription
buttonNumber
gamepadNumber<optional>
0
Returns:
Type: 
Boolean

(static) gamepadWasReleased(button, gamepadopt) → {Boolean}

Returns true if gamepad button was released

Parameters:
NameTypeAttributesDefaultDescription
buttonNumber
gamepadNumber<optional>
0
Returns:
Type: 
Boolean

(static) keyIsDown(key, deviceopt) → {Boolean}

Returns true if device key is down

Parameters:
NameTypeAttributesDefaultDescription
keyNumber
deviceNumber<optional>
0
Returns:
Type: 
Boolean

(static) keyWasPressed(key, deviceopt) → {Boolean}

Returns true if device key was pressed this frame

Parameters:
NameTypeAttributesDefaultDescription
keyNumber
deviceNumber<optional>
0
Returns:
Type: 
Boolean

(static) keyWasReleased(key, deviceopt) → {Boolean}

Returns true if device key was released this frame

Parameters:
NameTypeAttributesDefaultDescription
keyNumber
deviceNumber<optional>
0
Returns:
Type: 
Boolean

(static) mouseIsDown(button) → {Boolean}

Returns true if mouse button is down

Parameters:
NameTypeDescription
buttonNumber
Returns:
Type: 
Boolean

(static) mouseWasPressed(button) → {Boolean}

Returns true if mouse button was pressed

Parameters:
NameTypeDescription
buttonNumber
Returns:
Type: 
Boolean

(static) mouseWasReleased(button) → {Boolean}

Returns true if mouse button was released

Parameters:
NameTypeDescription
buttonNumber
Returns:
Type: 
Boolean

(static) vibrate(patternopt)

Pulse the vibration hardware if it exists

Parameters:
NameTypeAttributesDefaultDescription
patternNumber<optional>
100

a single value in miliseconds or vibration interval array

(static) vibrateStop()

Cancel any ongoing vibration

\ No newline at end of file +
On this page

Input

LittleJS Input System

  • Tracks keyboard down, pressed, and released
  • Tracks mouse buttons, position, and wheel
  • Tracks multiple analog gamepads
  • Virtual gamepad for touch devices

Members

(static, constant) isTouchDevice

True if a touch device has been detected

(static) isUsingGamepad :Boolean

Returns true if user is using gamepad (has more recently pressed a gamepad button)

Type:
  • Boolean

(static) mousePos :Vector2

Mouse pos in world space

Type:

(static) mousePosScreen :Vector2

Mouse pos in screen space

Type:

(static) mouseWheel :Number

Mouse wheel delta this frame

Type:
  • Number

(static) preventDefaultInput :Boolean

Prevents input continuing to the default browser handling (false by default)

Type:
  • Boolean

Methods

(static) clearInput()

Clears all input

(static) gamepadIsDown(button, gamepadopt) → {Boolean}

Returns true if gamepad button is down

Parameters:
NameTypeAttributesDefaultDescription
buttonNumber
gamepadNumber<optional>
0
Returns:
Type: 
Boolean

(static) gamepadStick(stick, gamepadopt) → {Vector2}

Returns gamepad stick value

Parameters:
NameTypeAttributesDefaultDescription
stickNumber
gamepadNumber<optional>
0
Returns:
Type: 
Vector2

(static) gamepadWasPressed(button, gamepadopt) → {Boolean}

Returns true if gamepad button was pressed

Parameters:
NameTypeAttributesDefaultDescription
buttonNumber
gamepadNumber<optional>
0
Returns:
Type: 
Boolean

(static) gamepadWasReleased(button, gamepadopt) → {Boolean}

Returns true if gamepad button was released

Parameters:
NameTypeAttributesDefaultDescription
buttonNumber
gamepadNumber<optional>
0
Returns:
Type: 
Boolean

(static) keyIsDown(key, deviceopt) → {Boolean}

Returns true if device key is down

Parameters:
NameTypeAttributesDefaultDescription
keyNumber
deviceNumber<optional>
0
Returns:
Type: 
Boolean

(static) keyWasPressed(key, deviceopt) → {Boolean}

Returns true if device key was pressed this frame

Parameters:
NameTypeAttributesDefaultDescription
keyNumber
deviceNumber<optional>
0
Returns:
Type: 
Boolean

(static) keyWasReleased(key, deviceopt) → {Boolean}

Returns true if device key was released this frame

Parameters:
NameTypeAttributesDefaultDescription
keyNumber
deviceNumber<optional>
0
Returns:
Type: 
Boolean

(static) mouseIsDown(button) → {Boolean}

Returns true if mouse button is down

Parameters:
NameTypeDescription
buttonNumber
Returns:
Type: 
Boolean

(static) mouseWasPressed(button) → {Boolean}

Returns true if mouse button was pressed

Parameters:
NameTypeDescription
buttonNumber
Returns:
Type: 
Boolean

(static) mouseWasReleased(button) → {Boolean}

Returns true if mouse button was released

Parameters:
NameTypeDescription
buttonNumber
Returns:
Type: 
Boolean

(static) vibrate(patternopt)

Pulse the vibration hardware if it exists

Parameters:
NameTypeAttributesDefaultDescription
patternNumber<optional>
100

a single value in miliseconds or vibration interval array

(static) vibrateStop()

Cancel any ongoing vibration

\ No newline at end of file diff --git a/docs/Medal.html b/docs/Medal.html index 3fbfa1b5..470dd44d 100644 --- a/docs/Medal.html +++ b/docs/Medal.html @@ -1,3 +1,3 @@ Class: Medal
On this page

Medal

Medal Object - Tracks an unlockable medal

Constructor

new Medal(id, name, descriptionopt, iconopt, srcopt)

Create an medal object and adds it to the list of medals

Parameters:
NameTypeAttributesDefaultDescription
idNumber

The unique identifier of the medal

nameString

Name of the medal

descriptionString<optional>

Description of the medal

iconString<optional>
'🏆'

Icon for the medal

srcString<optional>

Image location for the medal

Example
// create a medal
const medal_example = new Medal(0, 'Example Medal', 'More info about the medal goes here.', '🎖️');

// initialize medals
medalsInit('Example Game');

// unlock the medal
medal_example.unlock();

Methods

render(hidePercentopt)

Render a medal

Parameters:
NameTypeAttributesDefaultDescription
hidePercentNumber<optional>
0

How much to slide the medal off screen

renderIcon(x, y, sizeopt)

Render the icon for a medal

Parameters:
NameTypeAttributesDefaultDescription
xNumber

Screen space X position

yNumber

Screen space Y position

sizeNumber<optional>
medalDisplayIconSize

Screen space size

unlock()

Unlocks a medal if not already unlocked

\ No newline at end of file +
On this page

Medal

Medal Object - Tracks an unlockable medal

Constructor

new Medal(id, name, descriptionopt, iconopt, srcopt)

Create an medal object and adds it to the list of medals

Parameters:
NameTypeAttributesDefaultDescription
idNumber

The unique identifier of the medal

nameString

Name of the medal

descriptionString<optional>

Description of the medal

iconString<optional>
'🏆'

Icon for the medal

srcString<optional>

Image location for the medal

Example
// create a medal
const medal_example = new Medal(0, 'Example Medal', 'More info about the medal goes here.', '🎖️');

// initialize medals
medalsInit('Example Game');

// unlock the medal
medal_example.unlock();

Methods

render(hidePercentopt)

Render a medal

Parameters:
NameTypeAttributesDefaultDescription
hidePercentNumber<optional>
0

How much to slide the medal off screen

renderIcon(x, y, sizeopt)

Render the icon for a medal

Parameters:
NameTypeAttributesDefaultDescription
xNumber

Screen space X position

yNumber

Screen space Y position

sizeNumber<optional>
medalDisplayIconSize

Screen space size

unlock()

Unlocks a medal if not already unlocked

\ No newline at end of file diff --git a/docs/Medals.html b/docs/Medals.html index 837a6304..74630636 100644 --- a/docs/Medals.html +++ b/docs/Medals.html @@ -1,3 +1,3 @@ Namespace: Medals
On this page

Medals

LittleJS Medal System

  • Tracks and displays medals
  • Saves medals to local storage
  • Newgrounds integration

Members

(static, constant) medals :Array

List of all medals

Type:
  • Array

Methods

(static) medalsInit(saveName)

Initialize medals with a save name used for storage

  • Call this after creating all medals
  • Checks if medals are unlocked
Parameters:
NameTypeDescription
saveNameString

(static) newgroundsInit(app_id, cipheropt)

This can used to enable Newgrounds functionality

Parameters:
NameTypeAttributesDescription
app_idNumber

The newgrounds App ID

cipherString<optional>

The encryption Key (AES-128/Base64)

\ No newline at end of file +
On this page

Medals

LittleJS Medal System

  • Tracks and displays medals
  • Saves medals to local storage
  • Newgrounds integration

Members

(static, constant) medals :Array

List of all medals

Type:
  • Array

Methods

(static) medalsInit(saveName)

Initialize medals with a save name used for storage

  • Call this after creating all medals
  • Checks if medals are unlocked
Parameters:
NameTypeDescription
saveNameString

(static) newgroundsInit(app_id, cipheropt)

This can used to enable Newgrounds functionality

Parameters:
NameTypeAttributesDescription
app_idNumber

The newgrounds App ID

cipherString<optional>

The encryption Key (AES-128/Base64)

\ No newline at end of file diff --git a/docs/Music.html b/docs/Music.html index daa17ecb..6da75e20 100644 --- a/docs/Music.html +++ b/docs/Music.html @@ -1,3 +1,3 @@ Class: Music
On this page

Music

Music Object - Stores a zzfx music track for later use

Create music with the ZzFXM tracker.

Constructor

new Music(zzfxMusic)

Create a music object and cache the zzfx music samples for later use

Parameters:
NameTypeDescription
zzfxMusicArray

Array of zzfx music parameters

Example
// create some music
const music_example = new Music(
[
    [                         // instruments
      [,0,400]                // simple note
    ], 
    [                         // patterns
        [                     // pattern 1
            [                 // channel 0
                0, -1,        // instrument 0, left speaker
                1, 0, 9, 1    // channel notes
            ], 
            [                 // channel 1
                0, 1,         // instrument 1, right speaker
                0, 12, 17, -1 // channel notes
            ]
        ],
    ],
    [0, 0, 0, 0], // sequence, play pattern 0 four times
    90            // BPM
]);

// play the music
music_example.play();

Methods

isPlaying() → {Boolean}

Check if music is playing

Returns:
Type: 
Boolean

play(volumeopt, loopopt) → {AudioBufferSourceNode}

Play the music

Parameters:
NameTypeAttributesDefaultDescription
volumeNumber<optional>
1

How much to scale volume by

loopBoolean<optional>
1

True if the music should loop when it reaches the end

Returns:
  • The audio node, can be used to stop sound later
Type: 
AudioBufferSourceNode

stop()

Stop the music

\ No newline at end of file +
On this page

Music

Music Object - Stores a zzfx music track for later use

Create music with the ZzFXM tracker.

Constructor

new Music(zzfxMusic)

Create a music object and cache the zzfx music samples for later use

Parameters:
NameTypeDescription
zzfxMusicArray

Array of zzfx music parameters

Example
// create some music
const music_example = new Music(
[
    [                         // instruments
      [,0,400]                // simple note
    ], 
    [                         // patterns
        [                     // pattern 1
            [                 // channel 0
                0, -1,        // instrument 0, left speaker
                1, 0, 9, 1    // channel notes
            ], 
            [                 // channel 1
                0, 1,         // instrument 1, right speaker
                0, 12, 17, -1 // channel notes
            ]
        ],
    ],
    [0, 0, 0, 0], // sequence, play pattern 0 four times
    90            // BPM
]);

// play the music
music_example.play();

Methods

play(volumeopt, loopopt) → {AudioBufferSourceNode}

Play the music

Parameters:
NameTypeAttributesDefaultDescription
volumeNumber<optional>
1

How much to scale volume by

loopBoolean<optional>
1

True if the music should loop

Returns:
  • The audio source node
Type: 
AudioBufferSourceNode
\ No newline at end of file diff --git a/docs/Newgrounds.html b/docs/Newgrounds.html index 1ddf65b3..befefcf5 100644 --- a/docs/Newgrounds.html +++ b/docs/Newgrounds.html @@ -1,3 +1,3 @@ Class: Newgrounds
On this page

Newgrounds

Newgrounds API wrapper object

Constructor

new Newgrounds(app_id, cipheropt)

Create a newgrounds object

Parameters:
NameTypeAttributesDescription
app_idNumber

The newgrounds App ID

cipherString<optional>

The encryption Key (AES-128/Base64)

Example
// create a newgrounds object, replace the app id and cipher with your own
const app_id = '53123:1ZuSTQ9l';
const cipher = 'enF0vGH@Mj/FRASKL23Q==';
newgrounds = new Newgrounds(app_id, cipher);

Methods

call(component, parametersopt, asyncopt) → {Object}

Send a message to call a component of the Newgrounds API

Parameters:
NameTypeAttributesDefaultDescription
componentString

Name of the component

parametersObject<optional>
0

Parameters to use for call

asyncBoolean<optional>
0

If true, don't wait for response before continuing (avoid stall)

Returns:
  • The response JSON object
Type: 
Object

getScores(id, useropt, socialopt, skipopt, limitopt) → {Object}

Get scores from a scoreboard

Parameters:
NameTypeAttributesDefaultDescription
idNumber

The scoreboard id

userString<optional>
0

A user's id or name

socialNumber<optional>
0

If true, only social scores will be loaded

skipNumber<optional>
0

Number of scores to skip before start

limitNumber<optional>
10

Number of scores to include in the list

Returns:
  • The response JSON object
Type: 
Object

logView()

Send message to log a view

postScore(id, value)

Send message to post score

Parameters:
NameTypeDescription
idNumber

The scoreboard id

valueNumber

The score value

unlockMedal(id)

Send message to unlock a medal by id

Parameters:
NameTypeDescription
idNumber

The medal id

\ No newline at end of file +
On this page

Newgrounds

Newgrounds API wrapper object

Constructor

new Newgrounds(app_id, cipheropt)

Create a newgrounds object

Parameters:
NameTypeAttributesDescription
app_idNumber

The newgrounds App ID

cipherString<optional>

The encryption Key (AES-128/Base64)

Example
// create a newgrounds object, replace the app id and cipher with your own
const app_id = '53123:1ZuSTQ9l';
const cipher = 'enF0vGH@Mj/FRASKL23Q==';
newgrounds = new Newgrounds(app_id, cipher);

Methods

call(component, parametersopt, asyncopt) → {Object}

Send a message to call a component of the Newgrounds API

Parameters:
NameTypeAttributesDefaultDescription
componentString

Name of the component

parametersObject<optional>
0

Parameters to use for call

asyncBoolean<optional>
0

If true, don't wait for response before continuing (avoid stall)

Returns:
  • The response JSON object
Type: 
Object

getScores(id, useropt, socialopt, skipopt, limitopt) → {Object}

Get scores from a scoreboard

Parameters:
NameTypeAttributesDefaultDescription
idNumber

The scoreboard id

userString<optional>
0

A user's id or name

socialNumber<optional>
0

If true, only social scores will be loaded

skipNumber<optional>
0

Number of scores to skip before start

limitNumber<optional>
10

Number of scores to include in the list

Returns:
  • The response JSON object
Type: 
Object

logView()

Send message to log a view

postScore(id, value)

Send message to post score

Parameters:
NameTypeDescription
idNumber

The scoreboard id

valueNumber

The score value

unlockMedal(id)

Send message to unlock a medal by id

Parameters:
NameTypeDescription
idNumber

The medal id

\ No newline at end of file diff --git a/docs/Particle.html b/docs/Particle.html index 723f87c5..af82c16f 100644 --- a/docs/Particle.html +++ b/docs/Particle.html @@ -1,3 +1,3 @@ Class: Particle
On this page

Particle

Particle Object - Created automatically by Particle Emitters

Constructor

new Particle(position, tileIndexopt, tileSizeopt, angleopt)

Create a particle with the given settings

Parameters:
NameTypeAttributesDefaultDescription
positionVector2

World space position of the particle

tileIndexNumber<optional>
-1

Tile to use to render, untextured if -1

tileSizeVector2<optional>
tileSizeDefault

Size of tile in source pixels

angleNumber<optional>
0

Angle to rotate the particle

Extends

Members

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
NameTypeAttributesDefaultDescription
angleDampingNumber<optional>
objectDefaultAngleDamping

How much to slow down rotation each frame (0-1)

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

color

Properties
TypeDescription
Color

Color to apply when rendered

damping

Properties
NameTypeAttributesDefaultDescription
dampingNumber<optional>
objectDefaultDamping

How much to slow down velocity each frame (0-1)

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
NameTypeAttributesDefaultDescription
gravityScaleNumber<optional>
1

How much to scale gravity by for this object

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

pos

Properties
TypeDescription
Vector2

World space position of the object

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

size

Properties
TypeDescription
Vector2

World space width and height of the object

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the particle, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the object transform and physics, called automatically by engine once each frame

\ No newline at end of file +
On this page

Particle

Particle Object - Created automatically by Particle Emitters

Constructor

new Particle(position, tileIndexopt, tileSizeopt, angleopt)

Create a particle with the given settings

Parameters:
NameTypeAttributesDefaultDescription
positionVector2

World space position of the particle

tileIndexNumber<optional>
-1

Tile to use to render, untextured if -1

tileSizeVector2<optional>
tileSizeDefault

Size of tile in source pixels

angleNumber<optional>
0

Angle to rotate the particle

Extends

Members

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
NameTypeAttributesDefaultDescription
angleDampingNumber<optional>
objectDefaultAngleDamping

How much to slow down rotation each frame (0-1)

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

color

Properties
TypeDescription
Color

Color to apply when rendered

damping

Properties
NameTypeAttributesDefaultDescription
dampingNumber<optional>
objectDefaultDamping

How much to slow down velocity each frame (0-1)

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
NameTypeAttributesDefaultDescription
gravityScaleNumber<optional>
1

How much to scale gravity by for this object

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

pos

Properties
TypeDescription
Vector2

World space position of the object

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

size

Properties
TypeDescription
Vector2

World space width and height of the object

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the particle, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the object transform and physics, called automatically by engine once each frame

\ No newline at end of file diff --git a/docs/ParticleEmitter.html b/docs/ParticleEmitter.html index 98932532..39171f74 100644 --- a/docs/ParticleEmitter.html +++ b/docs/ParticleEmitter.html @@ -1,3 +1,3 @@ Class: ParticleEmitter
On this page

ParticleEmitter

Particle Emitter - Spawns particles with the given settings

Constructor

new ParticleEmitter(position, angleopt, emitSizeopt, emitTimeopt, emitRateopt, emitConeAngleopt, tileIndexopt, tileSizeopt, colorStartAopt, colorStartBopt, colorEndAopt, colorEndBopt, particleTimeopt, sizeStartopt, sizeEndopt, speedopt, angleSpeedopt, dampingopt, angleDampingopt, gravityScaleopt, particleConeAngleopt, fadeRateopt, randomnessopt, collideTilesopt, additiveopt, randomColorLinearopt, renderOrderopt, localSpaceopt)

Create a particle system with the given settings

Parameters:
NameTypeAttributesDefaultDescription
positionVector2

World space position of the emitter

angleNumber<optional>
0

Angle to emit the particles

emitSizeNumber<optional>
0

World space size of the emitter (float for circle diameter, vec2 for rect)

emitTimeNumber<optional>
0

How long to stay alive (0 is forever)

emitRateNumber<optional>
100

How many particles per second to spawn, does not emit if 0

emitConeAngleNumber<optional>
PI

Local angle to apply velocity to particles from emitter

tileIndexNumber<optional>
-1

Index into tile sheet, if <0 no texture is applied

tileSizeVector2<optional>
tileSizeDefault

Tile size for particles

colorStartAColor<optional>
Color()

Color at start of life 1, randomized between start colors

colorStartBColor<optional>
Color()

Color at start of life 2, randomized between start colors

colorEndAColor<optional>
Color(1,1,1,0)

Color at end of life 1, randomized between end colors

colorEndBColor<optional>
Color(1,1,1,0)

Color at end of life 2, randomized between end colors

particleTimeNumber<optional>
.5

How long particles live

sizeStartNumber<optional>
.1

How big are particles at start

sizeEndNumber<optional>
1

How big are particles at end

speedNumber<optional>
.1

How fast are particles when spawned

angleSpeedNumber<optional>
.05

How fast are particles rotating

dampingNumber<optional>
1

How much to dampen particle speed

angleDampingNumber<optional>
1

How much to dampen particle angular speed

gravityScaleNumber<optional>
0

How much does gravity effect particles

particleConeAngleNumber<optional>
PI

Cone for start particle angle

fadeRateNumber<optional>
.1

How quick to fade in particles at start/end in percent of life

randomnessNumber<optional>
.2

Apply extra randomness percent

collideTilesBoolean<optional>
0

Do particles collide against tiles

additiveBoolean<optional>
0

Should particles use addtive blend

randomColorLinearBoolean<optional>
1

Should color be randomized linearly or across each component

renderOrderNumber<optional>
0

Render order for particles (additive is above other stuff by default)

localSpaceBoolean<optional>
0

Should it be in local space of emitter (world space is default)

Example
// create a particle emitter
let pos = vec2(2,3);
let particleEmiter = new ParticleEmitter
(
    pos, 0, 1, 0, 500, PI,  // pos, angle, emitSize, emitTime, emitRate, emiteCone
    0, vec2(16),                            // tileIndex, tileSize
    new Color(1,1,1),   new Color(0,0,0),   // colorStartA, colorStartB
    new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
    2, .2, .2, .1, .05,  // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
    .99, 1, 1, PI, .05,  // damping, angleDamping, gravityScale, particleCone, fadeRate, 
    .5, 1                // randomness, collide, additive, randomColorLinear, renderOrder
);

Extends

Members

additive

Properties
TypeDescription
Number

Should particles use addtive blend

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
TypeDescription
Number

How much to dampen particle angular speed

angleSpeed

Properties
TypeDescription
Number

How fast are particles rotating

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

collideTiles

Properties
TypeDescription
Number

Do particles collide against tiles

color

Properties
TypeDescription
Color

Color to apply when rendered

colorEndA

Properties
TypeDescription
Color

Color at end of life 1, randomized between end colors

colorEndB

Properties
TypeDescription
Color

Color at end of life 2, randomized between end colors

colorStartA

Properties
TypeDescription
Color

Color at start of life 1, randomized between start colors

colorStartB

Properties
TypeDescription
Color

Color at start of life 2, randomized between start colors

damping

Properties
TypeDescription
Number

How much to dampen particle speed

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

emitConeAngle

Properties
TypeDescription
Number

Local angle to apply velocity to particles from emitter

emitRate

Properties
TypeDescription
Number

How many particles per second to spawn, does not emit if 0

emitSize

Properties
TypeDescription
Number

World space size of the emitter (float for circle diameter, vec2 for rect)

emitTime

Properties
TypeDescription
Number

How long to stay alive (0 is forever)

fadeRate

Properties
TypeDescription
Number

How quick to fade in particles at start/end in percent of life

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
TypeDescription
Number

How much does gravity effect particles

localSpace

Properties
TypeDescription
Boolean

Should it be in local space of emitter

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

particleConeAngle

Properties
TypeDescription
Number

Cone for start particle angle

particleTime

Properties
TypeDescription
Number

How long particles live

pos

Properties
TypeDescription
Vector2

World space position of the object

randomColorLinear

Properties
TypeDescription
Boolean

Should color be randomized linearly or across each component

randomness

Properties
TypeDescription
Number

Apply extra randomness percent

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

size

Properties
TypeDescription
Vector2

World space width and height of the object

sizeEnd

Properties
TypeDescription
Number

How big are particles at end

sizeStart

Properties
TypeDescription
Number

How big are particles at start

speed

Properties
TypeDescription
Number

How fast are particles when spawned

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

trailScale

Properties
TypeDescription
Number

If set the partile is drawn as a trail, stretched in the drection of velocity

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

emitParticle() → {Particle}

Spawn one particle

Returns:
Type: 
Particle

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the emitter to spawn particles, called automatically by engine once each frame

\ No newline at end of file +
On this page

ParticleEmitter

Particle Emitter - Spawns particles with the given settings

Constructor

new ParticleEmitter(position, angleopt, emitSizeopt, emitTimeopt, emitRateopt, emitConeAngleopt, tileIndexopt, tileSizeopt, colorStartAopt, colorStartBopt, colorEndAopt, colorEndBopt, particleTimeopt, sizeStartopt, sizeEndopt, speedopt, angleSpeedopt, dampingopt, angleDampingopt, gravityScaleopt, particleConeAngleopt, fadeRateopt, randomnessopt, collideTilesopt, additiveopt, randomColorLinearopt, renderOrderopt, localSpaceopt)

Create a particle system with the given settings

Parameters:
NameTypeAttributesDefaultDescription
positionVector2

World space position of the emitter

angleNumber<optional>
0

Angle to emit the particles

emitSizeNumber<optional>
0

World space size of the emitter (float for circle diameter, vec2 for rect)

emitTimeNumber<optional>
0

How long to stay alive (0 is forever)

emitRateNumber<optional>
100

How many particles per second to spawn, does not emit if 0

emitConeAngleNumber<optional>
PI

Local angle to apply velocity to particles from emitter

tileIndexNumber<optional>
-1

Index into tile sheet, if <0 no texture is applied

tileSizeVector2<optional>
tileSizeDefault

Tile size for particles

colorStartAColor<optional>
Color()

Color at start of life 1, randomized between start colors

colorStartBColor<optional>
Color()

Color at start of life 2, randomized between start colors

colorEndAColor<optional>
Color(1,1,1,0)

Color at end of life 1, randomized between end colors

colorEndBColor<optional>
Color(1,1,1,0)

Color at end of life 2, randomized between end colors

particleTimeNumber<optional>
.5

How long particles live

sizeStartNumber<optional>
.1

How big are particles at start

sizeEndNumber<optional>
1

How big are particles at end

speedNumber<optional>
.1

How fast are particles when spawned

angleSpeedNumber<optional>
.05

How fast are particles rotating

dampingNumber<optional>
1

How much to dampen particle speed

angleDampingNumber<optional>
1

How much to dampen particle angular speed

gravityScaleNumber<optional>
0

How much does gravity effect particles

particleConeAngleNumber<optional>
PI

Cone for start particle angle

fadeRateNumber<optional>
.1

How quick to fade in particles at start/end in percent of life

randomnessNumber<optional>
.2

Apply extra randomness percent

collideTilesBoolean<optional>
0

Do particles collide against tiles

additiveBoolean<optional>
0

Should particles use addtive blend

randomColorLinearBoolean<optional>
1

Should color be randomized linearly or across each component

renderOrderNumber<optional>
0

Render order for particles (additive is above other stuff by default)

localSpaceBoolean<optional>
0

Should it be in local space of emitter (world space is default)

Example
// create a particle emitter
let pos = vec2(2,3);
let particleEmiter = new ParticleEmitter
(
    pos, 0, 1, 0, 500, PI,  // pos, angle, emitSize, emitTime, emitRate, emiteCone
    0, vec2(16),                            // tileIndex, tileSize
    new Color(1,1,1),   new Color(0,0,0),   // colorStartA, colorStartB
    new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
    2, .2, .2, .1, .05,  // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
    .99, 1, 1, PI, .05,  // damping, angleDamping, gravityScale, particleCone, fadeRate, 
    .5, 1                // randomness, collide, additive, randomColorLinear, renderOrder
);

Extends

Members

additive

Properties
TypeDescription
Number

Should particles use addtive blend

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
TypeDescription
Number

How much to dampen particle angular speed

angleSpeed

Properties
TypeDescription
Number

How fast are particles rotating

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

collideTiles

Properties
TypeDescription
Number

Do particles collide against tiles

color

Properties
TypeDescription
Color

Color to apply when rendered

colorEndA

Properties
TypeDescription
Color

Color at end of life 1, randomized between end colors

colorEndB

Properties
TypeDescription
Color

Color at end of life 2, randomized between end colors

colorStartA

Properties
TypeDescription
Color

Color at start of life 1, randomized between start colors

colorStartB

Properties
TypeDescription
Color

Color at start of life 2, randomized between start colors

damping

Properties
TypeDescription
Number

How much to dampen particle speed

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

emitConeAngle

Properties
TypeDescription
Number

Local angle to apply velocity to particles from emitter

emitRate

Properties
TypeDescription
Number

How many particles per second to spawn, does not emit if 0

emitSize

Properties
TypeDescription
Number

World space size of the emitter (float for circle diameter, vec2 for rect)

emitTime

Properties
TypeDescription
Number

How long to stay alive (0 is forever)

fadeRate

Properties
TypeDescription
Number

How quick to fade in particles at start/end in percent of life

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
TypeDescription
Number

How much does gravity effect particles

localSpace

Properties
TypeDescription
Boolean

Should it be in local space of emitter

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

particleConeAngle

Properties
TypeDescription
Number

Cone for start particle angle

particleTime

Properties
TypeDescription
Number

How long particles live

pos

Properties
TypeDescription
Vector2

World space position of the object

randomColorLinear

Properties
TypeDescription
Boolean

Should color be randomized linearly or across each component

randomness

Properties
TypeDescription
Number

Apply extra randomness percent

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

size

Properties
TypeDescription
Vector2

World space width and height of the object

sizeEnd

Properties
TypeDescription
Number

How big are particles at end

sizeStart

Properties
TypeDescription
Number

How big are particles at start

speed

Properties
TypeDescription
Number

How fast are particles when spawned

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

trailScale

Properties
TypeDescription
Number

If set the partile is drawn as a trail, stretched in the drection of velocity

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

emitParticle() → {Particle}

Spawn one particle

Returns:
Type: 
Particle

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the emitter to spawn particles, called automatically by engine once each frame

\ No newline at end of file diff --git a/docs/Random.html b/docs/Random.html index 3bc51af0..ca59d0af 100644 --- a/docs/Random.html +++ b/docs/Random.html @@ -1,3 +1,3 @@ Namespace: Random
On this page

Random

Random global functions

Methods

(static) rand(valueAopt, valueBopt) → {Number}

Returns a random value between the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber<optional>
1
valueBNumber<optional>
0
Returns:
Type: 
Number

(static) randColor(colorAopt, colorBopt, linearopt) → {Color}

Returns a random color between the two passed in colors, combine components if linear

Parameters:
NameTypeAttributesDefaultDescription
colorAColor<optional>
Color()
colorBColor<optional>
Color(0,0,0,1)
linearBoolean<optional>
Returns:
Type: 
Color

(static) randInCircle(radiusopt, minRadiusopt) → {Vector2}

Returns a random Vector2 within a circular shape

Parameters:
NameTypeAttributesDefaultDescription
radiusNumber<optional>
1
minRadiusNumber<optional>
0
Returns:
Type: 
Vector2

(static) randInt(valueA, valueBopt) → {Number}

Returns a floored random value the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber
valueBNumber<optional>
0
Returns:
Type: 
Number

(static) randSign() → {Number}

Randomly returns either -1 or 1

Returns:
Type: 
Number

(static) randVector(lengthopt) → {Vector2}

Returns a random Vector2 with the passed in length

Parameters:
NameTypeAttributesDefaultDescription
lengthNumber<optional>
1
Returns:
Type: 
Vector2
\ No newline at end of file +
On this page

Random

Random global functions

Methods

(static) rand(valueAopt, valueBopt) → {Number}

Returns a random value between the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber<optional>
1
valueBNumber<optional>
0
Returns:
Type: 
Number

(static) randColor(colorAopt, colorBopt, linearopt) → {Color}

Returns a random color between the two passed in colors, combine components if linear

Parameters:
NameTypeAttributesDefaultDescription
colorAColor<optional>
Color()
colorBColor<optional>
Color(0,0,0,1)
linearBoolean<optional>
Returns:
Type: 
Color

(static) randInCircle(radiusopt, minRadiusopt) → {Vector2}

Returns a random Vector2 within a circular shape

Parameters:
NameTypeAttributesDefaultDescription
radiusNumber<optional>
1
minRadiusNumber<optional>
0
Returns:
Type: 
Vector2

(static) randInt(valueA, valueBopt) → {Number}

Returns a floored random value the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber
valueBNumber<optional>
0
Returns:
Type: 
Number

(static) randSign() → {Number}

Randomly returns either -1 or 1

Returns:
Type: 
Number

(static) randVector(lengthopt) → {Vector2}

Returns a random Vector2 with the passed in length

Parameters:
NameTypeAttributesDefaultDescription
lengthNumber<optional>
1
Returns:
Type: 
Vector2
\ No newline at end of file diff --git a/docs/RandomGenerator.html b/docs/RandomGenerator.html index 3715c73a..e157e37b 100644 --- a/docs/RandomGenerator.html +++ b/docs/RandomGenerator.html @@ -1,3 +1,3 @@ Class: RandomGenerator
On this page

RandomGenerator

Seeded random number generator

  • Can be used to create a deterministic random number sequence

Constructor

new RandomGenerator(seed)

Create a random number generator with the seed passed in

Parameters:
NameTypeDescription
seedNumber

Starting seed

Example
let r = new RandomGenerator(123); // random number generator with seed 123
let a = r.rand();                 // random value between 0 and 1
let b = r.randInt(10);            // random integer between 0 and 9
r.seed = 123;                     // reset the seed
let c = r.rand();                 // the same value as a

Members

seed

Properties
TypeDescription
Number

random seed

Methods

float(valueAopt, valueBopt) → {Number}

Returns a seeded random value between the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber<optional>
1
valueBNumber<optional>
0
Returns:
Type: 
Number

int(valueA, valueBopt) → {Number}

Returns a floored seeded random value the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber
valueBNumber<optional>
0
Returns:
Type: 
Number

sign() → {Number}

Randomly returns either -1 or 1 deterministically

Returns:
Type: 
Number
\ No newline at end of file +
On this page

RandomGenerator

Seeded random number generator

  • Can be used to create a deterministic random number sequence

Constructor

new RandomGenerator(seed)

Create a random number generator with the seed passed in

Parameters:
NameTypeDescription
seedNumber

Starting seed

Example
let r = new RandomGenerator(123); // random number generator with seed 123
let a = r.rand();                 // random value between 0 and 1
let b = r.randInt(10);            // random integer between 0 and 9
r.seed = 123;                     // reset the seed
let c = r.rand();                 // the same value as a

Members

seed

Properties
TypeDescription
Number

random seed

Methods

float(valueAopt, valueBopt) → {Number}

Returns a seeded random value between the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber<optional>
1
valueBNumber<optional>
0
Returns:
Type: 
Number

int(valueA, valueBopt) → {Number}

Returns a floored seeded random value the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber
valueBNumber<optional>
0
Returns:
Type: 
Number

sign() → {Number}

Randomly returns either -1 or 1 deterministically

Returns:
Type: 
Number
\ No newline at end of file diff --git a/docs/Settings.html b/docs/Settings.html index 2f16d7e4..e1bd37f5 100644 --- a/docs/Settings.html +++ b/docs/Settings.html @@ -1,3 +1,3 @@ Namespace: Settings
On this page

Settings

LittleJS Engine Settings

  • All settings for the engine are here

Members

(static) cameraPos :Vector2

Position of camera in world space

Type:
Default Value
  • Vector2()

(static) cameraScale :Number

Scale of camera in world space

Type:
  • Number
Default Value
  • 32

(static) canvasFixedSize :Vector2

Fixed size of the canvas, if enabled canvas size never changes

  • you may also need to set mainCanvasSize if using screen space coords in startup
Type:
Default Value
  • Vector2()

(static) canvasMaxSize :Vector2

The max size of the canvas, centered if window is larger

Type:
Default Value
  • Vector2(1920,1200)

(static) canvasPixelated :Boolean

Disables filtering for crisper pixel art if true

Type:
  • Boolean
Default Value
  • 1

(static) enablePhysicsSolver :Boolean

Enable physics solver for collisions between objects

Type:
  • Boolean
Default Value
  • 1

(static) fontDefault :String

Default font used for text rendering

Type:
  • String
Default Value
  • arial

(static) gamepadDirectionEmulateStick :Boolean

If true, the dpad input is also routed to the left analog stick (for better accessability)

Type:
  • Boolean
Default Value
  • 1

(static) gamepadsEnable :Boolean

Should gamepads be allowed

Type:
  • Boolean
Default Value
  • 1

(static) glEnable :Boolean

Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)

Type:
  • Boolean
Default Value
  • 1

(static) glOverlay :Boolean

Fixes slow rendering in some browsers by not compositing the WebGL canvas

Type:
  • Boolean
Default Value
  • 1

(static) gravity :Number

How much gravity to apply to objects along the Y axis, negative is down

Type:
  • Number
Default Value
  • 0

(static) inputWASDEmulateDirection :Boolean

If true the WASD keys are also routed to the direction keys (for better accessability)

Type:
  • Boolean
Default Value
  • 1

(static) medalDisplayIconSize :Number

Size of icon in medal display

Type:
  • Number
Default Value
  • 50

(static) medalDisplaySize :Vector2

Size of medal display

Type:
Default Value
  • Vector2(640,80)

(static) medalDisplaySlideTime :Number

How quickly to slide on/off medals in seconds

Type:
  • Number
Default Value
  • 0.5

(static) medalDisplayTime :Number

How long to show medals for in seconds

Type:
  • Number
Default Value
  • 5

(static) medalsPreventUnlock :Boolean

Set to stop medals from being unlockable (like if cheats are enabled)

Type:
  • Boolean
Default Value
  • 0

(static) objectDefaultAngleDamping :Number

How much to slow angular velocity each frame (0-1)

Type:
  • Number
Default Value
  • 1

(static) objectDefaultDamping :Number

How much to slow velocity by each frame (0-1)

Type:
  • Number
Default Value
  • 1

(static) objectDefaultElasticity :Number

How much to bounce when a collision occurs (0-1)

Type:
  • Number
Default Value
  • 0

(static) objectDefaultFriction :Number

How much to slow when touching (0-1)

Type:
  • Number
Default Value
  • 0.8

(static) objectDefaultMass :Number

Default object mass for collison calcuations (how heavy objects are)

Type:
  • Number
Default Value
  • 1

(static) objectMaxSpeed :Number

Clamp max speed to avoid fast objects missing collisions

Type:
  • Number
Default Value
  • 1

(static) particleEmitRateScale :Number

Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)

Type:
  • Number
Default Value
  • 1

(static) soundDefaultRange :Number

Default range where sound no longer plays

Type:
  • Number
Default Value
  • 40

(static) soundDefaultTaper :Number

Default range percent to start tapering off sound (0-1)

Type:
  • Number
Default Value
  • 0.7

(static) soundEnable :Boolean

All audio code can be disabled and removed from build

Type:
  • Boolean
Default Value
  • 1

(static) soundVolume :Number

Volume scale to apply to all sound, music and speech

Type:
  • Number
Default Value
  • 0.5

(static) tileFixBleedScale :Number

Prevent tile bleeding from neighbors in pixels

Type:
  • Number
Default Value
  • 0.3

(static) tileSizeDefault :Vector2

Default size of tiles in pixels

Type:
Default Value
  • Vector2(16,16)

(static) touchGamepadAlpha :Number

Transparency of touch gamepad overlay

Type:
  • Number
Default Value
  • 0.3

(static) touchGamepadAnalog :Boolean

True if touch gamepad should be analog stick or false to use if 8 way dpad

Type:
  • Boolean
Default Value
  • 1

(static) touchGamepadEnable :Boolean

True if touch gamepad should appear on mobile devices

  • Supports left analog stick, 4 face buttons and start button (button 9)
  • Must be set by end of gameInit to be activated
Type:
  • Boolean
Default Value
  • 0

(static) touchGamepadSize :Number

Size of virutal gamepad for touch devices in pixels

Type:
  • Number
Default Value
  • 99

(static) vibrateEnable :Boolean

Allow vibration hardware if it exists

Type:
  • Boolean
Default Value
  • 1

Methods

(static) setCameraPos(pos)

Set position of camera in world space

Parameters:
NameTypeDescription
posVector2

(static) setCameraScale(scale)

Set scale of camera in world space

Parameters:
NameTypeDescription
scaleNumber

(static) setCanvasFixedSize(size)

Set fixed size of the canvas

Parameters:
NameTypeDescription
sizeVector2

(static) setCanvasMaxSize(size)

Set max size of the canvas

Parameters:
NameTypeDescription
sizeVector2

(static) setCanvasPixelated(pixelated)

Disables anti aliasing for pixel art if true

Parameters:
NameTypeDescription
pixelatedBoolean

(static) setEnablePhysicsSolver(enable)

Set if collisions between objects are enabled

Parameters:
NameTypeDescription
enableBoolean

(static) setFontDefault(font)

Set default font used for text rendering

Parameters:
NameTypeDescription
fontString

(static) setGamepadDirectionEmulateStick(enable)

Set if the dpad input is also routed to the left analog stick

Parameters:
NameTypeDescription
enableBoolean

(static) setGamepadsEnable(enable)

Set if gamepads are enabled

Parameters:
NameTypeDescription
enableBoolean

(static) setGlEnable(enable)

Set if webgl rendering is enabled

Parameters:
NameTypeDescription
enableBoolean

(static) setGlOverlay(overlay)

Set to not composite the WebGL canvas

Parameters:
NameTypeDescription
overlayBoolean

(static) setGravity(gravity)

Set how much gravity to apply to objects along the Y axis

Parameters:
NameTypeDescription
gravityNumber

(static) setInputWASDEmulateDirection(enable)

Set if true the WASD keys are also routed to the direction keys

Parameters:
NameTypeDescription
enableBoolean

(static) setMedalDisplayIconSize(size)

Set size of icon in medal display

Parameters:
NameTypeDescription
sizeNumber

(static) setMedalDisplaySize(size)

Set size of medal display

Parameters:
NameTypeDescription
sizeVector2

(static) setMedalDisplaySlideTime(time)

Set how quickly to slide on/off medals in seconds

Parameters:
NameTypeDescription
timeNumber

(static) setMedalDisplayTime(time)

Set how long to show medals for in seconds

Parameters:
NameTypeDescription
timeNumber

(static) setMedalsPreventUnlock(preventUnlock)

Set to stop medals from being unlockable

Parameters:
NameTypeDescription
preventUnlockBoolean

(static) setObjectDefaultAngleDamping(damping)

Set how much to slow angular velocity each frame

Parameters:
NameTypeDescription
dampingNumber

(static) setObjectDefaultDamping(damping)

Set how much to slow velocity by each frame

Parameters:
NameTypeDescription
dampingNumber

(static) setObjectDefaultElasticity(elasticity)

Set how much to bounce when a collision occur

Parameters:
NameTypeDescription
elasticityNumber

(static) setObjectDefaultFriction(friction)

Set how much to slow when touching

Parameters:
NameTypeDescription
frictionNumber

(static) setObjectDefaultMass(mass)

Set default object mass for collison calcuations

Parameters:
NameTypeDescription
massNumber

(static) setObjectMaxSpeed(speed)

Set max speed to avoid fast objects missing collisions

Parameters:
NameTypeDescription
speedNumber

(static) setParticleEmitRateScale(scale)

Set to scales emit rate of particles

Parameters:
NameTypeDescription
scaleNumber

(static) setSoundDefaultRange(range)

Set default range where sound no longer plays

Parameters:
NameTypeDescription
rangeNumber

(static) setSoundDefaultTaper(taper)

Set default range percent to start tapering off sound

Parameters:
NameTypeDescription
taperNumber

(static) setSoundEnable(enable)

Set to disable all audio code

Parameters:
NameTypeDescription
enableBoolean

(static) setSoundVolume(volume)

Set volume scale to apply to all sound, music and speech

Parameters:
NameTypeDescription
volumeNumber

(static) setTileFixBleedScale(scale)

Set to prevent tile bleeding from neighbors in pixels

Parameters:
NameTypeDescription
scaleNumber

(static) setTileSizeDefault(size)

Set default size of tiles in pixels

Parameters:
NameTypeDescription
sizeVector2

(static) setTouchGamepadAlpha(alpha)

Set transparency of touch gamepad overlay

Parameters:
NameTypeDescription
alphaNumber

(static) setTouchGamepadAnalog(analog)

Set if touch gamepad should be analog stick or 8 way dpad

Parameters:
NameTypeDescription
analogBoolean

(static) setTouchGamepadEnable(enable)

Set if touch gamepad should appear on mobile devices

Parameters:
NameTypeDescription
enableBoolean

(static) setTouchGamepadSize(size)

Set size of virutal gamepad for touch devices in pixels

Parameters:
NameTypeDescription
sizeNumber

(static) setVibrateEnable(enable)

Set to allow vibration hardware if it exists

Parameters:
NameTypeDescription
enableBoolean
\ No newline at end of file +
On this page

Settings

LittleJS Engine Settings

  • All settings for the engine are here

Members

(static) cameraPos :Vector2

Position of camera in world space

Type:
Default Value
  • Vector2()

(static) cameraScale :Number

Scale of camera in world space

Type:
  • Number
Default Value
  • 32

(static) canvasFixedSize :Vector2

Fixed size of the canvas, if enabled canvas size never changes

  • you may also need to set mainCanvasSize if using screen space coords in startup
Type:
Default Value
  • Vector2()

(static) canvasMaxSize :Vector2

The max size of the canvas, centered if window is larger

Type:
Default Value
  • Vector2(1920,1200)

(static) canvasPixelated :Boolean

Disables filtering for crisper pixel art if true

Type:
  • Boolean
Default Value
  • 1

(static) enablePhysicsSolver :Boolean

Enable physics solver for collisions between objects

Type:
  • Boolean
Default Value
  • 1

(static) fontDefault :String

Default font used for text rendering

Type:
  • String
Default Value
  • arial

(static) gamepadDirectionEmulateStick :Boolean

If true, the dpad input is also routed to the left analog stick (for better accessability)

Type:
  • Boolean
Default Value
  • 1

(static) gamepadsEnable :Boolean

Should gamepads be allowed

Type:
  • Boolean
Default Value
  • 1

(static) glEnable :Boolean

Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)

Type:
  • Boolean
Default Value
  • 1

(static) glOverlay :Boolean

Fixes slow rendering in some browsers by not compositing the WebGL canvas

Type:
  • Boolean
Default Value
  • 1

(static) gravity :Number

How much gravity to apply to objects along the Y axis, negative is down

Type:
  • Number
Default Value
  • 0

(static) inputWASDEmulateDirection :Boolean

If true the WASD keys are also routed to the direction keys (for better accessability)

Type:
  • Boolean
Default Value
  • 1

(static) medalDisplayIconSize :Number

Size of icon in medal display

Type:
  • Number
Default Value
  • 50

(static) medalDisplaySize :Vector2

Size of medal display

Type:
Default Value
  • Vector2(640,80)

(static) medalDisplaySlideTime :Number

How quickly to slide on/off medals in seconds

Type:
  • Number
Default Value
  • 0.5

(static) medalDisplayTime :Number

How long to show medals for in seconds

Type:
  • Number
Default Value
  • 5

(static) medalsPreventUnlock :Boolean

Set to stop medals from being unlockable (like if cheats are enabled)

Type:
  • Boolean
Default Value
  • 0

(static) objectDefaultAngleDamping :Number

How much to slow angular velocity each frame (0-1)

Type:
  • Number
Default Value
  • 1

(static) objectDefaultDamping :Number

How much to slow velocity by each frame (0-1)

Type:
  • Number
Default Value
  • 1

(static) objectDefaultElasticity :Number

How much to bounce when a collision occurs (0-1)

Type:
  • Number
Default Value
  • 0

(static) objectDefaultFriction :Number

How much to slow when touching (0-1)

Type:
  • Number
Default Value
  • 0.8

(static) objectDefaultMass :Number

Default object mass for collison calcuations (how heavy objects are)

Type:
  • Number
Default Value
  • 1

(static) objectMaxSpeed :Number

Clamp max speed to avoid fast objects missing collisions

Type:
  • Number
Default Value
  • 1

(static) particleEmitRateScale :Number

Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)

Type:
  • Number
Default Value
  • 1

(static) soundDefaultRange :Number

Default range where sound no longer plays

Type:
  • Number
Default Value
  • 40

(static) soundDefaultTaper :Number

Default range percent to start tapering off sound (0-1)

Type:
  • Number
Default Value
  • 0.7

(static) soundEnable :Boolean

All audio code can be disabled and removed from build

Type:
  • Boolean
Default Value
  • 1

(static) soundVolume :Number

Volume scale to apply to all sound, music and speech

Type:
  • Number
Default Value
  • 0.5

(static) tileFixBleedScale :Number

Prevent tile bleeding from neighbors in pixels

Type:
  • Number
Default Value
  • 0.3

(static) tileSizeDefault :Vector2

Default size of tiles in pixels

Type:
Default Value
  • Vector2(16,16)

(static) touchGamepadAlpha :Number

Transparency of touch gamepad overlay

Type:
  • Number
Default Value
  • 0.3

(static) touchGamepadAnalog :Boolean

True if touch gamepad should be analog stick or false to use if 8 way dpad

Type:
  • Boolean
Default Value
  • 1

(static) touchGamepadEnable :Boolean

True if touch gamepad should appear on mobile devices

  • Supports left analog stick, 4 face buttons and start button (button 9)
  • Must be set by end of gameInit to be activated
Type:
  • Boolean
Default Value
  • 0

(static) touchGamepadSize :Number

Size of virutal gamepad for touch devices in pixels

Type:
  • Number
Default Value
  • 99

(static) vibrateEnable :Boolean

Allow vibration hardware if it exists

Type:
  • Boolean
Default Value
  • 1

Methods

(static) setCameraPos(pos)

Set position of camera in world space

Parameters:
NameTypeDescription
posVector2

(static) setCameraScale(scale)

Set scale of camera in world space

Parameters:
NameTypeDescription
scaleNumber

(static) setCanvasFixedSize(size)

Set fixed size of the canvas

Parameters:
NameTypeDescription
sizeVector2

(static) setCanvasMaxSize(size)

Set max size of the canvas

Parameters:
NameTypeDescription
sizeVector2

(static) setCanvasPixelated(pixelated)

Disables anti aliasing for pixel art if true

Parameters:
NameTypeDescription
pixelatedBoolean

(static) setEnablePhysicsSolver(enable)

Set if collisions between objects are enabled

Parameters:
NameTypeDescription
enableBoolean

(static) setFontDefault(font)

Set default font used for text rendering

Parameters:
NameTypeDescription
fontString

(static) setGamepadDirectionEmulateStick(enable)

Set if the dpad input is also routed to the left analog stick

Parameters:
NameTypeDescription
enableBoolean

(static) setGamepadsEnable(enable)

Set if gamepads are enabled

Parameters:
NameTypeDescription
enableBoolean

(static) setGlEnable(enable)

Set if webgl rendering is enabled

Parameters:
NameTypeDescription
enableBoolean

(static) setGlOverlay(overlay)

Set to not composite the WebGL canvas

Parameters:
NameTypeDescription
overlayBoolean

(static) setGravity(gravity)

Set how much gravity to apply to objects along the Y axis

Parameters:
NameTypeDescription
gravityNumber

(static) setInputWASDEmulateDirection(enable)

Set if true the WASD keys are also routed to the direction keys

Parameters:
NameTypeDescription
enableBoolean

(static) setMedalDisplayIconSize(size)

Set size of icon in medal display

Parameters:
NameTypeDescription
sizeNumber

(static) setMedalDisplaySize(size)

Set size of medal display

Parameters:
NameTypeDescription
sizeVector2

(static) setMedalDisplaySlideTime(time)

Set how quickly to slide on/off medals in seconds

Parameters:
NameTypeDescription
timeNumber

(static) setMedalDisplayTime(time)

Set how long to show medals for in seconds

Parameters:
NameTypeDescription
timeNumber

(static) setMedalsPreventUnlock(preventUnlock)

Set to stop medals from being unlockable

Parameters:
NameTypeDescription
preventUnlockBoolean

(static) setObjectDefaultAngleDamping(damping)

Set how much to slow angular velocity each frame

Parameters:
NameTypeDescription
dampingNumber

(static) setObjectDefaultDamping(damping)

Set how much to slow velocity by each frame

Parameters:
NameTypeDescription
dampingNumber

(static) setObjectDefaultElasticity(elasticity)

Set how much to bounce when a collision occur

Parameters:
NameTypeDescription
elasticityNumber

(static) setObjectDefaultFriction(friction)

Set how much to slow when touching

Parameters:
NameTypeDescription
frictionNumber

(static) setObjectDefaultMass(mass)

Set default object mass for collison calcuations

Parameters:
NameTypeDescription
massNumber

(static) setObjectMaxSpeed(speed)

Set max speed to avoid fast objects missing collisions

Parameters:
NameTypeDescription
speedNumber

(static) setParticleEmitRateScale(scale)

Set to scales emit rate of particles

Parameters:
NameTypeDescription
scaleNumber

(static) setSoundDefaultRange(range)

Set default range where sound no longer plays

Parameters:
NameTypeDescription
rangeNumber

(static) setSoundDefaultTaper(taper)

Set default range percent to start tapering off sound

Parameters:
NameTypeDescription
taperNumber

(static) setSoundEnable(enable)

Set to disable all audio code

Parameters:
NameTypeDescription
enableBoolean

(static) setSoundVolume(volume)

Set volume scale to apply to all sound, music and speech

Parameters:
NameTypeDescription
volumeNumber

(static) setTileFixBleedScale(scale)

Set to prevent tile bleeding from neighbors in pixels

Parameters:
NameTypeDescription
scaleNumber

(static) setTileSizeDefault(size)

Set default size of tiles in pixels

Parameters:
NameTypeDescription
sizeVector2

(static) setTouchGamepadAlpha(alpha)

Set transparency of touch gamepad overlay

Parameters:
NameTypeDescription
alphaNumber

(static) setTouchGamepadAnalog(analog)

Set if touch gamepad should be analog stick or 8 way dpad

Parameters:
NameTypeDescription
analogBoolean

(static) setTouchGamepadEnable(enable)

Set if touch gamepad should appear on mobile devices

Parameters:
NameTypeDescription
enableBoolean

(static) setTouchGamepadSize(size)

Set size of virutal gamepad for touch devices in pixels

Parameters:
NameTypeDescription
sizeNumber

(static) setVibrateEnable(enable)

Set to allow vibration hardware if it exists

Parameters:
NameTypeDescription
enableBoolean
\ No newline at end of file diff --git a/docs/Sound.html b/docs/Sound.html index a533808a..f58bec00 100644 --- a/docs/Sound.html +++ b/docs/Sound.html @@ -1,3 +1,3 @@ Class: Sound
On this page

Sound

Sound Object - Stores a zzfx sound for later use and can be played positionally

Create sounds using the ZzFX Sound Designer.

Constructor

new Sound(zzfxSound, rangeopt, taperopt)

Create a sound object and cache the zzfx samples for later use

Parameters:
NameTypeAttributesDefaultDescription
zzfxSoundArray

Array of zzfx parameters, ex. [.5,.5]

rangeNumber<optional>
soundDefaultRange

World space max range of sound, will not play if camera is farther away

taperNumber<optional>
soundDefaultTaper

At what percentage of range should it start tapering off

Example
// create a sound
const sound_example = new Sound([.5,.5]);

// play the sound
sound_example.play();

Members

randomness

Properties
TypeDescription
Number

How much to randomize frequency each time sound plays

range

Properties
TypeDescription
Number

World space max range of sound, will not play if camera is farther away

taper

Properties
TypeDescription
Number

At what percentage of range should it start tapering off

Methods

play(posopt, volumeopt, pitchopt, randomnessScaleopt) → {AudioBufferSourceNode}

Play the sound

Parameters:
NameTypeAttributesDefaultDescription
posVector2<optional>

World space position to play the sound, sound is not attenuated if null

volumeNumber<optional>
1

How much to scale volume by (in addition to range fade)

pitchNumber<optional>
1

How much to scale pitch by (also adjusted by this.randomness)

randomnessScaleNumber<optional>
1

How much to scale randomness

Returns:
  • The audio, can be used to stop sound later
Type: 
AudioBufferSourceNode

playNote(semitoneOffset, posopt, volumeopt) → {AudioBufferSourceNode}

Play the sound as a note with a semitone offset

Parameters:
NameTypeAttributesDefaultDescription
semitoneOffsetNumber

How many semitones to offset pitch

posVector2<optional>

World space position to play the sound, sound is not attenuated if null

volumeNumber<optional>
1

How much to scale volume by (in addition to range fade)

Returns:
  • The audio, can be used to stop sound later
Type: 
AudioBufferSourceNode
\ No newline at end of file +
On this page

Sound

Sound Object - Stores a zzfx sound for later use and can be played positionally

Create sounds using the ZzFX Sound Designer.

Constructor

new Sound(zzfxSound, rangeopt, taperopt)

Create a sound object and cache the zzfx samples for later use

Parameters:
NameTypeAttributesDefaultDescription
zzfxSoundArray

Array of zzfx parameters, ex. [.5,.5]

rangeNumber<optional>
soundDefaultRange

World space max range of sound, will not play if camera is farther away

taperNumber<optional>
soundDefaultTaper

At what percentage of range should it start tapering off

Example
// create a sound
const sound_example = new Sound([.5,.5]);

// play the sound
sound_example.play();

Members

randomness

Properties
TypeDescription
Number

How much to randomize frequency each time sound plays

range

Properties
TypeDescription
Number

World space max range of sound, will not play if camera is farther away

taper

Properties
TypeDescription
Number

At what percentage of range should it start tapering off

Methods

getDuration() → {Number}

Get how long this sound is in seconds

Returns:
  • How long the sound is in seconds (undefined if loading)
Type: 
Number

isLoading() → {Boolean}

Check if sound is loading, for sounds fetched from a url

Returns:
  • True if sound is loading and not ready to play
Type: 
Boolean

isPlaying() → {Boolean}

Check if the last instance of this sound is playing

Returns:
  • True if the sound is playing
Type: 
Boolean

play(posopt, volumeopt, pitchopt, randomnessScaleopt, loopopt) → {AudioBufferSourceNode}

Play the sound

Parameters:
NameTypeAttributesDefaultDescription
posVector2<optional>

World space position to play the sound, sound is not attenuated if null

volumeNumber<optional>
1

How much to scale volume by (in addition to range fade)

pitchNumber<optional>
1

How much to scale pitch by (also adjusted by this.randomness)

randomnessScaleNumber<optional>
1

How much to scale randomness

loopBoolean<optional>
0

Should the sound loop

Returns:
  • The audio source node
Type: 
AudioBufferSourceNode

playNote(semitoneOffset, posopt, volumeopt) → {AudioBufferSourceNode}

Play the sound as a note with a semitone offset

Parameters:
NameTypeAttributesDefaultDescription
semitoneOffsetNumber

How many semitones to offset pitch

posVector2<optional>

World space position to play the sound, sound is not attenuated if null

volumeNumber<optional>
1

How much to scale volume by (in addition to range fade)

Returns:
  • The audio source node
Type: 
AudioBufferSourceNode

stop()

Stop the last instance of this sound that was played

\ No newline at end of file diff --git a/docs/SoundWave.html b/docs/SoundWave.html index 935e670d..83fe07af 100644 --- a/docs/SoundWave.html +++ b/docs/SoundWave.html @@ -1,3 +1,3 @@ -Class: SoundWave
On this page

SoundWave

Sound Wave Object - Stores a wave sound for later use and can be played positionally

Constructor

new SoundWave(waveFilename, randomnessopt, rangeopt, taperopt)

Create a sound object and cache the wave file for later use

Parameters:
NameTypeAttributesDefaultDescription
waveFilenameString

Filename of wave file to load

randomnessNumber<optional>
.05

How much to randomize frequency each time sound plays

rangeNumber<optional>
soundDefaultRange

World space max range of sound, will not play if camera is farther away

taperNumber<optional>
soundDefaultTaper

At what percentage of range should it start tapering off

\ No newline at end of file +Class: SoundWave
On this page

SoundWave

Sound Wave Object - Stores a wave sound for later use and can be played positionally

  • this can be used to play wave, mp3, and ogg files

Constructor

new SoundWave(filename, randomnessopt, rangeopt, taperopt)

Create a sound object and cache the wave file for later use

Parameters:
NameTypeAttributesDefaultDescription
filenameString

Filename of audio file to load

randomnessNumber<optional>
0

How much to randomize frequency each time sound plays

rangeNumber<optional>
soundDefaultRange

World space max range of sound, will not play if camera is farther away

taperNumber<optional>
soundDefaultTaper

At what percentage of range should it start tapering off

Example
// create a sound
const sound_example = new SoundWave('sound.mp3');

// play the sound
sound_example.play();
\ No newline at end of file diff --git a/docs/TileCollision.html b/docs/TileCollision.html index d64c6548..28dacf61 100644 --- a/docs/TileCollision.html +++ b/docs/TileCollision.html @@ -1,3 +1,3 @@ Namespace: TileCollision
On this page

TileCollision

LittleJS Tile Layer System

  • Caches arrays of tiles to off screen canvas for fast rendering
  • Unlimted numbers of layers, allocates canvases as needed
  • Interfaces with EngineObject for collision
  • Collision layer is separate from visible layers
  • It is recommended to have a visible layer that matches the collision
  • Tile layers can be drawn to using their context with canvas2d
  • Drawn directly to the main canvas without using WebGL

Members

(static) tileCollision :Array

The tile collision layer array, use setTileCollisionData and getTileCollisionData to access

Type:
  • Array

(static) tileCollisionSize :Vector2

Size of the tile collision layer

Type:

Methods

(static) getTileCollisionData(pos) → {Number}

Get tile collision data

Parameters:
NameTypeDescription
posVector2
Returns:
Type: 
Number

(static) initTileCollision(size)

Clear and initialize tile collision

Parameters:
NameTypeDescription
sizeVector2

(static) setTileCollisionData(pos, dataopt)

Set tile collision data

Parameters:
NameTypeAttributesDefaultDescription
posVector2
dataNumber<optional>
0

(static) tileCollisionRaycast(posStart, posEnd, objectopt) → {Vector2}

Return the center of tile if any that is hit (does not return the exact intersection)

Parameters:
NameTypeAttributesDescription
posStartVector2
posEndVector2
objectEngineObject<optional>
Returns:
Type: 
Vector2

(static) tileCollisionTest(pos, sizeopt, objectopt) → {Boolean}

Check if collision with another object should occur

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
objectEngineObject<optional>
Returns:
Type: 
Boolean
\ No newline at end of file +
On this page

TileCollision

LittleJS Tile Layer System

  • Caches arrays of tiles to off screen canvas for fast rendering
  • Unlimted numbers of layers, allocates canvases as needed
  • Interfaces with EngineObject for collision
  • Collision layer is separate from visible layers
  • It is recommended to have a visible layer that matches the collision
  • Tile layers can be drawn to using their context with canvas2d
  • Drawn directly to the main canvas without using WebGL

Members

(static) tileCollision :Array

The tile collision layer array, use setTileCollisionData and getTileCollisionData to access

Type:
  • Array

(static) tileCollisionSize :Vector2

Size of the tile collision layer

Type:

Methods

(static) getTileCollisionData(pos) → {Number}

Get tile collision data

Parameters:
NameTypeDescription
posVector2
Returns:
Type: 
Number

(static) initTileCollision(size)

Clear and initialize tile collision

Parameters:
NameTypeDescription
sizeVector2

(static) setTileCollisionData(pos, dataopt)

Set tile collision data

Parameters:
NameTypeAttributesDefaultDescription
posVector2
dataNumber<optional>
0

(static) tileCollisionRaycast(posStart, posEnd, objectopt) → {Vector2}

Return the center of tile if any that is hit (does not return the exact intersection)

Parameters:
NameTypeAttributesDescription
posStartVector2
posEndVector2
objectEngineObject<optional>
Returns:
Type: 
Vector2

(static) tileCollisionTest(pos, sizeopt, objectopt) → {Boolean}

Check if collision with another object should occur

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
objectEngineObject<optional>
Returns:
Type: 
Boolean
\ No newline at end of file diff --git a/docs/TileLayer.html b/docs/TileLayer.html index 7d5f1ee9..27551ba2 100644 --- a/docs/TileLayer.html +++ b/docs/TileLayer.html @@ -1,3 +1,3 @@ Class: TileLayer
On this page

TileLayer

Tile layer object - cached rendering system for tile layers

  • Each Tile layer is rendered to an off screen canvas
  • To allow dynamic modifications, layers are rendered using canvas 2d
  • Some devices like mobile phones are limited to 4k texture resolution
  • So with 16x16 tiles this limits layers to 256x256 on mobile devices

Constructor

new TileLayer(positionopt, sizeopt, tileSizeopt, scaleopt, renderOrderopt)

Create a tile layer object

Parameters:
NameTypeAttributesDefaultDescription
positionVector2<optional>
Vector2()

World space position

sizeVector2<optional>
tileCollisionSize

World space size

tileSizeVector2<optional>
tileSizeDefault

Size of tiles in source pixels

scaleVector2<optional>
Vector2(1,1)

How much to scale this layer when rendered

renderOrderNumber<optional>
0

Objects sorted by renderOrder before being rendered

Example
// create tile collision and visible tile layer
initTileCollision(vec2(200,100));
const tileLayer = new TileLayer();

Extends

Members

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
NameTypeAttributesDefaultDescription
angleDampingNumber<optional>
objectDefaultAngleDamping

How much to slow down rotation each frame (0-1)

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

canvas

Properties
TypeDescription
HTMLCanvasElement

The canvas used by this tile layer

color

Properties
TypeDescription
Color

Color to apply when rendered

context

Properties
TypeDescription
CanvasRenderingContext2D

The 2D canvas context used by this tile layer

damping

Properties
NameTypeAttributesDefaultDescription
dampingNumber<optional>
objectDefaultDamping

How much to slow down velocity each frame (0-1)

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
NameTypeAttributesDefaultDescription
gravityScaleNumber<optional>
1

How much to scale gravity by for this object

isOverlay

Properties
NameTypeAttributesDefaultDescription
isOverlayBoolean<optional>
0

If true this layer will render to overlay canvas and appear above all objects

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

pos

Properties
TypeDescription
Vector2

World space position of the object

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

scale

Properties
TypeDescription
Vector2

How much to scale this layer when rendered

size

Properties
TypeDescription
Vector2

World space width and height of the object

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

drawAllTileData()

Draw all the tiles in this layer

drawCanvas2D(pos, size, angleopt, mirroropt, drawFunction)

Draw directly to the 2D canvas in world space (bipass webgl)

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2
angleNumber<optional>
0
mirrorBoolean<optional>
0
drawFunctionfunction

drawRect(pos, sizeopt, coloropt, angleopt)

Draw a rectangle directly onto the layer canvas

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
colorColor<optional>
Color()
angleNumber<optional>
0

drawTile(pos, sizeopt, tileIndexopt, tileSizeopt, coloropt, angleopt, mirroropt)

Draw a tile directly onto the layer canvas

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
tileIndexNumber<optional>
-1
tileSizeVector2<optional>
tileSizeDefault
colorColor<optional>
Color()
angleNumber<optional>
0
mirrorBoolean<optional>
0

drawTileData(layerPos)

Draw the tile at a given position

Parameters:
NameTypeDescription
layerPosVector2

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getData(layerPos) → {TileLayerData}

Get data at a given position in the array

Parameters:
NameTypeDescription
layerPosVector2

Local position in array

Returns:
Type: 
TileLayerData

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

redraw()

Draw all the tile data to an offscreen canvas

  • This may be slow in some browsers

redrawEnd()

Call to end the redraw process

redrawStart(clearopt)

Call to start the redraw process

Parameters:
NameTypeAttributesDefaultDescription
clearBoolean<optional>
0

Should it clear the canvas before drawing

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

setData(position, data, redrawopt)

Set data at a given position in the array

Parameters:
NameTypeAttributesDefaultDescription
positionVector2

Local position in array

dataTileLayerData

Data to set

redrawBoolean<optional>
0

Force the tile to redraw if true

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the object transform and physics, called automatically by engine once each frame

\ No newline at end of file +
On this page

TileLayer

Tile layer object - cached rendering system for tile layers

  • Each Tile layer is rendered to an off screen canvas
  • To allow dynamic modifications, layers are rendered using canvas 2d
  • Some devices like mobile phones are limited to 4k texture resolution
  • So with 16x16 tiles this limits layers to 256x256 on mobile devices

Constructor

new TileLayer(positionopt, sizeopt, tileSizeopt, scaleopt, renderOrderopt)

Create a tile layer object

Parameters:
NameTypeAttributesDefaultDescription
positionVector2<optional>
Vector2()

World space position

sizeVector2<optional>
tileCollisionSize

World space size

tileSizeVector2<optional>
tileSizeDefault

Size of tiles in source pixels

scaleVector2<optional>
Vector2(1,1)

How much to scale this layer when rendered

renderOrderNumber<optional>
0

Objects sorted by renderOrder before being rendered

Example
// create tile collision and visible tile layer
initTileCollision(vec2(200,100));
const tileLayer = new TileLayer();

Extends

Members

additiveColor

Properties
TypeDescription
Color

Additive color to apply when rendered

angle

Properties
TypeDescription
Number

Angle to rotate the object

angleDamping

Properties
NameTypeAttributesDefaultDescription
angleDampingNumber<optional>
objectDefaultAngleDamping

How much to slow down rotation each frame (0-1)

angleVelocity

Properties
NameTypeAttributesDefaultDescription
angleVelocityNumber<optional>
0

Angular velocity of the object

canvas

Properties
TypeDescription
HTMLCanvasElement

The canvas used by this tile layer

color

Properties
TypeDescription
Color

Color to apply when rendered

context

Properties
TypeDescription
CanvasRenderingContext2D

The 2D canvas context used by this tile layer

damping

Properties
NameTypeAttributesDefaultDescription
dampingNumber<optional>
objectDefaultDamping

How much to slow down velocity each frame (0-1)

drawSize

Properties
TypeDescription
Vector2

Size of object used for drawing, uses size if not set

elasticity

Properties
NameTypeAttributesDefaultDescription
elasticityNumber<optional>
objectDefaultElasticity

How bouncy the object is when colliding (0-1)

friction

Properties
NameTypeAttributesDefaultDescription
frictionNumber<optional>
objectDefaultFriction

How much friction to apply when sliding (0-1)

gravityScale

Properties
NameTypeAttributesDefaultDescription
gravityScaleNumber<optional>
1

How much to scale gravity by for this object

isOverlay

Properties
NameTypeAttributesDefaultDescription
isOverlayBoolean<optional>
0

If true this layer will render to overlay canvas and appear above all objects

mass

Properties
NameTypeAttributesDefaultDescription
massNumber<optional>
objectDefaultMass

How heavy the object is, static if 0

pos

Properties
TypeDescription
Vector2

World space position of the object

renderOrder

Properties
NameTypeAttributesDefaultDescription
renderOrderNumber<optional>
0

Objects are sorted by render order

scale

Properties
TypeDescription
Vector2

How much to scale this layer when rendered

size

Properties
TypeDescription
Vector2

World space width and height of the object

tileIndex

Properties
TypeDescription
Number

Tile to use to render object (-1 is untextured)

tileSize

Properties
TypeDescription
Vector2

Size of tile in source pixels

velocity

Properties
NameTypeAttributesDefaultDescription
velocityVector2<optional>
Vector2()

Velocity of the object

Methods

addChild(child, localPosopt, localAngleopt)

Attaches a child to this with a given local transform

Parameters:
NameTypeAttributesDefaultDescription
childEngineObject
localPosVector2<optional>
Vector2()
localAngleNumber<optional>
0

applyAcceleration(acceleration)

Apply acceleration to this object (adjust velocity, not affected by mass)

Parameters:
NameTypeDescription
accelerationVector2

applyForce(force)

Apply force to this object (adjust velocity, affected by mass)

Parameters:
NameTypeDescription
forceVector2

collideWithObject(object) → {Boolean}

Called to check if a object collision should be resolved

Parameters:
NameTypeDescription
objectEngineObject

the object to test against

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTile(tileData, pos) → {Boolean}

Called to check if a tile collision should be resolved

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the collision occured

Returns:
  • true if the collision should be resolved
Type: 
Boolean

collideWithTileRaycast(tileData, pos) → {Boolean}

Called to check if a tile raycast hit

Parameters:
NameTypeDescription
tileDataNumber

the value of the tile at the position

posVector2

tile where the raycast is

Returns:
  • true if the raycast should hit
Type: 
Boolean

destroy()

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

drawAllTileData()

Draw all the tiles in this layer

drawCanvas2D(pos, size, angleopt, mirroropt, drawFunction)

Draw directly to the 2D canvas in world space (bipass webgl)

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2
angleNumber<optional>
0
mirrorBoolean<optional>
0
drawFunctionfunction

drawRect(pos, sizeopt, coloropt, angleopt)

Draw a rectangle directly onto the layer canvas

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
colorColor<optional>
Color()
angleNumber<optional>
0

drawTile(pos, sizeopt, tileIndexopt, tileSizeopt, coloropt, angleopt, mirroropt)

Draw a tile directly onto the layer canvas

Parameters:
NameTypeAttributesDefaultDescription
posVector2
sizeVector2<optional>
Vector2(1,1)
tileIndexNumber<optional>
-1
tileSizeVector2<optional>
tileSizeDefault
colorColor<optional>
Color()
angleNumber<optional>
0
mirrorBoolean<optional>
0

drawTileData(layerPos)

Draw the tile at a given position

Parameters:
NameTypeDescription
layerPosVector2

getAliveTime() → {Number}

How long since the object was created

Returns:
Type: 
Number

getData(layerPos) → {TileLayerData}

Get data at a given position in the array

Parameters:
NameTypeDescription
layerPosVector2

Local position in array

Returns:
Type: 
TileLayerData

getMirrorSign() → {Number}

Get the direction of the mirror

Returns:

-1 if this.mirror is true, or 1 if not mirrored

Type: 
Number

redraw()

Draw all the tile data to an offscreen canvas

  • This may be slow in some browsers

redrawEnd()

Call to end the redraw process

redrawStart(clearopt)

Call to start the redraw process

Parameters:
NameTypeAttributesDefaultDescription
clearBoolean<optional>
0

Should it clear the canvas before drawing

removeChild(child)

Removes a child from this one

Parameters:
NameTypeDescription
childEngineObject

render()

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

setCollision(collideSolidObjectsopt, isSolidopt, collideTilesopt)

Set how this object collides

Parameters:
NameTypeAttributesDefaultDescription
collideSolidObjectsBoolean<optional>
1

Does it collide with solid objects

isSolidBoolean<optional>
1

Does it collide with and block other objects (expensive in large numbers)

collideTilesBoolean<optional>
1

Does it collide with the tile collision

setData(position, data, redrawopt)

Set data at a given position in the array

Parameters:
NameTypeAttributesDefaultDescription
positionVector2

Local position in array

dataTileLayerData

Data to set

redrawBoolean<optional>
0

Force the tile to redraw if true

toString() → {String}

Returns string containg info about this object for debugging

Returns:
Type: 
String

update()

Update the object transform and physics, called automatically by engine once each frame

\ No newline at end of file diff --git a/docs/TileLayerData.html b/docs/TileLayerData.html index 4651748a..9523974e 100644 --- a/docs/TileLayerData.html +++ b/docs/TileLayerData.html @@ -1,3 +1,3 @@ Class: TileLayerData
On this page

TileLayerData

Tile layer data object stores info about how to render a tile

Constructor

new TileLayerData(tileopt, directionopt, mirroropt, coloropt)

Create a tile layer data object, one for each tile in a TileLayer

Parameters:
NameTypeAttributesDefaultDescription
tileNumber<optional>

The tile to use, untextured if undefined

directionNumber<optional>
0

Integer direction of tile, in 90 degree increments

mirrorBoolean<optional>
0

If the tile should be mirrored along the x axis

colorColor<optional>
Color()

Color of the tile

Example
// create tile layer data with tile index 0 and random orientation and color
const tileIndex = 0;
const direction = randInt(4)
const mirror = randInt(2);
const color = randColor();
const data = new TileLayerData(tileIndex, direction, mirror, color);

Members

color

Properties
TypeDescription
Color

Color of the tile

direction

Properties
TypeDescription
Number

Integer direction of tile, in 90 degree increments

mirror

Properties
TypeDescription
Boolean

If the tile should be mirrored along the x axis

tile

Properties
TypeDescription
Number

The tile to use, untextured if undefined

Methods

clear()

Set this tile to clear, it will not be rendered

\ No newline at end of file +
On this page

TileLayerData

Tile layer data object stores info about how to render a tile

Constructor

new TileLayerData(tileopt, directionopt, mirroropt, coloropt)

Create a tile layer data object, one for each tile in a TileLayer

Parameters:
NameTypeAttributesDefaultDescription
tileNumber<optional>

The tile to use, untextured if undefined

directionNumber<optional>
0

Integer direction of tile, in 90 degree increments

mirrorBoolean<optional>
0

If the tile should be mirrored along the x axis

colorColor<optional>
Color()

Color of the tile

Example
// create tile layer data with tile index 0 and random orientation and color
const tileIndex = 0;
const direction = randInt(4)
const mirror = randInt(2);
const color = randColor();
const data = new TileLayerData(tileIndex, direction, mirror, color);

Members

color

Properties
TypeDescription
Color

Color of the tile

direction

Properties
TypeDescription
Number

Integer direction of tile, in 90 degree increments

mirror

Properties
TypeDescription
Boolean

If the tile should be mirrored along the x axis

tile

Properties
TypeDescription
Number

The tile to use, untextured if undefined

Methods

clear()

Set this tile to clear, it will not be rendered

\ No newline at end of file diff --git a/docs/Timer.html b/docs/Timer.html index 4282bc86..70b9b361 100644 --- a/docs/Timer.html +++ b/docs/Timer.html @@ -1,3 +1,3 @@ Class: Timer
On this page

Timer

Timer object tracks how long has passed since it was set

Constructor

new Timer(timeLeftopt)

Create a timer object set time passed in

Parameters:
NameTypeAttributesDescription
timeLeftNumber<optional>

How much time left before the timer elapses in seconds

Example
let a = new Timer;    // creates a timer that is not set
a.set(3);             // sets the timer to 3 seconds

let b = new Timer(1); // creates a timer with 1 second left
b.unset();            // unsets the timer

Methods

active() → {Boolean}

Returns true if set and has not elapsed

Returns:
Type: 
Boolean

elapsed() → {Boolean}

Returns true if set and elapsed

Returns:
Type: 
Boolean

get() → {Number}

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

Returns:
Type: 
Number

getPercent() → {Number}

Get percentage elapsed based on time it was set to, returns 0 if not set

Returns:
Type: 
Number

isSet() → {Boolean}

Returns true if set

Returns:
Type: 
Boolean

set(timeLeftopt)

Set the timer with seconds passed in

Parameters:
NameTypeAttributesDefaultDescription
timeLeftNumber<optional>
0

How much time left before the timer is elapsed in seconds

toString() → {String}

Returns this timer expressed as a string

Returns:
Type: 
String

unset()

Unset the timer

valueOf() → {Number}

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

Returns:
Type: 
Number
\ No newline at end of file +
On this page

Timer

Timer object tracks how long has passed since it was set

Constructor

new Timer(timeLeftopt)

Create a timer object set time passed in

Parameters:
NameTypeAttributesDescription
timeLeftNumber<optional>

How much time left before the timer elapses in seconds

Example
let a = new Timer;    // creates a timer that is not set
a.set(3);             // sets the timer to 3 seconds

let b = new Timer(1); // creates a timer with 1 second left
b.unset();            // unsets the timer

Methods

active() → {Boolean}

Returns true if set and has not elapsed

Returns:
Type: 
Boolean

elapsed() → {Boolean}

Returns true if set and elapsed

Returns:
Type: 
Boolean

get() → {Number}

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

Returns:
Type: 
Number

getPercent() → {Number}

Get percentage elapsed based on time it was set to, returns 0 if not set

Returns:
Type: 
Number

isSet() → {Boolean}

Returns true if set

Returns:
Type: 
Boolean

set(timeLeftopt)

Set the timer with seconds passed in

Parameters:
NameTypeAttributesDefaultDescription
timeLeftNumber<optional>
0

How much time left before the timer is elapsed in seconds

toString() → {String}

Returns this timer expressed as a string

Returns:
Type: 
String

unset()

Unset the timer

valueOf() → {Number}

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

Returns:
Type: 
Number
\ No newline at end of file diff --git a/docs/Utilities.html b/docs/Utilities.html index f6a81eb4..c56df13b 100644 --- a/docs/Utilities.html +++ b/docs/Utilities.html @@ -1,3 +1,3 @@ Namespace: Utilities
On this page

Utilities

LittleJS Utility Classes and Functions

  • General purpose math library
  • Vector2 - fast, simple, easy 2D vector class
  • Color - holds a rgba color with some math functions
  • Timer - tracks time automatically
  • RandomGenerator - seeded random number generator

Members

(static, constant) PI :Number

A shortcut to get Math.PI

Type:
  • Number
Default Value
  • Math.PI

Methods

(static) abs(value) → {Number}

Returns absoulte value of value passed in

Parameters:
NameTypeDescription
valueNumber
Returns:
Type: 
Number

(static) clamp(value, minopt, maxopt) → {Number}

Clamps the value beween max and min

Parameters:
NameTypeAttributesDefaultDescription
valueNumber
minNumber<optional>
0
maxNumber<optional>
1
Returns:
Type: 
Number

(static) distanceAngle(angleA, angleB) → {Number}

Returns signed wrapped distance between the two angles passed in

Parameters:
NameTypeDescription
angleANumber
angleBNumber
Returns:
Type: 
Number

(static) distanceWrap(valueA, valueB, wrapSizeopt) → {Number}

Returns signed wrapped distance between the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber
valueBNumber
wrapSizeNumber<optional>
1
Returns:
Type: 
Number

(static) formatTime(t) → {String}

Formats seconds to mm:ss style for display purposes

Parameters:
NameTypeDescription
tNumber

time in seconds

Returns:
Type: 
String

(static) hsl(hopt, sopt, lopt, aopt) → {Color}

Create a color object with HSLA values

Parameters:
NameTypeAttributesDefaultDescription
hNumber<optional>
0

hue

sNumber<optional>
0

saturation

lNumber<optional>
1

lightness

aNumber<optional>
1

alpha

Returns:
Type: 
Color

(static) isOverlapping(pointA, sizeA, pointB, sizeB) → {Boolean}

Returns true if two axis aligned bounding boxes are overlapping

Parameters:
NameTypeDescription
pointAVector2

Center of box A

sizeAVector2

Size of box A

pointBVector2

Center of box B

sizeBVector2

Size of box B

Returns:
  • True if overlapping
Type: 
Boolean

(static) isVector2(v) → {Boolean}

Check if object is a valid Vector2

Parameters:
NameTypeDescription
vVector2
Returns:
Type: 
Boolean

(static) lerp(percent, valueA, valueB) → {Number}

Linearly interpolates between values passed in using percent

Parameters:
NameTypeDescription
percentNumber
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) lerpAngle(percent, angleA, angleB) → {Number}

Linearly interpolates between the angles passed in with wrappping

Parameters:
NameTypeDescription
percentNumber
angleANumber
angleBNumber
Returns:
Type: 
Number

(static) lerpWrap(percent, valueA, valueB, wrapSizeopt) → {Number}

Linearly interpolates between values passed in with wrappping

Parameters:
NameTypeAttributesDefaultDescription
percentNumber
valueANumber
valueBNumber
wrapSizeNumber<optional>
1
Returns:
Type: 
Number

(static) max(valueA, valueB) → {Number}

Returns highest of two values passed in

Parameters:
NameTypeDescription
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) min(valueA, valueB) → {Number}

Returns lowest of two values passed in

Parameters:
NameTypeDescription
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) mod(dividend, divisoropt) → {Number}

Returns first parm modulo the second param, but adjusted so negative numbers work as expected

Parameters:
NameTypeAttributesDefaultDescription
dividendNumber
divisorNumber<optional>
1
Returns:
Type: 
Number

(static) nearestPowerOfTwo(value) → {Number}

Returns the nearest power of two not less then the value

Parameters:
NameTypeDescription
valueNumber
Returns:
Type: 
Number

(static) percent(value, valueA, valueB) → {Number}

Returns what percentage the value is between valueA and valueB

Parameters:
NameTypeDescription
valueNumber
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) rgb(ropt, gopt, bopt, aopt) → {Color}

Create a color object with RGBA values

Parameters:
NameTypeAttributesDefaultDescription
rNumber<optional>
1

red

gNumber<optional>
1

green

bNumber<optional>
1

blue

aNumber<optional>
1

alpha

Returns:
Type: 
Color

(static) sign(value) → {Number}

Returns the sign of value passed in (also returns 1 if 0)

Parameters:
NameTypeDescription
valueNumber
Returns:
Type: 
Number

(static) smoothStep(percent) → {Number}

Applies smoothstep function to the percentage value

Parameters:
NameTypeDescription
percentNumber
Returns:
Type: 
Number

(static) vec2(xopt, yopt) → {Vector2}

Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar

Parameters:
NameTypeAttributesDefaultDescription
xNumber<optional>
0
yNumber<optional>
0
Returns:
Type: 
Vector2
Example
let a = vec2(0, 1); // vector with coordinates (0, 1)
let b = vec2(a);    // copy a into b
a = vec2(5);        // set a to (5, 5)
b = vec2();         // set b to (0, 0)

(static) wave(frequencyopt, amplitudeopt, topt) → {Number}

Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default

Parameters:
NameTypeAttributesDefaultDescription
frequencyNumber<optional>
1

Frequency of the wave in Hz

amplitudeNumber<optional>
1

Amplitude (max height) of the wave

tNumber<optional>
time

Value to use for time of the wave

Returns:
  • Value waving between 0 and amplitude
Type: 
Number
\ No newline at end of file +
On this page

Utilities

LittleJS Utility Classes and Functions

  • General purpose math library
  • Vector2 - fast, simple, easy 2D vector class
  • Color - holds a rgba color with some math functions
  • Timer - tracks time automatically
  • RandomGenerator - seeded random number generator

Members

(static, constant) PI :Number

A shortcut to get Math.PI

Type:
  • Number
Default Value
  • Math.PI

Methods

(static) abs(value) → {Number}

Returns absoulte value of value passed in

Parameters:
NameTypeDescription
valueNumber
Returns:
Type: 
Number

(static) clamp(value, minopt, maxopt) → {Number}

Clamps the value beween max and min

Parameters:
NameTypeAttributesDefaultDescription
valueNumber
minNumber<optional>
0
maxNumber<optional>
1
Returns:
Type: 
Number

(static) distanceAngle(angleA, angleB) → {Number}

Returns signed wrapped distance between the two angles passed in

Parameters:
NameTypeDescription
angleANumber
angleBNumber
Returns:
Type: 
Number

(static) distanceWrap(valueA, valueB, wrapSizeopt) → {Number}

Returns signed wrapped distance between the two values passed in

Parameters:
NameTypeAttributesDefaultDescription
valueANumber
valueBNumber
wrapSizeNumber<optional>
1
Returns:
Type: 
Number

(static) formatTime(t) → {String}

Formats seconds to mm:ss style for display purposes

Parameters:
NameTypeDescription
tNumber

time in seconds

Returns:
Type: 
String

(static) hsl(hopt, sopt, lopt, aopt) → {Color}

Create a color object with HSLA values

Parameters:
NameTypeAttributesDefaultDescription
hNumber<optional>
0

hue

sNumber<optional>
0

saturation

lNumber<optional>
1

lightness

aNumber<optional>
1

alpha

Returns:
Type: 
Color

(static) isOverlapping(pointA, sizeA, pointB, sizeB) → {Boolean}

Returns true if two axis aligned bounding boxes are overlapping

Parameters:
NameTypeDescription
pointAVector2

Center of box A

sizeAVector2

Size of box A

pointBVector2

Center of box B

sizeBVector2

Size of box B

Returns:
  • True if overlapping
Type: 
Boolean

(static) isVector2(v) → {Boolean}

Check if object is a valid Vector2

Parameters:
NameTypeDescription
vVector2
Returns:
Type: 
Boolean

(static) lerp(percent, valueA, valueB) → {Number}

Linearly interpolates between values passed in using percent

Parameters:
NameTypeDescription
percentNumber
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) lerpAngle(percent, angleA, angleB) → {Number}

Linearly interpolates between the angles passed in with wrappping

Parameters:
NameTypeDescription
percentNumber
angleANumber
angleBNumber
Returns:
Type: 
Number

(static) lerpWrap(percent, valueA, valueB, wrapSizeopt) → {Number}

Linearly interpolates between values passed in with wrappping

Parameters:
NameTypeAttributesDefaultDescription
percentNumber
valueANumber
valueBNumber
wrapSizeNumber<optional>
1
Returns:
Type: 
Number

(static) max(valueA, valueB) → {Number}

Returns highest of two values passed in

Parameters:
NameTypeDescription
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) min(valueA, valueB) → {Number}

Returns lowest of two values passed in

Parameters:
NameTypeDescription
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) mod(dividend, divisoropt) → {Number}

Returns first parm modulo the second param, but adjusted so negative numbers work as expected

Parameters:
NameTypeAttributesDefaultDescription
dividendNumber
divisorNumber<optional>
1
Returns:
Type: 
Number

(static) nearestPowerOfTwo(value) → {Number}

Returns the nearest power of two not less then the value

Parameters:
NameTypeDescription
valueNumber
Returns:
Type: 
Number

(static) percent(value, valueA, valueB) → {Number}

Returns what percentage the value is between valueA and valueB

Parameters:
NameTypeDescription
valueNumber
valueANumber
valueBNumber
Returns:
Type: 
Number

(static) rgb(ropt, gopt, bopt, aopt) → {Color}

Create a color object with RGBA values

Parameters:
NameTypeAttributesDefaultDescription
rNumber<optional>
1

red

gNumber<optional>
1

green

bNumber<optional>
1

blue

aNumber<optional>
1

alpha

Returns:
Type: 
Color

(static) sign(value) → {Number}

Returns the sign of value passed in (also returns 1 if 0)

Parameters:
NameTypeDescription
valueNumber
Returns:
Type: 
Number

(static) smoothStep(percent) → {Number}

Applies smoothstep function to the percentage value

Parameters:
NameTypeDescription
percentNumber
Returns:
Type: 
Number

(static) vec2(xopt, yopt) → {Vector2}

Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar

Parameters:
NameTypeAttributesDefaultDescription
xNumber<optional>
0
yNumber<optional>
0
Returns:
Type: 
Vector2
Example
let a = vec2(0, 1); // vector with coordinates (0, 1)
let b = vec2(a);    // copy a into b
a = vec2(5);        // set a to (5, 5)
b = vec2();         // set b to (0, 0)

(static) wave(frequencyopt, amplitudeopt, topt) → {Number}

Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default

Parameters:
NameTypeAttributesDefaultDescription
frequencyNumber<optional>
1

Frequency of the wave in Hz

amplitudeNumber<optional>
1

Amplitude (max height) of the wave

tNumber<optional>
time

Value to use for time of the wave

Returns:
  • Value waving between 0 and amplitude
Type: 
Number
\ No newline at end of file diff --git a/docs/Vector2.html b/docs/Vector2.html index ab1b4086..2c5600d6 100644 --- a/docs/Vector2.html +++ b/docs/Vector2.html @@ -1,3 +1,3 @@ Class: Vector2
On this page

Vector2

2D Vector object with vector math library

  • Functions do not change this so they can be chained together

Constructor

new Vector2(xopt, yopt)

Create a 2D vector with the x and y passed in, can also be created with vec2()

Parameters:
NameTypeAttributesDefaultDescription
xNumber<optional>
0

X axis location

yNumber<optional>
0

Y axis location

Example
let a = new Vector2(2, 3); // vector with coordinates (2, 3)
let b = new Vector2;       // vector with coordinates (0, 0)
let c = vec2(4, 2);        // use the vec2 function to make a Vector2
let d = a.add(b).scale(5); // operators can be chained

Members

x

Properties
TypeDescription
Number

X axis location

y

Properties
TypeDescription
Number

Y axis location

Methods

add(v) → {Vector2}

Returns a copy of this vector plus the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

angle() → {Number}

Returns the angle of this vector, up is angle 0

Returns:
Type: 
Number

area() → {Number}

Returns the area this vector covers as a rectangle

Returns:
Type: 
Number

arrayCheck(arraySize) → {Boolean}

Returns true if this vector is within the bounds of an array size passed in

Parameters:
NameTypeDescription
arraySizeVector2
Returns:
Type: 
Boolean

clampLength(lengthopt) → {Vector2}

Returns a new vector clamped to length passed in

Parameters:
NameTypeAttributesDefaultDescription
lengthNumber<optional>
1
Returns:
Type: 
Vector2

copy() → {Vector2}

Returns a new vector that is a copy of this

Returns:
Type: 
Vector2

cross(v) → {Number}

Returns the cross product of this and the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

direction() → {Number}

Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)

Returns:
Type: 
Number

distance(v) → {Number}

Returns the distance from this vector to vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

distanceSquared(v) → {Number}

Returns the distance squared from this vector to vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

divide(v) → {Vector2}

Returns a copy of this vector divided by the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

dot(v) → {Number}

Returns the dot product of this and the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

floor() → {Vector2}

Returns a copy of this vector with each axis floored

Returns:
Type: 
Vector2

invert() → {Vector2}

Returns a copy of this vector that has been inverted

Returns:
Type: 
Vector2

length() → {Number}

Returns the length of this vector

Returns:
Type: 
Number

lengthSquared() → {Number}

Returns the length of this vector squared

Returns:
Type: 
Number

lerp(v, percent) → {Vector2}

Returns a new vector that is p percent between this and the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

percentNumber
Returns:
Type: 
Vector2

multiply(v) → {Vector2}

Returns a copy of this vector times the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

normalize(lengthopt) → {Vector2}

Returns a new vector in same direction as this one with the length passed in

Parameters:
NameTypeAttributesDefaultDescription
lengthNumber<optional>
1
Returns:
Type: 
Vector2

rotate(angle) → {Vector2}

Returns copy of this vector rotated by the angle passed in

Parameters:
NameTypeDescription
angleNumber
Returns:
Type: 
Vector2

scale(s) → {Vector2}

Returns a copy of this vector scaled by the vector passed in

Parameters:
NameTypeDescription
sNumber

scale

Returns:
Type: 
Vector2

setAngle(angleopt, lengthopt) → {Vector2}

Sets this vector with angle and length passed in

Parameters:
NameTypeAttributesDefaultDescription
angleNumber<optional>
0
lengthNumber<optional>
1
Returns:
Type: 
Vector2

subtract(v) → {Vector2}

Returns a copy of this vector minus the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

toString(digits) → {String}

Returns this vector expressed as a string

Parameters:
NameTypeDefaultDescription
digitsfloat3

precision to display

Returns:
Type: 
String
\ No newline at end of file +
On this page

Vector2

2D Vector object with vector math library

  • Functions do not change this so they can be chained together

Constructor

new Vector2(xopt, yopt)

Create a 2D vector with the x and y passed in, can also be created with vec2()

Parameters:
NameTypeAttributesDefaultDescription
xNumber<optional>
0

X axis location

yNumber<optional>
0

Y axis location

Example
let a = new Vector2(2, 3); // vector with coordinates (2, 3)
let b = new Vector2;       // vector with coordinates (0, 0)
let c = vec2(4, 2);        // use the vec2 function to make a Vector2
let d = a.add(b).scale(5); // operators can be chained

Members

x

Properties
TypeDescription
Number

X axis location

y

Properties
TypeDescription
Number

Y axis location

Methods

add(v) → {Vector2}

Returns a copy of this vector plus the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

angle() → {Number}

Returns the angle of this vector, up is angle 0

Returns:
Type: 
Number

area() → {Number}

Returns the area this vector covers as a rectangle

Returns:
Type: 
Number

arrayCheck(arraySize) → {Boolean}

Returns true if this vector is within the bounds of an array size passed in

Parameters:
NameTypeDescription
arraySizeVector2
Returns:
Type: 
Boolean

clampLength(lengthopt) → {Vector2}

Returns a new vector clamped to length passed in

Parameters:
NameTypeAttributesDefaultDescription
lengthNumber<optional>
1
Returns:
Type: 
Vector2

copy() → {Vector2}

Returns a new vector that is a copy of this

Returns:
Type: 
Vector2

cross(v) → {Number}

Returns the cross product of this and the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

direction() → {Number}

Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)

Returns:
Type: 
Number

distance(v) → {Number}

Returns the distance from this vector to vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

distanceSquared(v) → {Number}

Returns the distance squared from this vector to vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

divide(v) → {Vector2}

Returns a copy of this vector divided by the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

dot(v) → {Number}

Returns the dot product of this and the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Number

floor() → {Vector2}

Returns a copy of this vector with each axis floored

Returns:
Type: 
Vector2

invert() → {Vector2}

Returns a copy of this vector that has been inverted

Returns:
Type: 
Vector2

length() → {Number}

Returns the length of this vector

Returns:
Type: 
Number

lengthSquared() → {Number}

Returns the length of this vector squared

Returns:
Type: 
Number

lerp(v, percent) → {Vector2}

Returns a new vector that is p percent between this and the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

percentNumber
Returns:
Type: 
Vector2

multiply(v) → {Vector2}

Returns a copy of this vector times the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

normalize(lengthopt) → {Vector2}

Returns a new vector in same direction as this one with the length passed in

Parameters:
NameTypeAttributesDefaultDescription
lengthNumber<optional>
1
Returns:
Type: 
Vector2

rotate(angle) → {Vector2}

Returns copy of this vector rotated by the angle passed in

Parameters:
NameTypeDescription
angleNumber
Returns:
Type: 
Vector2

scale(s) → {Vector2}

Returns a copy of this vector scaled by the vector passed in

Parameters:
NameTypeDescription
sNumber

scale

Returns:
Type: 
Vector2

setAngle(angleopt, lengthopt) → {Vector2}

Sets this vector with angle and length passed in

Parameters:
NameTypeAttributesDefaultDescription
angleNumber<optional>
0
lengthNumber<optional>
1
Returns:
Type: 
Vector2

subtract(v) → {Vector2}

Returns a copy of this vector minus the vector passed in

Parameters:
NameTypeDescription
vVector2

other vector

Returns:
Type: 
Vector2

toString(digits) → {String}

Returns this vector expressed as a string

Parameters:
NameTypeDefaultDescription
digitsfloat3

precision to display

Returns:
Type: 
String
\ No newline at end of file diff --git a/docs/WebGL.html b/docs/WebGL.html index 4a7f07f0..f3df5617 100644 --- a/docs/WebGL.html +++ b/docs/WebGL.html @@ -1,3 +1,3 @@ Namespace: WebGL
On this page

WebGL

LittleJS WebGL Interface

  • All webgl used by the engine is wrapped up here
  • For normal stuff you won't need to see or call anything in this file
  • For advanced stuff there are helper functions to create shaders, textures, etc
  • Can be disabled with glEnable to revert to 2D canvas rendering
  • Batches sprite rendering on GPU for incredibly fast performance
  • Sprite transform math is done in the shader where possible

Members

(static) glCanvas :HTMLCanvasElement

The WebGL canvas which appears above the main canvas and below the overlay canvas

Type:
  • HTMLCanvasElement

(static) glContext :WebGLRenderingContext

2d context for glCanvas

Type:
  • WebGLRenderingContext

(static) glTileTexture :WebGLTexture

Main tile sheet texture automatically loaded by engine

Type:
  • WebGLTexture

Methods

(static) glCompileShader(source, type) → {WebGLShader}

Compile WebGL shader of the given type, will throw errors if in debug mode

Parameters:
NameTypeDescription
sourceString
type
Returns:
Type: 
WebGLShader

(static) glCopyToContext(context, forceDrawopt)

Draw any sprites still in the buffer, copy to main canvas and clear

Parameters:
NameTypeAttributesDefaultDescription
contextCanvasRenderingContext2D
forceDrawBoolean<optional>
0

(static) glCreateProgram(vsSource, fsSource) → {WebGLProgram}

Create WebGL program with given shaders

Parameters:
NameTypeDescription
vsSourceWebGLShader
fsSourceWebGLShader
Returns:
Type: 
WebGLProgram

(static) glCreateTexture(image) → {WebGLTexture}

Create WebGL texture from an image and set the texture settings

Parameters:
NameTypeDescription
imageImage
Returns:
Type: 
WebGLTexture

(static) glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdditiveopt)

Add a sprite to the gl draw list, used by all gl draw functions

Parameters:
NameTypeAttributesDefaultDescription
xNumber
yNumber
sizeXNumber
sizeYNumber
angleNumber
uv0XNumber
uv0YNumber
uv1XNumber
uv1YNumber
rgbaNumber
rgbaAdditiveNumber<optional>
0

(static) glDrawPoints(points, rgba)

Add a convex polygon to the gl draw list

Parameters:
NameTypeDescription
pointsArray

Array of Vector2 points

rgbaNumber

Color of the polygon

(static) glFlush()

Draw all sprites and clear out the buffer, called automatically by the system whenever necessary

(static) glInitPostProcess(shaderCode, includeOverlay)

Set up a post processing shader

Parameters:
NameTypeDescription
shaderCodeString
includeOverlayBoolean

(static) glSetBlendMode(additiveopt)

Set the WebGl blend mode, normally you should call setBlendMode instead

Parameters:
NameTypeAttributesDefaultDescription
additiveBoolean<optional>
0

(static) glSetTexture(textureopt)

Set the WebGl texture, not normally necessary unless multiple tile sheets are used

  • This may also flush the gl buffer resulting in more draw calls and worse performance
Parameters:
NameTypeAttributesDefaultDescription
textureWebGLTexture<optional>
glTileTexture
\ No newline at end of file +
On this page

WebGL

LittleJS WebGL Interface

  • All webgl used by the engine is wrapped up here
  • For normal stuff you won't need to see or call anything in this file
  • For advanced stuff there are helper functions to create shaders, textures, etc
  • Can be disabled with glEnable to revert to 2D canvas rendering
  • Batches sprite rendering on GPU for incredibly fast performance
  • Sprite transform math is done in the shader where possible

Members

(static) glCanvas :HTMLCanvasElement

The WebGL canvas which appears above the main canvas and below the overlay canvas

Type:
  • HTMLCanvasElement

(static) glContext :WebGLRenderingContext

2d context for glCanvas

Type:
  • WebGLRenderingContext

(static) glTileTexture :WebGLTexture

Main tile sheet texture automatically loaded by engine

Type:
  • WebGLTexture

Methods

(static) glCompileShader(source, type) → {WebGLShader}

Compile WebGL shader of the given type, will throw errors if in debug mode

Parameters:
NameTypeDescription
sourceString
type
Returns:
Type: 
WebGLShader

(static) glCopyToContext(context, forceDrawopt)

Draw any sprites still in the buffer, copy to main canvas and clear

Parameters:
NameTypeAttributesDefaultDescription
contextCanvasRenderingContext2D
forceDrawBoolean<optional>
0

(static) glCreateProgram(vsSource, fsSource) → {WebGLProgram}

Create WebGL program with given shaders

Parameters:
NameTypeDescription
vsSourceWebGLShader
fsSourceWebGLShader
Returns:
Type: 
WebGLProgram

(static) glCreateTexture(image) → {WebGLTexture}

Create WebGL texture from an image and set the texture settings

Parameters:
NameTypeDescription
imageImage
Returns:
Type: 
WebGLTexture

(static) glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdditiveopt)

Add a sprite to the gl draw list, used by all gl draw functions

Parameters:
NameTypeAttributesDefaultDescription
xNumber
yNumber
sizeXNumber
sizeYNumber
angleNumber
uv0XNumber
uv0YNumber
uv1XNumber
uv1YNumber
rgbaNumber
rgbaAdditiveNumber<optional>
0

(static) glDrawPoints(points, rgba)

Add a convex polygon to the gl draw list

Parameters:
NameTypeDescription
pointsArray

Array of Vector2 points

rgbaNumber

Color of the polygon

(static) glFlush()

Draw all sprites and clear out the buffer, called automatically by the system whenever necessary

(static) glInitPostProcess(shaderCode, includeOverlay)

Set up a post processing shader

Parameters:
NameTypeDescription
shaderCodeString
includeOverlayBoolean

(static) glSetBlendMode(additiveopt)

Set the WebGl blend mode, normally you should call setBlendMode instead

Parameters:
NameTypeAttributesDefaultDescription
additiveBoolean<optional>
0

(static) glSetTexture(textureopt)

Set the WebGl texture, not normally necessary unless multiple tile sheets are used

  • This may also flush the gl buffer resulting in more draw calls and worse performance
Parameters:
NameTypeAttributesDefaultDescription
textureWebGLTexture<optional>
glTileTexture
\ No newline at end of file diff --git a/docs/data/search.json b/docs/data/search.json index b79c9463..044d6bd6 100644 --- a/docs/data/search.json +++ b/docs/data/search.json @@ -1 +1 @@ -{"list":[{"title":"Audio","link":"Audio","description":"

LittleJS Audio System

\n"},{"title":"Audio.audioContext","link":"audioContext","description":"

Audio context used by the engine

"},{"title":"Audio.getNoteFrequency","link":"getNoteFrequency","description":"

Get frequency of a note on a musical scale

"},{"title":"Audio.playAudioFile","link":"playAudioFile","description":"

Play an mp3 or wav audio from a local file or url

"},{"title":"Audio.playSamples","link":"playSamples","description":"

Play cached audio samples with given settings

"},{"title":"Audio.speak","link":"speak","description":"

Speak text with passed in settings

"},{"title":"Audio.speakStop","link":"speakStop","description":"

Stop all queued speech

"},{"title":"Audio.zzfx","link":"zzfx","description":"

Generate and play a ZzFX sound

\n

Create sounds using the ZzFX Sound Designer.

"},{"title":"Audio.zzfxG","link":"zzfxG","description":"

Generate samples for a ZzFX sound

"},{"title":"Audio.zzfxM","link":"zzfxM","description":"

Generate samples for a ZzFM song with given parameters

"},{"title":"Audio.zzfxR","link":"zzfxR","description":"

Sample rate used for all ZzFX sounds

"},{"title":"Color","link":"Color","description":"

Create a color with the rgba components passed in, white by default

"},{"title":"Color#a","link":"a"},{"title":"Color#add","link":"add","description":"

Returns a copy of this color plus the color passed in

"},{"title":"Color#b","link":"b"},{"title":"Color#clamp","link":"clamp","description":"

Returns a copy of this color clamped to the valid range between 0 and 1

"},{"title":"Color#copy","link":"copy","description":"

Returns a new color that is a copy of this

"},{"title":"Color#divide","link":"divide","description":"

Returns a copy of this color divided by the color passed in

"},{"title":"Color#g","link":"g"},{"title":"Color#getHSLA","link":"getHSLA","description":"

Returns this color expressed in hsla format

"},{"title":"Color#lerp","link":"lerp","description":"

Returns a new color that is p percent between this and the color passed in

"},{"title":"Color#multiply","link":"multiply","description":"

Returns a copy of this color times the color passed in

"},{"title":"Color#mutate","link":"mutate","description":"

Returns a new color that has each component randomly adjusted

"},{"title":"Color#r","link":"r"},{"title":"Color#rgbaInt","link":"rgbaInt","description":"

Returns this color expressed as 32 bit RGBA value

"},{"title":"Color#scale","link":"scale","description":"

Returns a copy of this color scaled by the value passed in, alpha can be scaled separately

"},{"title":"Color#setHSLA","link":"setHSLA","description":"

Sets this color given a hue, saturation, lightness, and alpha

"},{"title":"Color#setHex","link":"setHex","description":"

Set this color from a hex code

"},{"title":"Color#subtract","link":"subtract","description":"

Returns a copy of this color minus the color passed in

"},{"title":"Color#toString","link":"toString","description":"

Returns this color expressed as a hex color code

"},{"title":"Debug","link":"Debug","description":"

LittleJS Debug System

\n"},{"title":"Debug.ASSERT","link":"ASSERT","description":"

Asserts if the experssion is false, does not do anything in release builds

"},{"title":"Debug.debug","link":"debug","description":"

True if debug is enabled

"},{"title":"Debug.debugAABB","link":"debugAABB","description":"

Draw a debug axis aligned bounding box in world space

"},{"title":"Debug.debugCircle","link":"debugCircle","description":"

Draw a debug circle in world space

"},{"title":"Debug.debugClear","link":"debugClear","description":"

Clear all debug primitives in the list

"},{"title":"Debug.debugKey","link":"debugKey","description":"

Key code used to toggle debug mode, Esc by default

"},{"title":"Debug.debugLine","link":"debugLine","description":"

Draw a debug line in world space

"},{"title":"Debug.debugPoint","link":"debugPoint","description":"

Draw a debug point in world space

"},{"title":"Debug.debugPointSize","link":"debugPointSize","description":"

Size to render debug points by default

"},{"title":"Debug.debugRect","link":"debugRect","description":"

Draw a debug rectangle in world space

"},{"title":"Debug.debugSaveCanvas","link":"debugSaveCanvas","description":"

Save a canvas to disk

"},{"title":"Debug.debugSaveDataURL","link":"debugSaveDataURL","description":"

Save a data url to disk

"},{"title":"Debug.debugSaveText","link":"debugSaveText","description":"

Save a text file to disk

"},{"title":"Debug.debugText","link":"debugText","description":"

Draw a debug axis aligned bounding box in world space

"},{"title":"Debug.enableAsserts","link":"enableAsserts","description":"

True if asserts are enaled

"},{"title":"Debug.setDebugKey","link":"setDebugKey","description":"

Set key code used to toggle debug mode, Esc by default

"},{"title":"Debug.setShowWatermark","link":"setShowWatermark","description":"

Set if watermark with FPS should be shown

"},{"title":"Debug.showWatermark","link":"showWatermark","description":"

True if watermark with FPS should be shown, false in release builds

"},{"title":"Draw","link":"Draw","description":"

LittleJS Drawing System

\n\n

LittleJS uses a hybrid rendering solution with the best of both Canvas2D and WebGL.\nThere are 3 canvas/contexts available to draw to...\nmainCanvas - 2D background canvas, non WebGL stuff like tile layers are drawn here.\nglCanvas - Used by the accelerated WebGL batch rendering system.\noverlayCanvas - Another 2D canvas that appears on top of the other 2 canvases.

\n

The WebGL rendering system is very fast with some caveats...

\n\n

The LittleJS rendering solution is intentionally simple, feel free to adjust it for your needs!

"},{"title":"Draw.drawCanvas2D","link":"drawCanvas2D","description":"

Draw directly to a 2d canvas context in world space

"},{"title":"Draw.drawLine","link":"drawLine","description":"

Draw colored line between two points

"},{"title":"Draw.drawPoly","link":"drawPoly","description":"

Draw colored polygon using passed in points

"},{"title":"Draw.drawRect","link":"drawRect","description":"

Draw colored rect centered on pos

"},{"title":"Draw.drawText","link":"drawText","description":"

Draw text on overlay canvas in world space\nAutomatically splits new lines into rows

"},{"title":"Draw.drawTextScreen","link":"drawTextScreen","description":"

Draw text on overlay canvas in screen space\nAutomatically splits new lines into rows

"},{"title":"Draw.drawTile","link":"drawTile","description":"

Draw textured tile centered in world space, with color applied if using WebGL

"},{"title":"Draw.isFullscreen","link":"isFullscreen","description":"

Returns true if fullscreen mode is active

"},{"title":"Draw.mainCanvas","link":"mainCanvas","description":"

The primary 2D canvas visible to the user

"},{"title":"Draw.mainCanvasSize","link":"mainCanvasSize","description":"

The size of the main canvas (and other secondary canvases)

"},{"title":"Draw.mainContext","link":"mainContext","description":"

2d context for mainCanvas

"},{"title":"Draw.overlayCanvas","link":"overlayCanvas","description":"

A canvas that appears on top of everything the same size as mainCanvas

"},{"title":"Draw.overlayContext","link":"overlayContext","description":"

2d context for overlayCanvas

"},{"title":"Draw.screenToWorld","link":"screenToWorld","description":"

Convert from screen to world space coordinates

"},{"title":"Draw.setBlendMode","link":"setBlendMode","description":"

Enable normal or additive blend mode

"},{"title":"Draw.tileImage","link":"tileImage","description":"

Tile sheet for batch rendering system

"},{"title":"Draw.toggleFullscreen","link":"toggleFullscreen","description":"

Toggle fullsceen mode

"},{"title":"Draw.worldToScreen","link":"worldToScreen","description":"

Convert from world to screen space coordinates

"},{"title":"Engine","link":"Engine","description":"

LittleJS - The Tiny JavaScript Game Engine That Can!\nMIT License - Copyright 2021 Frank Force

\n

Engine Features

\n"},{"title":"Engine.engineInit","link":"engineInit","description":"

Start up LittleJS engine with your callback functions

"},{"title":"Engine.engineName","link":"engineName","description":"

Name of engine

"},{"title":"Engine.engineObjects","link":"engineObjects","description":"

Array containing all engine objects

"},{"title":"Engine.engineObjectsCallback","link":"engineObjectsCallback","description":"

Triggers a callback for each object within a given area

"},{"title":"Engine.engineObjectsCollide","link":"engineObjectsCollide","description":"

Array containing only objects that are set to collide with other objects this frame (for optimization)

"},{"title":"Engine.engineObjectsDestroy","link":"engineObjectsDestroy","description":"

Destroy and remove all objects

"},{"title":"Engine.engineObjectsUpdate","link":"engineObjectsUpdate","description":"

Update each engine object, remove destroyed objects, and update time

"},{"title":"Engine.engineVersion","link":"engineVersion","description":"

Version of engine

"},{"title":"Engine.frame","link":"frame","description":"

Current update frame, used to calculate time

"},{"title":"Engine.frameRate","link":"frameRate","description":"

Frames per second to update objects

"},{"title":"Engine.paused","link":"paused","description":"

Is the game paused? Causes time and objects to not be updated

"},{"title":"Engine.setPaused","link":"setPaused","description":"

Set if game is paused

"},{"title":"Engine.time","link":"time","description":"

Current engine time since start in seconds, derived from frame

"},{"title":"Engine.timeDelta","link":"timeDelta","description":"

How many seconds each frame lasts, engine uses a fixed time step

"},{"title":"Engine.timeReal","link":"timeReal","description":"

Actual clock time since start in seconds (not affected by pause or frame rate clamping)

"},{"title":"EngineObject","link":"EngineObject","description":"

Create an engine object and adds it to the list of objects

"},{"title":"EngineObject#addChild","link":"addChild","description":"

Attaches a child to this with a given local transform

"},{"title":"EngineObject#additiveColor","link":"additiveColor"},{"title":"EngineObject#angle","link":"angle"},{"title":"EngineObject#angleDamping","link":"angleDamping"},{"title":"EngineObject#angleVelocity","link":"angleVelocity"},{"title":"EngineObject#applyAcceleration","link":"applyAcceleration","description":"

Apply acceleration to this object (adjust velocity, not affected by mass)

"},{"title":"EngineObject#applyForce","link":"applyForce","description":"

Apply force to this object (adjust velocity, affected by mass)

"},{"title":"EngineObject#collideWithObject","link":"collideWithObject","description":"

Called to check if a object collision should be resolved

"},{"title":"EngineObject#collideWithTile","link":"collideWithTile","description":"

Called to check if a tile collision should be resolved

"},{"title":"EngineObject#collideWithTileRaycast","link":"collideWithTileRaycast","description":"

Called to check if a tile raycast hit

"},{"title":"EngineObject#color","link":"color"},{"title":"EngineObject#damping","link":"damping"},{"title":"EngineObject#destroy","link":"destroy","description":"

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

"},{"title":"EngineObject#drawSize","link":"drawSize"},{"title":"EngineObject#elasticity","link":"elasticity"},{"title":"EngineObject#friction","link":"friction"},{"title":"EngineObject#getAliveTime","link":"getAliveTime","description":"

How long since the object was created

"},{"title":"EngineObject#getMirrorSign","link":"getMirrorSign","description":"

Get the direction of the mirror

"},{"title":"EngineObject#gravityScale","link":"gravityScale"},{"title":"EngineObject#mass","link":"mass"},{"title":"EngineObject#pos","link":"pos"},{"title":"EngineObject#removeChild","link":"removeChild","description":"

Removes a child from this one

"},{"title":"EngineObject#render","link":"render","description":"

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

"},{"title":"EngineObject#renderOrder","link":"renderOrder"},{"title":"EngineObject#setCollision","link":"setCollision","description":"

Set how this object collides

"},{"title":"EngineObject#size","link":"size"},{"title":"EngineObject#tileIndex","link":"tileIndex"},{"title":"EngineObject#tileSize","link":"tileSize"},{"title":"EngineObject#toString","link":"toString","description":"

Returns string containg info about this object for debugging

"},{"title":"EngineObject#update","link":"update","description":"

Update the object transform and physics, called automatically by engine once each frame

"},{"title":"EngineObject#velocity","link":"velocity"},{"title":"FontImage","link":"FontImage","description":"

Create an image font

"},{"title":"FontImage#drawText","link":"drawText","description":"

Draw text in world space using the image font

"},{"title":"FontImage#drawTextScreen","link":"drawTextScreen","description":"

Draw text in screen space using the image font

"},{"title":"Input","link":"Input","description":"

LittleJS Input System

\n"},{"title":"Input.clearInput","link":"clearInput","description":"

Clears all input

"},{"title":"Input.gamepadIsDown","link":"gamepadIsDown","description":"

Returns true if gamepad button is down

"},{"title":"Input.gamepadStick","link":"gamepadStick","description":"

Returns gamepad stick value

"},{"title":"Input.gamepadWasPressed","link":"gamepadWasPressed","description":"

Returns true if gamepad button was pressed

"},{"title":"Input.gamepadWasReleased","link":"gamepadWasReleased","description":"

Returns true if gamepad button was released

"},{"title":"Input.isTouchDevice","link":"isTouchDevice","description":"

True if a touch device has been detected

"},{"title":"Input.isUsingGamepad","link":"isUsingGamepad","description":"

Returns true if user is using gamepad (has more recently pressed a gamepad button)

"},{"title":"Input.keyIsDown","link":"keyIsDown","description":"

Returns true if device key is down

"},{"title":"Input.keyWasPressed","link":"keyWasPressed","description":"

Returns true if device key was pressed this frame

"},{"title":"Input.keyWasReleased","link":"keyWasReleased","description":"

Returns true if device key was released this frame

"},{"title":"Input.mouseIsDown","link":"mouseIsDown","description":"

Returns true if mouse button is down

"},{"title":"Input.mousePos","link":"mousePos","description":"

Mouse pos in world space

"},{"title":"Input.mousePosScreen","link":"mousePosScreen","description":"

Mouse pos in screen space

"},{"title":"Input.mouseWasPressed","link":"mouseWasPressed","description":"

Returns true if mouse button was pressed

"},{"title":"Input.mouseWasReleased","link":"mouseWasReleased","description":"

Returns true if mouse button was released

"},{"title":"Input.mouseWheel","link":"mouseWheel","description":"

Mouse wheel delta this frame

"},{"title":"Input.preventDefaultInput","link":"preventDefaultInput","description":"

Prevents input continuing to the default browser handling (false by default)

"},{"title":"Input.vibrate","link":"vibrate","description":"

Pulse the vibration hardware if it exists

"},{"title":"Input.vibrateStop","link":"vibrateStop","description":"

Cancel any ongoing vibration

"},{"title":"Medal","link":"Medal","description":"

Create an medal object and adds it to the list of medals

"},{"title":"Medal#render","link":"render","description":"

Render a medal

"},{"title":"Medal#renderIcon","link":"renderIcon","description":"

Render the icon for a medal

"},{"title":"Medal#unlock","link":"unlock","description":"

Unlocks a medal if not already unlocked

"},{"title":"Medals","link":"Medals","description":"

LittleJS Medal System

\n"},{"title":"Medals.medals","link":"medals","description":"

List of all medals

"},{"title":"Medals.medalsInit","link":"medalsInit","description":"

Initialize medals with a save name used for storage

\n"},{"title":"Medals.newgroundsInit","link":"newgroundsInit","description":"

This can used to enable Newgrounds functionality

"},{"title":"Music","link":"Music","description":"

Create a music object and cache the zzfx music samples for later use

"},{"title":"Music#isPlaying","link":"isPlaying","description":"

Check if music is playing

"},{"title":"Music#play","link":"play","description":"

Play the music

"},{"title":"Music#stop","link":"stop","description":"

Stop the music

"},{"title":"Newgrounds","link":"Newgrounds","description":"

Create a newgrounds object

"},{"title":"Newgrounds#call","link":"call","description":"

Send a message to call a component of the Newgrounds API

"},{"title":"Newgrounds#getScores","link":"getScores","description":"

Get scores from a scoreboard

"},{"title":"Newgrounds#logView","link":"logView","description":"

Send message to log a view

"},{"title":"Newgrounds#postScore","link":"postScore","description":"

Send message to post score

"},{"title":"Newgrounds#unlockMedal","link":"unlockMedal","description":"

Send message to unlock a medal by id

"},{"title":"Particle","link":"Particle","description":"

Create a particle with the given settings

"},{"title":"Particle#render","link":"render","description":"

Render the particle, automatically called each frame, sorted by renderOrder

"},{"title":"ParticleEmitter","link":"ParticleEmitter","description":"

Create a particle system with the given settings

"},{"title":"ParticleEmitter#additive","link":"additive"},{"title":"ParticleEmitter#angleDamping","link":"angleDamping"},{"title":"ParticleEmitter#angleSpeed","link":"angleSpeed"},{"title":"ParticleEmitter#collideTiles","link":"collideTiles"},{"title":"ParticleEmitter#colorEndA","link":"colorEndA"},{"title":"ParticleEmitter#colorEndB","link":"colorEndB"},{"title":"ParticleEmitter#colorStartA","link":"colorStartA"},{"title":"ParticleEmitter#colorStartB","link":"colorStartB"},{"title":"ParticleEmitter#damping","link":"damping"},{"title":"ParticleEmitter#emitConeAngle","link":"emitConeAngle"},{"title":"ParticleEmitter#emitParticle","link":"emitParticle","description":"

Spawn one particle

"},{"title":"ParticleEmitter#emitRate","link":"emitRate"},{"title":"ParticleEmitter#emitSize","link":"emitSize"},{"title":"ParticleEmitter#emitTime","link":"emitTime"},{"title":"ParticleEmitter#fadeRate","link":"fadeRate"},{"title":"ParticleEmitter#gravityScale","link":"gravityScale"},{"title":"ParticleEmitter#localSpace","link":"localSpace"},{"title":"ParticleEmitter#particleConeAngle","link":"particleConeAngle"},{"title":"ParticleEmitter#particleTime","link":"particleTime"},{"title":"ParticleEmitter#randomColorLinear","link":"randomColorLinear"},{"title":"ParticleEmitter#randomness","link":"randomness"},{"title":"ParticleEmitter#sizeEnd","link":"sizeEnd"},{"title":"ParticleEmitter#sizeStart","link":"sizeStart"},{"title":"ParticleEmitter#speed","link":"speed"},{"title":"ParticleEmitter#trailScale","link":"trailScale"},{"title":"ParticleEmitter#update","link":"update","description":"

Update the emitter to spawn particles, called automatically by engine once each frame

"},{"title":"Random","link":"Random","description":"

Random global functions

"},{"title":"Random.rand","link":"rand","description":"

Returns a random value between the two values passed in

"},{"title":"Random.randColor","link":"randColor","description":"

Returns a random color between the two passed in colors, combine components if linear

"},{"title":"Random.randInCircle","link":"randInCircle","description":"

Returns a random Vector2 within a circular shape

"},{"title":"Random.randInt","link":"randInt","description":"

Returns a floored random value the two values passed in

"},{"title":"Random.randSign","link":"randSign","description":"

Randomly returns either -1 or 1

"},{"title":"Random.randVector","link":"randVector","description":"

Returns a random Vector2 with the passed in length

"},{"title":"RandomGenerator","link":"RandomGenerator","description":"

Create a random number generator with the seed passed in

"},{"title":"RandomGenerator#float","link":"float","description":"

Returns a seeded random value between the two values passed in

"},{"title":"RandomGenerator#int","link":"int","description":"

Returns a floored seeded random value the two values passed in

"},{"title":"RandomGenerator#seed","link":"seed"},{"title":"RandomGenerator#sign","link":"sign","description":"

Randomly returns either -1 or 1 deterministically

"},{"title":"Settings","link":"Settings","description":"

LittleJS Engine Settings

\n"},{"title":"Settings.cameraPos","link":"cameraPos","description":"

Position of camera in world space

"},{"title":"Settings.cameraScale","link":"cameraScale","description":"

Scale of camera in world space

"},{"title":"Settings.canvasFixedSize","link":"canvasFixedSize","description":"

Fixed size of the canvas, if enabled canvas size never changes

\n"},{"title":"Settings.canvasMaxSize","link":"canvasMaxSize","description":"

The max size of the canvas, centered if window is larger

"},{"title":"Settings.canvasPixelated","link":"canvasPixelated","description":"

Disables filtering for crisper pixel art if true

"},{"title":"Settings.enablePhysicsSolver","link":"enablePhysicsSolver","description":"

Enable physics solver for collisions between objects

"},{"title":"Settings.fontDefault","link":"fontDefault","description":"

Default font used for text rendering

"},{"title":"Settings.gamepadDirectionEmulateStick","link":"gamepadDirectionEmulateStick","description":"

If true, the dpad input is also routed to the left analog stick (for better accessability)

"},{"title":"Settings.gamepadsEnable","link":"gamepadsEnable","description":"

Should gamepads be allowed

"},{"title":"Settings.glEnable","link":"glEnable","description":"

Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)

"},{"title":"Settings.glOverlay","link":"glOverlay","description":"

Fixes slow rendering in some browsers by not compositing the WebGL canvas

"},{"title":"Settings.gravity","link":"gravity","description":"

How much gravity to apply to objects along the Y axis, negative is down

"},{"title":"Settings.inputWASDEmulateDirection","link":"inputWASDEmulateDirection","description":"

If true the WASD keys are also routed to the direction keys (for better accessability)

"},{"title":"Settings.medalDisplayIconSize","link":"medalDisplayIconSize","description":"

Size of icon in medal display

"},{"title":"Settings.medalDisplaySize","link":"medalDisplaySize","description":"

Size of medal display

"},{"title":"Settings.medalDisplaySlideTime","link":"medalDisplaySlideTime","description":"

How quickly to slide on/off medals in seconds

"},{"title":"Settings.medalDisplayTime","link":"medalDisplayTime","description":"

How long to show medals for in seconds

"},{"title":"Settings.medalsPreventUnlock","link":"medalsPreventUnlock","description":"

Set to stop medals from being unlockable (like if cheats are enabled)

"},{"title":"Settings.objectDefaultAngleDamping","link":"objectDefaultAngleDamping","description":"

How much to slow angular velocity each frame (0-1)

"},{"title":"Settings.objectDefaultDamping","link":"objectDefaultDamping","description":"

How much to slow velocity by each frame (0-1)

"},{"title":"Settings.objectDefaultElasticity","link":"objectDefaultElasticity","description":"

How much to bounce when a collision occurs (0-1)

"},{"title":"Settings.objectDefaultFriction","link":"objectDefaultFriction","description":"

How much to slow when touching (0-1)

"},{"title":"Settings.objectDefaultMass","link":"objectDefaultMass","description":"

Default object mass for collison calcuations (how heavy objects are)

"},{"title":"Settings.objectMaxSpeed","link":"objectMaxSpeed","description":"

Clamp max speed to avoid fast objects missing collisions

"},{"title":"Settings.particleEmitRateScale","link":"particleEmitRateScale","description":"

Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)

"},{"title":"Settings.setCameraPos","link":"setCameraPos","description":"

Set position of camera in world space

"},{"title":"Settings.setCameraScale","link":"setCameraScale","description":"

Set scale of camera in world space

"},{"title":"Settings.setCanvasFixedSize","link":"setCanvasFixedSize","description":"

Set fixed size of the canvas

"},{"title":"Settings.setCanvasMaxSize","link":"setCanvasMaxSize","description":"

Set max size of the canvas

"},{"title":"Settings.setCanvasPixelated","link":"setCanvasPixelated","description":"

Disables anti aliasing for pixel art if true

"},{"title":"Settings.setEnablePhysicsSolver","link":"setEnablePhysicsSolver","description":"

Set if collisions between objects are enabled

"},{"title":"Settings.setFontDefault","link":"setFontDefault","description":"

Set default font used for text rendering

"},{"title":"Settings.setGamepadDirectionEmulateStick","link":"setGamepadDirectionEmulateStick","description":"

Set if the dpad input is also routed to the left analog stick

"},{"title":"Settings.setGamepadsEnable","link":"setGamepadsEnable","description":"

Set if gamepads are enabled

"},{"title":"Settings.setGlEnable","link":"setGlEnable","description":"

Set if webgl rendering is enabled

"},{"title":"Settings.setGlOverlay","link":"setGlOverlay","description":"

Set to not composite the WebGL canvas

"},{"title":"Settings.setGravity","link":"setGravity","description":"

Set how much gravity to apply to objects along the Y axis

"},{"title":"Settings.setInputWASDEmulateDirection","link":"setInputWASDEmulateDirection","description":"

Set if true the WASD keys are also routed to the direction keys

"},{"title":"Settings.setMedalDisplayIconSize","link":"setMedalDisplayIconSize","description":"

Set size of icon in medal display

"},{"title":"Settings.setMedalDisplaySize","link":"setMedalDisplaySize","description":"

Set size of medal display

"},{"title":"Settings.setMedalDisplaySlideTime","link":"setMedalDisplaySlideTime","description":"

Set how quickly to slide on/off medals in seconds

"},{"title":"Settings.setMedalDisplayTime","link":"setMedalDisplayTime","description":"

Set how long to show medals for in seconds

"},{"title":"Settings.setMedalsPreventUnlock","link":"setMedalsPreventUnlock","description":"

Set to stop medals from being unlockable

"},{"title":"Settings.setObjectDefaultAngleDamping","link":"setObjectDefaultAngleDamping","description":"

Set how much to slow angular velocity each frame

"},{"title":"Settings.setObjectDefaultDamping","link":"setObjectDefaultDamping","description":"

Set how much to slow velocity by each frame

"},{"title":"Settings.setObjectDefaultElasticity","link":"setObjectDefaultElasticity","description":"

Set how much to bounce when a collision occur

"},{"title":"Settings.setObjectDefaultFriction","link":"setObjectDefaultFriction","description":"

Set how much to slow when touching

"},{"title":"Settings.setObjectDefaultMass","link":"setObjectDefaultMass","description":"

Set default object mass for collison calcuations

"},{"title":"Settings.setObjectMaxSpeed","link":"setObjectMaxSpeed","description":"

Set max speed to avoid fast objects missing collisions

"},{"title":"Settings.setParticleEmitRateScale","link":"setParticleEmitRateScale","description":"

Set to scales emit rate of particles

"},{"title":"Settings.setSoundDefaultRange","link":"setSoundDefaultRange","description":"

Set default range where sound no longer plays

"},{"title":"Settings.setSoundDefaultTaper","link":"setSoundDefaultTaper","description":"

Set default range percent to start tapering off sound

"},{"title":"Settings.setSoundEnable","link":"setSoundEnable","description":"

Set to disable all audio code

"},{"title":"Settings.setSoundVolume","link":"setSoundVolume","description":"

Set volume scale to apply to all sound, music and speech

"},{"title":"Settings.setTileFixBleedScale","link":"setTileFixBleedScale","description":"

Set to prevent tile bleeding from neighbors in pixels

"},{"title":"Settings.setTileSizeDefault","link":"setTileSizeDefault","description":"

Set default size of tiles in pixels

"},{"title":"Settings.setTouchGamepadAlpha","link":"setTouchGamepadAlpha","description":"

Set transparency of touch gamepad overlay

"},{"title":"Settings.setTouchGamepadAnalog","link":"setTouchGamepadAnalog","description":"

Set if touch gamepad should be analog stick or 8 way dpad

"},{"title":"Settings.setTouchGamepadEnable","link":"setTouchGamepadEnable","description":"

Set if touch gamepad should appear on mobile devices

"},{"title":"Settings.setTouchGamepadSize","link":"setTouchGamepadSize","description":"

Set size of virutal gamepad for touch devices in pixels

"},{"title":"Settings.setVibrateEnable","link":"setVibrateEnable","description":"

Set to allow vibration hardware if it exists

"},{"title":"Settings.soundDefaultRange","link":"soundDefaultRange","description":"

Default range where sound no longer plays

"},{"title":"Settings.soundDefaultTaper","link":"soundDefaultTaper","description":"

Default range percent to start tapering off sound (0-1)

"},{"title":"Settings.soundEnable","link":"soundEnable","description":"

All audio code can be disabled and removed from build

"},{"title":"Settings.soundVolume","link":"soundVolume","description":"

Volume scale to apply to all sound, music and speech

"},{"title":"Settings.tileFixBleedScale","link":"tileFixBleedScale","description":"

Prevent tile bleeding from neighbors in pixels

"},{"title":"Settings.tileSizeDefault","link":"tileSizeDefault","description":"

Default size of tiles in pixels

"},{"title":"Settings.touchGamepadAlpha","link":"touchGamepadAlpha","description":"

Transparency of touch gamepad overlay

"},{"title":"Settings.touchGamepadAnalog","link":"touchGamepadAnalog","description":"

True if touch gamepad should be analog stick or false to use if 8 way dpad

"},{"title":"Settings.touchGamepadEnable","link":"touchGamepadEnable","description":"

True if touch gamepad should appear on mobile devices

\n"},{"title":"Settings.touchGamepadSize","link":"touchGamepadSize","description":"

Size of virutal gamepad for touch devices in pixels

"},{"title":"Settings.vibrateEnable","link":"vibrateEnable","description":"

Allow vibration hardware if it exists

"},{"title":"Sound","link":"Sound","description":"

Create a sound object and cache the zzfx samples for later use

"},{"title":"Sound#play","link":"play","description":"

Play the sound

"},{"title":"Sound#playNote","link":"playNote","description":"

Play the sound as a note with a semitone offset

"},{"title":"Sound#randomness","link":"randomness"},{"title":"Sound#range","link":"range"},{"title":"Sound#taper","link":"taper"},{"title":"SoundWave","link":"SoundWave","description":"

Create a sound object and cache the wave file for later use

"},{"title":"TileCollision","link":"TileCollision","description":"

LittleJS Tile Layer System

\n"},{"title":"TileCollision.getTileCollisionData","link":"getTileCollisionData","description":"

Get tile collision data

"},{"title":"TileCollision.initTileCollision","link":"initTileCollision","description":"

Clear and initialize tile collision

"},{"title":"TileCollision.setTileCollisionData","link":"setTileCollisionData","description":"

Set tile collision data

"},{"title":"TileCollision.tileCollision","link":"tileCollision","description":"

The tile collision layer array, use setTileCollisionData and getTileCollisionData to access

"},{"title":"TileCollision.tileCollisionRaycast","link":"tileCollisionRaycast","description":"

Return the center of tile if any that is hit (does not return the exact intersection)

"},{"title":"TileCollision.tileCollisionSize","link":"tileCollisionSize","description":"

Size of the tile collision layer

"},{"title":"TileCollision.tileCollisionTest","link":"tileCollisionTest","description":"

Check if collision with another object should occur

"},{"title":"TileLayer","link":"TileLayer","description":"

Create a tile layer object

"},{"title":"TileLayer#canvas","link":"canvas"},{"title":"TileLayer#context","link":"context"},{"title":"TileLayer#drawAllTileData","link":"drawAllTileData","description":"

Draw all the tiles in this layer

"},{"title":"TileLayer#drawCanvas2D","link":"drawCanvas2D","description":"

Draw directly to the 2D canvas in world space (bipass webgl)

"},{"title":"TileLayer#drawRect","link":"drawRect","description":"

Draw a rectangle directly onto the layer canvas

"},{"title":"TileLayer#drawTile","link":"drawTile","description":"

Draw a tile directly onto the layer canvas

"},{"title":"TileLayer#drawTileData","link":"drawTileData","description":"

Draw the tile at a given position

"},{"title":"TileLayer#getData","link":"getData","description":"

Get data at a given position in the array

"},{"title":"TileLayer#isOverlay","link":"isOverlay"},{"title":"TileLayer#redraw","link":"redraw","description":"

Draw all the tile data to an offscreen canvas

\n"},{"title":"TileLayer#redrawEnd","link":"redrawEnd","description":"

Call to end the redraw process

"},{"title":"TileLayer#redrawStart","link":"redrawStart","description":"

Call to start the redraw process

"},{"title":"TileLayer#scale","link":"scale"},{"title":"TileLayer#setData","link":"setData","description":"

Set data at a given position in the array

"},{"title":"TileLayerData","link":"TileLayerData","description":"

Create a tile layer data object, one for each tile in a TileLayer

"},{"title":"TileLayerData#clear","link":"clear","description":"

Set this tile to clear, it will not be rendered

"},{"title":"TileLayerData#color","link":"color"},{"title":"TileLayerData#direction","link":"direction"},{"title":"TileLayerData#mirror","link":"mirror"},{"title":"TileLayerData#tile","link":"tile"},{"title":"Timer","link":"Timer","description":"

Create a timer object set time passed in

"},{"title":"Timer#active","link":"active","description":"

Returns true if set and has not elapsed

"},{"title":"Timer#elapsed","link":"elapsed","description":"

Returns true if set and elapsed

"},{"title":"Timer#get","link":"get","description":"

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

"},{"title":"Timer#getPercent","link":"getPercent","description":"

Get percentage elapsed based on time it was set to, returns 0 if not set

"},{"title":"Timer#isSet","link":"isSet","description":"

Returns true if set

"},{"title":"Timer#set","link":"set","description":"

Set the timer with seconds passed in

"},{"title":"Timer#toString","link":"toString","description":"

Returns this timer expressed as a string

"},{"title":"Timer#unset","link":"unset","description":"

Unset the timer

"},{"title":"Timer#valueOf","link":"valueOf","description":"

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

"},{"title":"Utilities","link":"Utilities","description":"

LittleJS Utility Classes and Functions

\n"},{"title":"Utilities.PI","link":"PI","description":"

A shortcut to get Math.PI

"},{"title":"Utilities.abs","link":"abs","description":"

Returns absoulte value of value passed in

"},{"title":"Utilities.clamp","link":"clamp","description":"

Clamps the value beween max and min

"},{"title":"Utilities.distanceAngle","link":"distanceAngle","description":"

Returns signed wrapped distance between the two angles passed in

"},{"title":"Utilities.distanceWrap","link":"distanceWrap","description":"

Returns signed wrapped distance between the two values passed in

"},{"title":"Utilities.formatTime","link":"formatTime","description":"

Formats seconds to mm:ss style for display purposes

"},{"title":"Utilities.hsl","link":"hsl","description":"

Create a color object with HSLA values

"},{"title":"Utilities.isOverlapping","link":"isOverlapping","description":"

Returns true if two axis aligned bounding boxes are overlapping

"},{"title":"Utilities.isVector2","link":"isVector2","description":"

Check if object is a valid Vector2

"},{"title":"Utilities.lerp","link":"lerp","description":"

Linearly interpolates between values passed in using percent

"},{"title":"Utilities.lerpAngle","link":"lerpAngle","description":"

Linearly interpolates between the angles passed in with wrappping

"},{"title":"Utilities.lerpWrap","link":"lerpWrap","description":"

Linearly interpolates between values passed in with wrappping

"},{"title":"Utilities.max","link":"max","description":"

Returns highest of two values passed in

"},{"title":"Utilities.min","link":"min","description":"

Returns lowest of two values passed in

"},{"title":"Utilities.mod","link":"mod","description":"

Returns first parm modulo the second param, but adjusted so negative numbers work as expected

"},{"title":"Utilities.nearestPowerOfTwo","link":"nearestPowerOfTwo","description":"

Returns the nearest power of two not less then the value

"},{"title":"Utilities.percent","link":"percent","description":"

Returns what percentage the value is between valueA and valueB

"},{"title":"Utilities.rgb","link":"rgb","description":"

Create a color object with RGBA values

"},{"title":"Utilities.sign","link":"sign","description":"

Returns the sign of value passed in (also returns 1 if 0)

"},{"title":"Utilities.smoothStep","link":"smoothStep","description":"

Applies smoothstep function to the percentage value

"},{"title":"Utilities.vec2","link":"vec2","description":"

Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar

"},{"title":"Utilities.wave","link":"wave","description":"

Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default

"},{"title":"Vector2","link":"Vector2","description":"

Create a 2D vector with the x and y passed in, can also be created with vec2()

"},{"title":"Vector2#add","link":"add","description":"

Returns a copy of this vector plus the vector passed in

"},{"title":"Vector2#angle","link":"angle","description":"

Returns the angle of this vector, up is angle 0

"},{"title":"Vector2#area","link":"area","description":"

Returns the area this vector covers as a rectangle

"},{"title":"Vector2#arrayCheck","link":"arrayCheck","description":"

Returns true if this vector is within the bounds of an array size passed in

"},{"title":"Vector2#clampLength","link":"clampLength","description":"

Returns a new vector clamped to length passed in

"},{"title":"Vector2#copy","link":"copy","description":"

Returns a new vector that is a copy of this

"},{"title":"Vector2#cross","link":"cross","description":"

Returns the cross product of this and the vector passed in

"},{"title":"Vector2#direction","link":"direction","description":"

Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)

"},{"title":"Vector2#distance","link":"distance","description":"

Returns the distance from this vector to vector passed in

"},{"title":"Vector2#distanceSquared","link":"distanceSquared","description":"

Returns the distance squared from this vector to vector passed in

"},{"title":"Vector2#divide","link":"divide","description":"

Returns a copy of this vector divided by the vector passed in

"},{"title":"Vector2#dot","link":"dot","description":"

Returns the dot product of this and the vector passed in

"},{"title":"Vector2#floor","link":"floor","description":"

Returns a copy of this vector with each axis floored

"},{"title":"Vector2#invert","link":"invert","description":"

Returns a copy of this vector that has been inverted

"},{"title":"Vector2#length","link":"length","description":"

Returns the length of this vector

"},{"title":"Vector2#lengthSquared","link":"lengthSquared","description":"

Returns the length of this vector squared

"},{"title":"Vector2#lerp","link":"lerp","description":"

Returns a new vector that is p percent between this and the vector passed in

"},{"title":"Vector2#multiply","link":"multiply","description":"

Returns a copy of this vector times the vector passed in

"},{"title":"Vector2#normalize","link":"normalize","description":"

Returns a new vector in same direction as this one with the length passed in

"},{"title":"Vector2#rotate","link":"rotate","description":"

Returns copy of this vector rotated by the angle passed in

"},{"title":"Vector2#scale","link":"scale","description":"

Returns a copy of this vector scaled by the vector passed in

"},{"title":"Vector2#setAngle","link":"setAngle","description":"

Sets this vector with angle and length passed in

"},{"title":"Vector2#subtract","link":"subtract","description":"

Returns a copy of this vector minus the vector passed in

"},{"title":"Vector2#toString","link":"toString","description":"

Returns this vector expressed as a string

"},{"title":"Vector2#x","link":"x"},{"title":"Vector2#y","link":"y"},{"title":"WebGL","link":"WebGL","description":"

LittleJS WebGL Interface

\n"},{"title":"WebGL.glCanvas","link":"glCanvas","description":"

The WebGL canvas which appears above the main canvas and below the overlay canvas

"},{"title":"WebGL.glCompileShader","link":"glCompileShader","description":"

Compile WebGL shader of the given type, will throw errors if in debug mode

"},{"title":"WebGL.glContext","link":"glContext","description":"

2d context for glCanvas

"},{"title":"WebGL.glCopyToContext","link":"glCopyToContext","description":"

Draw any sprites still in the buffer, copy to main canvas and clear

"},{"title":"WebGL.glCreateProgram","link":"glCreateProgram","description":"

Create WebGL program with given shaders

"},{"title":"WebGL.glCreateTexture","link":"glCreateTexture","description":"

Create WebGL texture from an image and set the texture settings

"},{"title":"WebGL.glDraw","link":"glDraw","description":"

Add a sprite to the gl draw list, used by all gl draw functions

"},{"title":"WebGL.glDrawPoints","link":"glDrawPoints","description":"

Add a convex polygon to the gl draw list

"},{"title":"WebGL.glFlush","link":"glFlush","description":"

Draw all sprites and clear out the buffer, called automatically by the system whenever necessary

"},{"title":"WebGL.glInitPostProcess","link":"glInitPostProcess","description":"

Set up a post processing shader

"},{"title":"WebGL.glSetBlendMode","link":"glSetBlendMode","description":"

Set the WebGl blend mode, normally you should call setBlendMode instead

"},{"title":"WebGL.glSetTexture","link":"glSetTexture","description":"

Set the WebGl texture, not normally necessary unless multiple tile sheets are used

\n"},{"title":"WebGL.glTileTexture","link":"glTileTexture","description":"

Main tile sheet texture automatically loaded by engine

"}]} \ No newline at end of file +{"list":[{"title":"Audio","link":"Audio","description":"

LittleJS Audio System

\n"},{"title":"Audio.audioContext","link":"audioContext","description":"

Audio context used by the engine

"},{"title":"Audio.getNoteFrequency","link":"getNoteFrequency","description":"

Get frequency of a note on a musical scale

"},{"title":"Audio.playAudioFile","link":"playAudioFile","description":"

Play an mp3, ogg, or wav audio from a local file or url

"},{"title":"Audio.playSamples","link":"playSamples","description":"

Play cached audio samples with given settings

"},{"title":"Audio.speak","link":"speak","description":"

Speak text with passed in settings

"},{"title":"Audio.speakStop","link":"speakStop","description":"

Stop all queued speech

"},{"title":"Audio.zzfx","link":"zzfx","description":"

Generate and play a ZzFX sound

\n

Create sounds using the ZzFX Sound Designer.

"},{"title":"Audio.zzfxG","link":"zzfxG","description":"

Generate samples for a ZzFX sound

"},{"title":"Audio.zzfxM","link":"zzfxM","description":"

Generate samples for a ZzFM song with given parameters

"},{"title":"Audio.zzfxR","link":"zzfxR","description":"

Sample rate used for all ZzFX sounds

"},{"title":"Color","link":"Color","description":"

Create a color with the rgba components passed in, white by default

"},{"title":"Color#a","link":"a"},{"title":"Color#add","link":"add","description":"

Returns a copy of this color plus the color passed in

"},{"title":"Color#b","link":"b"},{"title":"Color#clamp","link":"clamp","description":"

Returns a copy of this color clamped to the valid range between 0 and 1

"},{"title":"Color#copy","link":"copy","description":"

Returns a new color that is a copy of this

"},{"title":"Color#divide","link":"divide","description":"

Returns a copy of this color divided by the color passed in

"},{"title":"Color#g","link":"g"},{"title":"Color#getHSLA","link":"getHSLA","description":"

Returns this color expressed in hsla format

"},{"title":"Color#lerp","link":"lerp","description":"

Returns a new color that is p percent between this and the color passed in

"},{"title":"Color#multiply","link":"multiply","description":"

Returns a copy of this color times the color passed in

"},{"title":"Color#mutate","link":"mutate","description":"

Returns a new color that has each component randomly adjusted

"},{"title":"Color#r","link":"r"},{"title":"Color#rgbaInt","link":"rgbaInt","description":"

Returns this color expressed as 32 bit RGBA value

"},{"title":"Color#scale","link":"scale","description":"

Returns a copy of this color scaled by the value passed in, alpha can be scaled separately

"},{"title":"Color#setHSLA","link":"setHSLA","description":"

Sets this color given a hue, saturation, lightness, and alpha

"},{"title":"Color#setHex","link":"setHex","description":"

Set this color from a hex code

"},{"title":"Color#subtract","link":"subtract","description":"

Returns a copy of this color minus the color passed in

"},{"title":"Color#toString","link":"toString","description":"

Returns this color expressed as a hex color code

"},{"title":"Debug","link":"Debug","description":"

LittleJS Debug System

\n"},{"title":"Debug.ASSERT","link":"ASSERT","description":"

Asserts if the experssion is false, does not do anything in release builds

"},{"title":"Debug.debug","link":"debug","description":"

True if debug is enabled

"},{"title":"Debug.debugAABB","link":"debugAABB","description":"

Draw a debug axis aligned bounding box in world space

"},{"title":"Debug.debugCircle","link":"debugCircle","description":"

Draw a debug circle in world space

"},{"title":"Debug.debugClear","link":"debugClear","description":"

Clear all debug primitives in the list

"},{"title":"Debug.debugKey","link":"debugKey","description":"

Key code used to toggle debug mode, Esc by default

"},{"title":"Debug.debugLine","link":"debugLine","description":"

Draw a debug line in world space

"},{"title":"Debug.debugPoint","link":"debugPoint","description":"

Draw a debug point in world space

"},{"title":"Debug.debugPointSize","link":"debugPointSize","description":"

Size to render debug points by default

"},{"title":"Debug.debugRect","link":"debugRect","description":"

Draw a debug rectangle in world space

"},{"title":"Debug.debugSaveCanvas","link":"debugSaveCanvas","description":"

Save a canvas to disk

"},{"title":"Debug.debugSaveDataURL","link":"debugSaveDataURL","description":"

Save a data url to disk

"},{"title":"Debug.debugSaveText","link":"debugSaveText","description":"

Save a text file to disk

"},{"title":"Debug.debugText","link":"debugText","description":"

Draw a debug axis aligned bounding box in world space

"},{"title":"Debug.enableAsserts","link":"enableAsserts","description":"

True if asserts are enaled

"},{"title":"Debug.setDebugKey","link":"setDebugKey","description":"

Set key code used to toggle debug mode, Esc by default

"},{"title":"Debug.setShowWatermark","link":"setShowWatermark","description":"

Set if watermark with FPS should be shown

"},{"title":"Debug.showWatermark","link":"showWatermark","description":"

True if watermark with FPS should be shown, false in release builds

"},{"title":"Draw","link":"Draw","description":"

LittleJS Drawing System

\n\n

LittleJS uses a hybrid rendering solution with the best of both Canvas2D and WebGL.\nThere are 3 canvas/contexts available to draw to...\nmainCanvas - 2D background canvas, non WebGL stuff like tile layers are drawn here.\nglCanvas - Used by the accelerated WebGL batch rendering system.\noverlayCanvas - Another 2D canvas that appears on top of the other 2 canvases.

\n

The WebGL rendering system is very fast with some caveats...

\n\n

The LittleJS rendering solution is intentionally simple, feel free to adjust it for your needs!

"},{"title":"Draw.drawCanvas2D","link":"drawCanvas2D","description":"

Draw directly to a 2d canvas context in world space

"},{"title":"Draw.drawLine","link":"drawLine","description":"

Draw colored line between two points

"},{"title":"Draw.drawPoly","link":"drawPoly","description":"

Draw colored polygon using passed in points

"},{"title":"Draw.drawRect","link":"drawRect","description":"

Draw colored rect centered on pos

"},{"title":"Draw.drawText","link":"drawText","description":"

Draw text on overlay canvas in world space\nAutomatically splits new lines into rows

"},{"title":"Draw.drawTextScreen","link":"drawTextScreen","description":"

Draw text on overlay canvas in screen space\nAutomatically splits new lines into rows

"},{"title":"Draw.drawTile","link":"drawTile","description":"

Draw textured tile centered in world space, with color applied if using WebGL

"},{"title":"Draw.isFullscreen","link":"isFullscreen","description":"

Returns true if fullscreen mode is active

"},{"title":"Draw.mainCanvas","link":"mainCanvas","description":"

The primary 2D canvas visible to the user

"},{"title":"Draw.mainCanvasSize","link":"mainCanvasSize","description":"

The size of the main canvas (and other secondary canvases)

"},{"title":"Draw.mainContext","link":"mainContext","description":"

2d context for mainCanvas

"},{"title":"Draw.overlayCanvas","link":"overlayCanvas","description":"

A canvas that appears on top of everything the same size as mainCanvas

"},{"title":"Draw.overlayContext","link":"overlayContext","description":"

2d context for overlayCanvas

"},{"title":"Draw.screenToWorld","link":"screenToWorld","description":"

Convert from screen to world space coordinates

"},{"title":"Draw.setBlendMode","link":"setBlendMode","description":"

Enable normal or additive blend mode

"},{"title":"Draw.tileImage","link":"tileImage","description":"

Tile sheet for batch rendering system

"},{"title":"Draw.toggleFullscreen","link":"toggleFullscreen","description":"

Toggle fullsceen mode

"},{"title":"Draw.worldToScreen","link":"worldToScreen","description":"

Convert from world to screen space coordinates

"},{"title":"Engine","link":"Engine","description":"

LittleJS - The Tiny JavaScript Game Engine That Can!\nMIT License - Copyright 2021 Frank Force

\n

Engine Features

\n"},{"title":"Engine.engineInit","link":"engineInit","description":"

Start up LittleJS engine with your callback functions

"},{"title":"Engine.engineName","link":"engineName","description":"

Name of engine

"},{"title":"Engine.engineObjects","link":"engineObjects","description":"

Array containing all engine objects

"},{"title":"Engine.engineObjectsCallback","link":"engineObjectsCallback","description":"

Triggers a callback for each object within a given area

"},{"title":"Engine.engineObjectsCollide","link":"engineObjectsCollide","description":"

Array containing only objects that are set to collide with other objects this frame (for optimization)

"},{"title":"Engine.engineObjectsDestroy","link":"engineObjectsDestroy","description":"

Destroy and remove all objects

"},{"title":"Engine.engineObjectsUpdate","link":"engineObjectsUpdate","description":"

Update each engine object, remove destroyed objects, and update time

"},{"title":"Engine.engineVersion","link":"engineVersion","description":"

Version of engine

"},{"title":"Engine.frame","link":"frame","description":"

Current update frame, used to calculate time

"},{"title":"Engine.frameRate","link":"frameRate","description":"

Frames per second to update objects

"},{"title":"Engine.paused","link":"paused","description":"

Is the game paused? Causes time and objects to not be updated

"},{"title":"Engine.setPaused","link":"setPaused","description":"

Set if game is paused

"},{"title":"Engine.time","link":"time","description":"

Current engine time since start in seconds, derived from frame

"},{"title":"Engine.timeDelta","link":"timeDelta","description":"

How many seconds each frame lasts, engine uses a fixed time step

"},{"title":"Engine.timeReal","link":"timeReal","description":"

Actual clock time since start in seconds (not affected by pause or frame rate clamping)

"},{"title":"EngineObject","link":"EngineObject","description":"

Create an engine object and adds it to the list of objects

"},{"title":"EngineObject#addChild","link":"addChild","description":"

Attaches a child to this with a given local transform

"},{"title":"EngineObject#additiveColor","link":"additiveColor"},{"title":"EngineObject#angle","link":"angle"},{"title":"EngineObject#angleDamping","link":"angleDamping"},{"title":"EngineObject#angleVelocity","link":"angleVelocity"},{"title":"EngineObject#applyAcceleration","link":"applyAcceleration","description":"

Apply acceleration to this object (adjust velocity, not affected by mass)

"},{"title":"EngineObject#applyForce","link":"applyForce","description":"

Apply force to this object (adjust velocity, affected by mass)

"},{"title":"EngineObject#collideWithObject","link":"collideWithObject","description":"

Called to check if a object collision should be resolved

"},{"title":"EngineObject#collideWithTile","link":"collideWithTile","description":"

Called to check if a tile collision should be resolved

"},{"title":"EngineObject#collideWithTileRaycast","link":"collideWithTileRaycast","description":"

Called to check if a tile raycast hit

"},{"title":"EngineObject#color","link":"color"},{"title":"EngineObject#damping","link":"damping"},{"title":"EngineObject#destroy","link":"destroy","description":"

Destroy this object, destroy it's children, detach it's parent, and mark it for removal

"},{"title":"EngineObject#drawSize","link":"drawSize"},{"title":"EngineObject#elasticity","link":"elasticity"},{"title":"EngineObject#friction","link":"friction"},{"title":"EngineObject#getAliveTime","link":"getAliveTime","description":"

How long since the object was created

"},{"title":"EngineObject#getMirrorSign","link":"getMirrorSign","description":"

Get the direction of the mirror

"},{"title":"EngineObject#gravityScale","link":"gravityScale"},{"title":"EngineObject#mass","link":"mass"},{"title":"EngineObject#pos","link":"pos"},{"title":"EngineObject#removeChild","link":"removeChild","description":"

Removes a child from this one

"},{"title":"EngineObject#render","link":"render","description":"

Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder

"},{"title":"EngineObject#renderOrder","link":"renderOrder"},{"title":"EngineObject#setCollision","link":"setCollision","description":"

Set how this object collides

"},{"title":"EngineObject#size","link":"size"},{"title":"EngineObject#tileIndex","link":"tileIndex"},{"title":"EngineObject#tileSize","link":"tileSize"},{"title":"EngineObject#toString","link":"toString","description":"

Returns string containg info about this object for debugging

"},{"title":"EngineObject#update","link":"update","description":"

Update the object transform and physics, called automatically by engine once each frame

"},{"title":"EngineObject#velocity","link":"velocity"},{"title":"FontImage","link":"FontImage","description":"

Create an image font

"},{"title":"FontImage#drawText","link":"drawText","description":"

Draw text in world space using the image font

"},{"title":"FontImage#drawTextScreen","link":"drawTextScreen","description":"

Draw text in screen space using the image font

"},{"title":"Input","link":"Input","description":"

LittleJS Input System

\n"},{"title":"Input.clearInput","link":"clearInput","description":"

Clears all input

"},{"title":"Input.gamepadIsDown","link":"gamepadIsDown","description":"

Returns true if gamepad button is down

"},{"title":"Input.gamepadStick","link":"gamepadStick","description":"

Returns gamepad stick value

"},{"title":"Input.gamepadWasPressed","link":"gamepadWasPressed","description":"

Returns true if gamepad button was pressed

"},{"title":"Input.gamepadWasReleased","link":"gamepadWasReleased","description":"

Returns true if gamepad button was released

"},{"title":"Input.isTouchDevice","link":"isTouchDevice","description":"

True if a touch device has been detected

"},{"title":"Input.isUsingGamepad","link":"isUsingGamepad","description":"

Returns true if user is using gamepad (has more recently pressed a gamepad button)

"},{"title":"Input.keyIsDown","link":"keyIsDown","description":"

Returns true if device key is down

"},{"title":"Input.keyWasPressed","link":"keyWasPressed","description":"

Returns true if device key was pressed this frame

"},{"title":"Input.keyWasReleased","link":"keyWasReleased","description":"

Returns true if device key was released this frame

"},{"title":"Input.mouseIsDown","link":"mouseIsDown","description":"

Returns true if mouse button is down

"},{"title":"Input.mousePos","link":"mousePos","description":"

Mouse pos in world space

"},{"title":"Input.mousePosScreen","link":"mousePosScreen","description":"

Mouse pos in screen space

"},{"title":"Input.mouseWasPressed","link":"mouseWasPressed","description":"

Returns true if mouse button was pressed

"},{"title":"Input.mouseWasReleased","link":"mouseWasReleased","description":"

Returns true if mouse button was released

"},{"title":"Input.mouseWheel","link":"mouseWheel","description":"

Mouse wheel delta this frame

"},{"title":"Input.preventDefaultInput","link":"preventDefaultInput","description":"

Prevents input continuing to the default browser handling (false by default)

"},{"title":"Input.vibrate","link":"vibrate","description":"

Pulse the vibration hardware if it exists

"},{"title":"Input.vibrateStop","link":"vibrateStop","description":"

Cancel any ongoing vibration

"},{"title":"Medal","link":"Medal","description":"

Create an medal object and adds it to the list of medals

"},{"title":"Medal#render","link":"render","description":"

Render a medal

"},{"title":"Medal#renderIcon","link":"renderIcon","description":"

Render the icon for a medal

"},{"title":"Medal#unlock","link":"unlock","description":"

Unlocks a medal if not already unlocked

"},{"title":"Medals","link":"Medals","description":"

LittleJS Medal System

\n"},{"title":"Medals.medals","link":"medals","description":"

List of all medals

"},{"title":"Medals.medalsInit","link":"medalsInit","description":"

Initialize medals with a save name used for storage

\n"},{"title":"Medals.newgroundsInit","link":"newgroundsInit","description":"

This can used to enable Newgrounds functionality

"},{"title":"Music","link":"Music","description":"

Create a music object and cache the zzfx music samples for later use

"},{"title":"Music#play","link":"play","description":"

Play the music

"},{"title":"Newgrounds","link":"Newgrounds","description":"

Create a newgrounds object

"},{"title":"Newgrounds#call","link":"call","description":"

Send a message to call a component of the Newgrounds API

"},{"title":"Newgrounds#getScores","link":"getScores","description":"

Get scores from a scoreboard

"},{"title":"Newgrounds#logView","link":"logView","description":"

Send message to log a view

"},{"title":"Newgrounds#postScore","link":"postScore","description":"

Send message to post score

"},{"title":"Newgrounds#unlockMedal","link":"unlockMedal","description":"

Send message to unlock a medal by id

"},{"title":"Particle","link":"Particle","description":"

Create a particle with the given settings

"},{"title":"Particle#render","link":"render","description":"

Render the particle, automatically called each frame, sorted by renderOrder

"},{"title":"ParticleEmitter","link":"ParticleEmitter","description":"

Create a particle system with the given settings

"},{"title":"ParticleEmitter#additive","link":"additive"},{"title":"ParticleEmitter#angleDamping","link":"angleDamping"},{"title":"ParticleEmitter#angleSpeed","link":"angleSpeed"},{"title":"ParticleEmitter#collideTiles","link":"collideTiles"},{"title":"ParticleEmitter#colorEndA","link":"colorEndA"},{"title":"ParticleEmitter#colorEndB","link":"colorEndB"},{"title":"ParticleEmitter#colorStartA","link":"colorStartA"},{"title":"ParticleEmitter#colorStartB","link":"colorStartB"},{"title":"ParticleEmitter#damping","link":"damping"},{"title":"ParticleEmitter#emitConeAngle","link":"emitConeAngle"},{"title":"ParticleEmitter#emitParticle","link":"emitParticle","description":"

Spawn one particle

"},{"title":"ParticleEmitter#emitRate","link":"emitRate"},{"title":"ParticleEmitter#emitSize","link":"emitSize"},{"title":"ParticleEmitter#emitTime","link":"emitTime"},{"title":"ParticleEmitter#fadeRate","link":"fadeRate"},{"title":"ParticleEmitter#gravityScale","link":"gravityScale"},{"title":"ParticleEmitter#localSpace","link":"localSpace"},{"title":"ParticleEmitter#particleConeAngle","link":"particleConeAngle"},{"title":"ParticleEmitter#particleTime","link":"particleTime"},{"title":"ParticleEmitter#randomColorLinear","link":"randomColorLinear"},{"title":"ParticleEmitter#randomness","link":"randomness"},{"title":"ParticleEmitter#sizeEnd","link":"sizeEnd"},{"title":"ParticleEmitter#sizeStart","link":"sizeStart"},{"title":"ParticleEmitter#speed","link":"speed"},{"title":"ParticleEmitter#trailScale","link":"trailScale"},{"title":"ParticleEmitter#update","link":"update","description":"

Update the emitter to spawn particles, called automatically by engine once each frame

"},{"title":"Random","link":"Random","description":"

Random global functions

"},{"title":"Random.rand","link":"rand","description":"

Returns a random value between the two values passed in

"},{"title":"Random.randColor","link":"randColor","description":"

Returns a random color between the two passed in colors, combine components if linear

"},{"title":"Random.randInCircle","link":"randInCircle","description":"

Returns a random Vector2 within a circular shape

"},{"title":"Random.randInt","link":"randInt","description":"

Returns a floored random value the two values passed in

"},{"title":"Random.randSign","link":"randSign","description":"

Randomly returns either -1 or 1

"},{"title":"Random.randVector","link":"randVector","description":"

Returns a random Vector2 with the passed in length

"},{"title":"RandomGenerator","link":"RandomGenerator","description":"

Create a random number generator with the seed passed in

"},{"title":"RandomGenerator#float","link":"float","description":"

Returns a seeded random value between the two values passed in

"},{"title":"RandomGenerator#int","link":"int","description":"

Returns a floored seeded random value the two values passed in

"},{"title":"RandomGenerator#seed","link":"seed"},{"title":"RandomGenerator#sign","link":"sign","description":"

Randomly returns either -1 or 1 deterministically

"},{"title":"Settings","link":"Settings","description":"

LittleJS Engine Settings

\n"},{"title":"Settings.cameraPos","link":"cameraPos","description":"

Position of camera in world space

"},{"title":"Settings.cameraScale","link":"cameraScale","description":"

Scale of camera in world space

"},{"title":"Settings.canvasFixedSize","link":"canvasFixedSize","description":"

Fixed size of the canvas, if enabled canvas size never changes

\n"},{"title":"Settings.canvasMaxSize","link":"canvasMaxSize","description":"

The max size of the canvas, centered if window is larger

"},{"title":"Settings.canvasPixelated","link":"canvasPixelated","description":"

Disables filtering for crisper pixel art if true

"},{"title":"Settings.enablePhysicsSolver","link":"enablePhysicsSolver","description":"

Enable physics solver for collisions between objects

"},{"title":"Settings.fontDefault","link":"fontDefault","description":"

Default font used for text rendering

"},{"title":"Settings.gamepadDirectionEmulateStick","link":"gamepadDirectionEmulateStick","description":"

If true, the dpad input is also routed to the left analog stick (for better accessability)

"},{"title":"Settings.gamepadsEnable","link":"gamepadsEnable","description":"

Should gamepads be allowed

"},{"title":"Settings.glEnable","link":"glEnable","description":"

Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)

"},{"title":"Settings.glOverlay","link":"glOverlay","description":"

Fixes slow rendering in some browsers by not compositing the WebGL canvas

"},{"title":"Settings.gravity","link":"gravity","description":"

How much gravity to apply to objects along the Y axis, negative is down

"},{"title":"Settings.inputWASDEmulateDirection","link":"inputWASDEmulateDirection","description":"

If true the WASD keys are also routed to the direction keys (for better accessability)

"},{"title":"Settings.medalDisplayIconSize","link":"medalDisplayIconSize","description":"

Size of icon in medal display

"},{"title":"Settings.medalDisplaySize","link":"medalDisplaySize","description":"

Size of medal display

"},{"title":"Settings.medalDisplaySlideTime","link":"medalDisplaySlideTime","description":"

How quickly to slide on/off medals in seconds

"},{"title":"Settings.medalDisplayTime","link":"medalDisplayTime","description":"

How long to show medals for in seconds

"},{"title":"Settings.medalsPreventUnlock","link":"medalsPreventUnlock","description":"

Set to stop medals from being unlockable (like if cheats are enabled)

"},{"title":"Settings.objectDefaultAngleDamping","link":"objectDefaultAngleDamping","description":"

How much to slow angular velocity each frame (0-1)

"},{"title":"Settings.objectDefaultDamping","link":"objectDefaultDamping","description":"

How much to slow velocity by each frame (0-1)

"},{"title":"Settings.objectDefaultElasticity","link":"objectDefaultElasticity","description":"

How much to bounce when a collision occurs (0-1)

"},{"title":"Settings.objectDefaultFriction","link":"objectDefaultFriction","description":"

How much to slow when touching (0-1)

"},{"title":"Settings.objectDefaultMass","link":"objectDefaultMass","description":"

Default object mass for collison calcuations (how heavy objects are)

"},{"title":"Settings.objectMaxSpeed","link":"objectMaxSpeed","description":"

Clamp max speed to avoid fast objects missing collisions

"},{"title":"Settings.particleEmitRateScale","link":"particleEmitRateScale","description":"

Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)

"},{"title":"Settings.setCameraPos","link":"setCameraPos","description":"

Set position of camera in world space

"},{"title":"Settings.setCameraScale","link":"setCameraScale","description":"

Set scale of camera in world space

"},{"title":"Settings.setCanvasFixedSize","link":"setCanvasFixedSize","description":"

Set fixed size of the canvas

"},{"title":"Settings.setCanvasMaxSize","link":"setCanvasMaxSize","description":"

Set max size of the canvas

"},{"title":"Settings.setCanvasPixelated","link":"setCanvasPixelated","description":"

Disables anti aliasing for pixel art if true

"},{"title":"Settings.setEnablePhysicsSolver","link":"setEnablePhysicsSolver","description":"

Set if collisions between objects are enabled

"},{"title":"Settings.setFontDefault","link":"setFontDefault","description":"

Set default font used for text rendering

"},{"title":"Settings.setGamepadDirectionEmulateStick","link":"setGamepadDirectionEmulateStick","description":"

Set if the dpad input is also routed to the left analog stick

"},{"title":"Settings.setGamepadsEnable","link":"setGamepadsEnable","description":"

Set if gamepads are enabled

"},{"title":"Settings.setGlEnable","link":"setGlEnable","description":"

Set if webgl rendering is enabled

"},{"title":"Settings.setGlOverlay","link":"setGlOverlay","description":"

Set to not composite the WebGL canvas

"},{"title":"Settings.setGravity","link":"setGravity","description":"

Set how much gravity to apply to objects along the Y axis

"},{"title":"Settings.setInputWASDEmulateDirection","link":"setInputWASDEmulateDirection","description":"

Set if true the WASD keys are also routed to the direction keys

"},{"title":"Settings.setMedalDisplayIconSize","link":"setMedalDisplayIconSize","description":"

Set size of icon in medal display

"},{"title":"Settings.setMedalDisplaySize","link":"setMedalDisplaySize","description":"

Set size of medal display

"},{"title":"Settings.setMedalDisplaySlideTime","link":"setMedalDisplaySlideTime","description":"

Set how quickly to slide on/off medals in seconds

"},{"title":"Settings.setMedalDisplayTime","link":"setMedalDisplayTime","description":"

Set how long to show medals for in seconds

"},{"title":"Settings.setMedalsPreventUnlock","link":"setMedalsPreventUnlock","description":"

Set to stop medals from being unlockable

"},{"title":"Settings.setObjectDefaultAngleDamping","link":"setObjectDefaultAngleDamping","description":"

Set how much to slow angular velocity each frame

"},{"title":"Settings.setObjectDefaultDamping","link":"setObjectDefaultDamping","description":"

Set how much to slow velocity by each frame

"},{"title":"Settings.setObjectDefaultElasticity","link":"setObjectDefaultElasticity","description":"

Set how much to bounce when a collision occur

"},{"title":"Settings.setObjectDefaultFriction","link":"setObjectDefaultFriction","description":"

Set how much to slow when touching

"},{"title":"Settings.setObjectDefaultMass","link":"setObjectDefaultMass","description":"

Set default object mass for collison calcuations

"},{"title":"Settings.setObjectMaxSpeed","link":"setObjectMaxSpeed","description":"

Set max speed to avoid fast objects missing collisions

"},{"title":"Settings.setParticleEmitRateScale","link":"setParticleEmitRateScale","description":"

Set to scales emit rate of particles

"},{"title":"Settings.setSoundDefaultRange","link":"setSoundDefaultRange","description":"

Set default range where sound no longer plays

"},{"title":"Settings.setSoundDefaultTaper","link":"setSoundDefaultTaper","description":"

Set default range percent to start tapering off sound

"},{"title":"Settings.setSoundEnable","link":"setSoundEnable","description":"

Set to disable all audio code

"},{"title":"Settings.setSoundVolume","link":"setSoundVolume","description":"

Set volume scale to apply to all sound, music and speech

"},{"title":"Settings.setTileFixBleedScale","link":"setTileFixBleedScale","description":"

Set to prevent tile bleeding from neighbors in pixels

"},{"title":"Settings.setTileSizeDefault","link":"setTileSizeDefault","description":"

Set default size of tiles in pixels

"},{"title":"Settings.setTouchGamepadAlpha","link":"setTouchGamepadAlpha","description":"

Set transparency of touch gamepad overlay

"},{"title":"Settings.setTouchGamepadAnalog","link":"setTouchGamepadAnalog","description":"

Set if touch gamepad should be analog stick or 8 way dpad

"},{"title":"Settings.setTouchGamepadEnable","link":"setTouchGamepadEnable","description":"

Set if touch gamepad should appear on mobile devices

"},{"title":"Settings.setTouchGamepadSize","link":"setTouchGamepadSize","description":"

Set size of virutal gamepad for touch devices in pixels

"},{"title":"Settings.setVibrateEnable","link":"setVibrateEnable","description":"

Set to allow vibration hardware if it exists

"},{"title":"Settings.soundDefaultRange","link":"soundDefaultRange","description":"

Default range where sound no longer plays

"},{"title":"Settings.soundDefaultTaper","link":"soundDefaultTaper","description":"

Default range percent to start tapering off sound (0-1)

"},{"title":"Settings.soundEnable","link":"soundEnable","description":"

All audio code can be disabled and removed from build

"},{"title":"Settings.soundVolume","link":"soundVolume","description":"

Volume scale to apply to all sound, music and speech

"},{"title":"Settings.tileFixBleedScale","link":"tileFixBleedScale","description":"

Prevent tile bleeding from neighbors in pixels

"},{"title":"Settings.tileSizeDefault","link":"tileSizeDefault","description":"

Default size of tiles in pixels

"},{"title":"Settings.touchGamepadAlpha","link":"touchGamepadAlpha","description":"

Transparency of touch gamepad overlay

"},{"title":"Settings.touchGamepadAnalog","link":"touchGamepadAnalog","description":"

True if touch gamepad should be analog stick or false to use if 8 way dpad

"},{"title":"Settings.touchGamepadEnable","link":"touchGamepadEnable","description":"

True if touch gamepad should appear on mobile devices

\n"},{"title":"Settings.touchGamepadSize","link":"touchGamepadSize","description":"

Size of virutal gamepad for touch devices in pixels

"},{"title":"Settings.vibrateEnable","link":"vibrateEnable","description":"

Allow vibration hardware if it exists

"},{"title":"Sound","link":"Sound","description":"

Create a sound object and cache the zzfx samples for later use

"},{"title":"Sound#getDuration","link":"getDuration","description":"

Get how long this sound is in seconds

"},{"title":"Sound#isLoading","link":"isLoading","description":"

Check if sound is loading, for sounds fetched from a url

"},{"title":"Sound#isPlaying","link":"isPlaying","description":"

Check if the last instance of this sound is playing

"},{"title":"Sound#play","link":"play","description":"

Play the sound

"},{"title":"Sound#playNote","link":"playNote","description":"

Play the sound as a note with a semitone offset

"},{"title":"Sound#randomness","link":"randomness"},{"title":"Sound#range","link":"range"},{"title":"Sound#stop","link":"stop","description":"

Stop the last instance of this sound that was played

"},{"title":"Sound#taper","link":"taper"},{"title":"SoundWave","link":"SoundWave","description":"

Create a sound object and cache the wave file for later use

"},{"title":"TileCollision","link":"TileCollision","description":"

LittleJS Tile Layer System

\n"},{"title":"TileCollision.getTileCollisionData","link":"getTileCollisionData","description":"

Get tile collision data

"},{"title":"TileCollision.initTileCollision","link":"initTileCollision","description":"

Clear and initialize tile collision

"},{"title":"TileCollision.setTileCollisionData","link":"setTileCollisionData","description":"

Set tile collision data

"},{"title":"TileCollision.tileCollision","link":"tileCollision","description":"

The tile collision layer array, use setTileCollisionData and getTileCollisionData to access

"},{"title":"TileCollision.tileCollisionRaycast","link":"tileCollisionRaycast","description":"

Return the center of tile if any that is hit (does not return the exact intersection)

"},{"title":"TileCollision.tileCollisionSize","link":"tileCollisionSize","description":"

Size of the tile collision layer

"},{"title":"TileCollision.tileCollisionTest","link":"tileCollisionTest","description":"

Check if collision with another object should occur

"},{"title":"TileLayer","link":"TileLayer","description":"

Create a tile layer object

"},{"title":"TileLayer#canvas","link":"canvas"},{"title":"TileLayer#context","link":"context"},{"title":"TileLayer#drawAllTileData","link":"drawAllTileData","description":"

Draw all the tiles in this layer

"},{"title":"TileLayer#drawCanvas2D","link":"drawCanvas2D","description":"

Draw directly to the 2D canvas in world space (bipass webgl)

"},{"title":"TileLayer#drawRect","link":"drawRect","description":"

Draw a rectangle directly onto the layer canvas

"},{"title":"TileLayer#drawTile","link":"drawTile","description":"

Draw a tile directly onto the layer canvas

"},{"title":"TileLayer#drawTileData","link":"drawTileData","description":"

Draw the tile at a given position

"},{"title":"TileLayer#getData","link":"getData","description":"

Get data at a given position in the array

"},{"title":"TileLayer#isOverlay","link":"isOverlay"},{"title":"TileLayer#redraw","link":"redraw","description":"

Draw all the tile data to an offscreen canvas

\n"},{"title":"TileLayer#redrawEnd","link":"redrawEnd","description":"

Call to end the redraw process

"},{"title":"TileLayer#redrawStart","link":"redrawStart","description":"

Call to start the redraw process

"},{"title":"TileLayer#scale","link":"scale"},{"title":"TileLayer#setData","link":"setData","description":"

Set data at a given position in the array

"},{"title":"TileLayerData","link":"TileLayerData","description":"

Create a tile layer data object, one for each tile in a TileLayer

"},{"title":"TileLayerData#clear","link":"clear","description":"

Set this tile to clear, it will not be rendered

"},{"title":"TileLayerData#color","link":"color"},{"title":"TileLayerData#direction","link":"direction"},{"title":"TileLayerData#mirror","link":"mirror"},{"title":"TileLayerData#tile","link":"tile"},{"title":"Timer","link":"Timer","description":"

Create a timer object set time passed in

"},{"title":"Timer#active","link":"active","description":"

Returns true if set and has not elapsed

"},{"title":"Timer#elapsed","link":"elapsed","description":"

Returns true if set and elapsed

"},{"title":"Timer#get","link":"get","description":"

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

"},{"title":"Timer#getPercent","link":"getPercent","description":"

Get percentage elapsed based on time it was set to, returns 0 if not set

"},{"title":"Timer#isSet","link":"isSet","description":"

Returns true if set

"},{"title":"Timer#set","link":"set","description":"

Set the timer with seconds passed in

"},{"title":"Timer#toString","link":"toString","description":"

Returns this timer expressed as a string

"},{"title":"Timer#unset","link":"unset","description":"

Unset the timer

"},{"title":"Timer#valueOf","link":"valueOf","description":"

Get how long since elapsed, returns 0 if not set (returns negative if currently active)

"},{"title":"Utilities","link":"Utilities","description":"

LittleJS Utility Classes and Functions

\n"},{"title":"Utilities.PI","link":"PI","description":"

A shortcut to get Math.PI

"},{"title":"Utilities.abs","link":"abs","description":"

Returns absoulte value of value passed in

"},{"title":"Utilities.clamp","link":"clamp","description":"

Clamps the value beween max and min

"},{"title":"Utilities.distanceAngle","link":"distanceAngle","description":"

Returns signed wrapped distance between the two angles passed in

"},{"title":"Utilities.distanceWrap","link":"distanceWrap","description":"

Returns signed wrapped distance between the two values passed in

"},{"title":"Utilities.formatTime","link":"formatTime","description":"

Formats seconds to mm:ss style for display purposes

"},{"title":"Utilities.hsl","link":"hsl","description":"

Create a color object with HSLA values

"},{"title":"Utilities.isOverlapping","link":"isOverlapping","description":"

Returns true if two axis aligned bounding boxes are overlapping

"},{"title":"Utilities.isVector2","link":"isVector2","description":"

Check if object is a valid Vector2

"},{"title":"Utilities.lerp","link":"lerp","description":"

Linearly interpolates between values passed in using percent

"},{"title":"Utilities.lerpAngle","link":"lerpAngle","description":"

Linearly interpolates between the angles passed in with wrappping

"},{"title":"Utilities.lerpWrap","link":"lerpWrap","description":"

Linearly interpolates between values passed in with wrappping

"},{"title":"Utilities.max","link":"max","description":"

Returns highest of two values passed in

"},{"title":"Utilities.min","link":"min","description":"

Returns lowest of two values passed in

"},{"title":"Utilities.mod","link":"mod","description":"

Returns first parm modulo the second param, but adjusted so negative numbers work as expected

"},{"title":"Utilities.nearestPowerOfTwo","link":"nearestPowerOfTwo","description":"

Returns the nearest power of two not less then the value

"},{"title":"Utilities.percent","link":"percent","description":"

Returns what percentage the value is between valueA and valueB

"},{"title":"Utilities.rgb","link":"rgb","description":"

Create a color object with RGBA values

"},{"title":"Utilities.sign","link":"sign","description":"

Returns the sign of value passed in (also returns 1 if 0)

"},{"title":"Utilities.smoothStep","link":"smoothStep","description":"

Applies smoothstep function to the percentage value

"},{"title":"Utilities.vec2","link":"vec2","description":"

Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar

"},{"title":"Utilities.wave","link":"wave","description":"

Returns an oscillating wave between 0 and amplitude with frequency of 1 Hz by default

"},{"title":"Vector2","link":"Vector2","description":"

Create a 2D vector with the x and y passed in, can also be created with vec2()

"},{"title":"Vector2#add","link":"add","description":"

Returns a copy of this vector plus the vector passed in

"},{"title":"Vector2#angle","link":"angle","description":"

Returns the angle of this vector, up is angle 0

"},{"title":"Vector2#area","link":"area","description":"

Returns the area this vector covers as a rectangle

"},{"title":"Vector2#arrayCheck","link":"arrayCheck","description":"

Returns true if this vector is within the bounds of an array size passed in

"},{"title":"Vector2#clampLength","link":"clampLength","description":"

Returns a new vector clamped to length passed in

"},{"title":"Vector2#copy","link":"copy","description":"

Returns a new vector that is a copy of this

"},{"title":"Vector2#cross","link":"cross","description":"

Returns the cross product of this and the vector passed in

"},{"title":"Vector2#direction","link":"direction","description":"

Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)

"},{"title":"Vector2#distance","link":"distance","description":"

Returns the distance from this vector to vector passed in

"},{"title":"Vector2#distanceSquared","link":"distanceSquared","description":"

Returns the distance squared from this vector to vector passed in

"},{"title":"Vector2#divide","link":"divide","description":"

Returns a copy of this vector divided by the vector passed in

"},{"title":"Vector2#dot","link":"dot","description":"

Returns the dot product of this and the vector passed in

"},{"title":"Vector2#floor","link":"floor","description":"

Returns a copy of this vector with each axis floored

"},{"title":"Vector2#invert","link":"invert","description":"

Returns a copy of this vector that has been inverted

"},{"title":"Vector2#length","link":"length","description":"

Returns the length of this vector

"},{"title":"Vector2#lengthSquared","link":"lengthSquared","description":"

Returns the length of this vector squared

"},{"title":"Vector2#lerp","link":"lerp","description":"

Returns a new vector that is p percent between this and the vector passed in

"},{"title":"Vector2#multiply","link":"multiply","description":"

Returns a copy of this vector times the vector passed in

"},{"title":"Vector2#normalize","link":"normalize","description":"

Returns a new vector in same direction as this one with the length passed in

"},{"title":"Vector2#rotate","link":"rotate","description":"

Returns copy of this vector rotated by the angle passed in

"},{"title":"Vector2#scale","link":"scale","description":"

Returns a copy of this vector scaled by the vector passed in

"},{"title":"Vector2#setAngle","link":"setAngle","description":"

Sets this vector with angle and length passed in

"},{"title":"Vector2#subtract","link":"subtract","description":"

Returns a copy of this vector minus the vector passed in

"},{"title":"Vector2#toString","link":"toString","description":"

Returns this vector expressed as a string

"},{"title":"Vector2#x","link":"x"},{"title":"Vector2#y","link":"y"},{"title":"WebGL","link":"WebGL","description":"

LittleJS WebGL Interface

\n"},{"title":"WebGL.glCanvas","link":"glCanvas","description":"

The WebGL canvas which appears above the main canvas and below the overlay canvas

"},{"title":"WebGL.glCompileShader","link":"glCompileShader","description":"

Compile WebGL shader of the given type, will throw errors if in debug mode

"},{"title":"WebGL.glContext","link":"glContext","description":"

2d context for glCanvas

"},{"title":"WebGL.glCopyToContext","link":"glCopyToContext","description":"

Draw any sprites still in the buffer, copy to main canvas and clear

"},{"title":"WebGL.glCreateProgram","link":"glCreateProgram","description":"

Create WebGL program with given shaders

"},{"title":"WebGL.glCreateTexture","link":"glCreateTexture","description":"

Create WebGL texture from an image and set the texture settings

"},{"title":"WebGL.glDraw","link":"glDraw","description":"

Add a sprite to the gl draw list, used by all gl draw functions

"},{"title":"WebGL.glDrawPoints","link":"glDrawPoints","description":"

Add a convex polygon to the gl draw list

"},{"title":"WebGL.glFlush","link":"glFlush","description":"

Draw all sprites and clear out the buffer, called automatically by the system whenever necessary

"},{"title":"WebGL.glInitPostProcess","link":"glInitPostProcess","description":"

Set up a post processing shader

"},{"title":"WebGL.glSetBlendMode","link":"glSetBlendMode","description":"

Set the WebGl blend mode, normally you should call setBlendMode instead

"},{"title":"WebGL.glSetTexture","link":"glSetTexture","description":"

Set the WebGl texture, not normally necessary unless multiple tile sheets are used

\n"},{"title":"WebGL.glTileTexture","link":"glTileTexture","description":"

Main tile sheet texture automatically loaded by engine

"}]} \ No newline at end of file diff --git a/docs/engine.js.html b/docs/engine.js.html index 0f96f9d6..0a067f97 100644 --- a/docs/engine.js.html +++ b/docs/engine.js.html @@ -1,6 +1,6 @@ Source: engine.js
On this page

engine.js

/** 
+    
On this page

engine.js

/** 
  * LittleJS - The Tiny JavaScript Game Engine That Can!
  * MIT License - Copyright 2021 Frank Force
  * 
@@ -32,7 +32,7 @@
  *  @type {String}
  *  @default
  *  @memberof Engine */
-const engineVersion = '1.7.12';
+const engineVersion = '1.7.21';
 
 /** Frames per second to update objects
  *  @type {Number}
@@ -102,11 +102,13 @@
         debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
 
         // setup html
-        const styleBody = 'margin:0;overflow:hidden;' + // fill the window
-            'background:#000;' +        // set background color
-            'touch-action:none;' +      // prevent mobile pinch to resize
-            'user-select:none;' +       // prevent mobile hold to select
-            '-webkit-user-select:none'; // compatibility for ios
+        const styleBody = 
+            'margin:0;overflow:hidden;' + // fill the window
+            'background:#000;' +          // set background color
+            'touch-action:none;' +        // prevent mobile pinch to resize
+            'user-select:none;' +         // prevent mobile hold to select
+            '-webkit-user-select:none;' + // compatibility for ios
+            '-webkit-touch-callout:none'; // compatibility for ios
         document.body.style = styleBody;
         document.body.appendChild(mainCanvas = document.createElement('canvas'));
         mainContext = mainCanvas.getContext('2d');
@@ -120,7 +122,8 @@
         overlayContext = overlayCanvas.getContext('2d');
 
         // set canvas style
-        const styleCanvas = 'position:absolute;' +
+        const styleCanvas = 
+            'position:absolute;' +                               // position canvas              
             'top:50%;left:50%;transform:translate(-50%,-50%);' + // center the canvas
             (canvasPixelated?'image-rendering:pixelated':'');    // set pixelated rendering
         (glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
@@ -321,4 +324,4 @@
         for (const o of objects)
             pos.distanceSquared(o.pos) < sizeSquared && callbackFunction(o);
     }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineAudio.js.html b/docs/engineAudio.js.html index c5555f98..3cc3d1f7 100644 --- a/docs/engineAudio.js.html +++ b/docs/engineAudio.js.html @@ -1,6 +1,6 @@ Source: engineAudio.js
On this page

engineAudio.js

/** 
+    
On this page

engineAudio.js

/** 
  * LittleJS Audio System
  * - <a href=https://killedbyapixel.github.io/ZzFX/>ZzFX Sound Effects</a> - ZzFX Sound Effect Generator
  * - <a href=https://keithclark.github.io/ZzFXM/>ZzFXM Music</a> - ZzFXM Music System
@@ -47,8 +47,9 @@
         if (zzfxSound)
         {
             // generate zzfx sound now for fast playback
-            this.randomness = zzfxSound[1] || (zzfxSound[1] = 0); 
-            this.cachedSamples = zzfxSound && zzfxG(...zzfxSound);
+            this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
+            this.sampleChannels = [zzfxG(...zzfxSound)];
+            this.sampleRate = zzfxR;
         }
     }
 
@@ -57,11 +58,12 @@
      *  @param {Number}  [volume=1] - How much to scale volume by (in addition to range fade)
      *  @param {Number}  [pitch=1] - How much to scale pitch by (also adjusted by this.randomness)
      *  @param {Number}  [randomnessScale=1] - How much to scale randomness
-     *  @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
+     *  @param {Boolean} [loop=0] - Should the sound loop
+     *  @return {AudioBufferSourceNode} - The audio source node
      */
-    play(pos, volume=1, pitch=1, randomnessScale=1)
+    play(pos, volume=1, pitch=1, randomnessScale=1, loop=0)
     {
-        if (!soundEnable || !this.cachedSamples) return;
+        if (!soundEnable || !this.sampleChannels) return;
 
         let pan;
         if (pos)
@@ -84,43 +86,80 @@
 
         // play the sound
         const playbackRate = pitch + pitch * this.randomness*randomnessScale*rand(-1,1);
-        return playSamples([this.cachedSamples], volume, playbackRate, pan);
+        return this.source = playSamples(this.sampleChannels, volume, playbackRate, pan, loop, this.sampleRate);
+    }
+
+    /** Stop the last instance of this sound that was played */
+    stop()
+    {
+        if (this.source)
+            this.source.stop();
+        this.source = 0;
     }
 
     /** Play the sound as a note with a semitone offset
      *  @param {Number}  semitoneOffset - How many semitones to offset pitch
      *  @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
      *  @param {Number}  [volume=1] - How much to scale volume by (in addition to range fade)
-     *  @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
+     *  @return {AudioBufferSourceNode} - The audio source node
      */
     playNote(semitoneOffset, pos, volume)
     { return this.play(pos, volume, 2**(semitoneOffset/12), 0); }
+
+    /** Get how long this sound is in seconds
+     *  @return {Number} - How long the sound is in seconds (undefined if loading)
+     */
+    getDuration() 
+    { return this.sampleChannels && this.sampleChannels[0].length / this.sampleRate; }
+
+    /** Check if the last instance of this sound is playing
+     *  @return {Boolean} - True if the sound is playing
+     */
+    isPlaying() { return this.source && !this.source.ended; }
+
+    /** Check if sound is loading, for sounds fetched from a url
+     *  @return {Boolean} - True if sound is loading and not ready to play
+     */
+    isLoading() { return !this.sampleChannels; }
 }
 
 /** 
  * Sound Wave Object - Stores a wave sound for later use and can be played positionally
+ * - this can be used to play wave, mp3, and ogg files
+ * @example
+ * // create a sound
+ * const sound_example = new SoundWave('sound.mp3');
+ * 
+ * // play the sound
+ * sound_example.play();
  */
 class SoundWave extends Sound
 {
     /** Create a sound object and cache the wave file for later use
-     *  @param {String} waveFilename - Filename of wave file to load
-     *  @param {Number} [randomness=.05] - How much to randomize frequency each time sound plays
+     *  @param {String} filename - Filename of audio file to load
+     *  @param {Number} [randomness=0] - How much to randomize frequency each time sound plays
      *  @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
      *  @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
      */
-    constructor(waveFilename, randomness=.05, range, taper)
+    constructor(filename, randomness=0, range, taper)
     {
         super(0, range, taper);
         this.randomness = randomness;
 
         if (!soundEnable) return;
-        if (!soundWaveDecoderContext)
+        if (!soundDecoderContext)
             soundDecoderContext = new AudioContext;
 
-        fetch(waveFilename)
+        fetch(filename)
         .then(response => response.arrayBuffer())
-        .then(arrayBuffer => soundWaveDecoderContext.decodeAudioData(arrayBuffer))
-        .then(audioBuffer => this.cachedSamples = audioBuffer.getChannelData(0));
+        .then(arrayBuffer => soundDecoderContext.decodeAudioData(arrayBuffer))
+        .then(audioBuffer => 
+        {
+            this.sampleChannels = [];
+            for (let i = audioBuffer.numberOfChannels; i--;)
+                this.sampleChannels[i] = audioBuffer.getChannelData(i);
+            this.sampleRate = audioBuffer.sampleRate;
+        });
     }
 }
 let soundDecoderContext; // audio context used only to decode audio files
@@ -155,48 +194,34 @@
  * // play the music
  * music_example.play();
  */
-class Music
+class Music extends Sound
 {
     /** Create a music object and cache the zzfx music samples for later use
      *  @param {Array} zzfxMusic - Array of zzfx music parameters
      */
     constructor(zzfxMusic)
     {
-        if (!soundEnable) return;
+        super();
 
-        this.cachedSamples = zzfxM(...zzfxMusic);
+        if (!soundEnable) return;
+        this.randomness = 0;
+        this.sampleChannels = zzfxM(...zzfxMusic);
+        this.sampleRate = zzfxR;
     }
 
     /** Play the music
      *  @param {Number}  [volume=1] - How much to scale volume by
-     *  @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
-     *  @return {AudioBufferSourceNode} - The audio node, can be used to stop sound later
+     *  @param {Boolean} [loop=1] - True if the music should loop
+     *  @return {AudioBufferSourceNode} - The audio source node
      */
     play(volume, loop = 1)
-    {
-        if (!soundEnable) return;
-
-        return this.source = playSamples(this.cachedSamples, volume, 1, 0, loop);
-    }
-
-    /** Stop the music */
-    stop()
-    {
-        if (this.source)
-            this.source.stop();
-        this.source = 0;
-    }
-
-    /** Check if music is playing
-     *  @return {Boolean}
-     */
-    isPlaying() { return this.source; }
+    { return super.play(0, volume, 1, 1, loop); }
 }
 
-/** Play an mp3 or wav audio from a local file or url
+/** Play an mp3, ogg, or wav audio from a local file or url
  *  @param {String}  url - Location of sound file to play
  *  @param {Number}  [volume=1] - How much to scale volume by
- *  @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
+ *  @param {Boolean} [loop=1] - True if the music should loop
  *  @return {HTMLAudioElement} - The audio element for this sound
  *  @memberof Audio */
 function playAudioFile(url, volume=1, loop=1)
@@ -260,9 +285,10 @@
  *  @param {Number}  [rate=1] - The playback rate to use
  *  @param {Number}  [pan=0] - How much to apply stereo panning
  *  @param {Boolean} [loop=0] - True if the sound should loop when it reaches the end
+ *  @param {Number}  [sampleRate=44100] - Sample rate for the sound
  *  @return {AudioBufferSourceNode} - The audio node of the sound played
  *  @memberof Audio */
-function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0) 
+function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0, sampleRate=zzfxR) 
 {
     if (!soundEnable) return;
 
@@ -279,7 +305,7 @@
     }
 
     // create buffer and source
-    const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length, zzfxR), 
+    const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length, sampleRate), 
         source = audioContext.createBufferSource();
 
     // copy samples to buffer and setup source
@@ -525,4 +551,4 @@
   }
 
   return [leftChannelBuffer, rightChannelBuffer];
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineDebug.js.html b/docs/engineDebug.js.html index abcd3a1e..284d577f 100644 --- a/docs/engineDebug.js.html +++ b/docs/engineDebug.js.html @@ -1,6 +1,6 @@ Source: engineDebug.js
On this page

engineDebug.js

/** 
+    
On this page

engineDebug.js

/** 
  * LittleJS Debug System
  * - Press Esc to show debug overlay with mouse pick
  * - Number keys toggle debug functions
@@ -213,7 +213,11 @@
         mainContext.drawImage(overlayCanvas, 0, 0);
         overlayCanvas.width |= 0;
 
-        debugSaveCanvas(mainCanvas);
+        // remove alpha and save
+        const w = mainCanvas.width, h = mainCanvas.height;
+        overlayContext.fillRect(0,0,w,h);
+        overlayContext.drawImage(mainCanvas, 0, 0);
+        debugSaveCanvas(overlayCanvas);
         debugTakeScreenshot = 0;
     }
 
@@ -403,4 +407,4 @@
     
         overlayContext.restore();
     }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineDraw.js.html b/docs/engineDraw.js.html index 6d762643..6518e30c 100644 --- a/docs/engineDraw.js.html +++ b/docs/engineDraw.js.html @@ -1,6 +1,6 @@ Source: engineDraw.js
On this page

engineDraw.js

/** 
+    
On this page

engineDraw.js

/** 
  * LittleJS Drawing System
  * - Hybrid system with both Canvas2D and WebGL available
  * - Super fast tile sheet rendering with WebGL
@@ -193,7 +193,7 @@
  *  @param {Boolean} [useWebGL=glEnable]
  *  @param {Boolean} [screenSpace=0]
  *  @memberof Draw */
-function drawLine(posA, posB, thickness=.1, color, useWebGL)
+function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace)
 {
     const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
     const size = vec2(thickness, halfDelta.length()*2);
@@ -213,12 +213,12 @@
 {
     if (!screenSpace)
     {
-        // create canvas transform from world space to screen space
+        // transform from world space to screen space
         pos = worldToScreen(pos);
         size = size.scale(cameraScale);
     }
     context.save();
-    context.translate(pos.x+.5|0, pos.y+.5|0);
+    context.translate(pos.x+.5, pos.y+.5);
     context.rotate(angle);
     context.scale(mirror ? -size.x : size.x, size.y);
     drawFunction(context);
@@ -393,4 +393,4 @@
     else if (document.body.requestFullscreen)
             document.body.requestFullscreen();
 }
-
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/engineExport.js.html b/docs/engineExport.js.html index f81a024f..780caacf 100644 --- a/docs/engineExport.js.html +++ b/docs/engineExport.js.html @@ -1,6 +1,6 @@ Source: engineExport.js
On this page

engineExport.js

/** 
+    
On this page

engineExport.js

/** 
  * LittleJS Module Export
  * - Export engine as a module with functions where necessary
  */
@@ -431,4 +431,4 @@
 	engineObjectsUpdate,
 	engineObjectsDestroy,
 	engineObjectsCallback,
-};
\ No newline at end of file +};
\ No newline at end of file diff --git a/docs/engineInput.js.html b/docs/engineInput.js.html index a5f7a430..815893fd 100644 --- a/docs/engineInput.js.html +++ b/docs/engineInput.js.html @@ -1,6 +1,6 @@ Source: engineInput.js
On this page

engineInput.js

/** 
+    
On this page

engineInput.js

/** 
  * LittleJS Input System
  * - Tracks keyboard down, pressed, and released
  * - Tracks mouse buttons, position, and wheel
@@ -193,18 +193,26 @@
 const stickData = [];
 function gamepadsUpdate()
 {
-    if (touchGamepadEnable && touchGamepadTimer.isSet())
+    // update touch gamepad if enabled
+    if (touchGamepadEnable && isTouchDevice)
     {
-        // read virtual analog stick
-        const sticks = stickData[0] || (stickData[0] = []);
-        sticks[0] = vec2(touchGamepadStick.x, -touchGamepadStick.y); // flip vertical
+        // create the touch gamepad if it doesn't exist
+        if (!touchGamepadButtons)
+            createTouchGamepad();
 
-        // read virtual gamepad buttons
-        const data = inputData[1] || (inputData[1] = []);
-        for (let i=10; i--;)
+        if (touchGamepadTimer.isSet())
         {
-            const j = i == 3 ? 2 : i == 2 ? 3 : i; // fix button locations
-            data[j] = touchGamepadButtons[i] ? 1 + 2*!gamepadIsDown(j,0) : 4*gamepadIsDown(j,0);
+            // read virtual analog stick
+            const sticks = stickData[0] || (stickData[0] = []);
+            sticks[0] = vec2(touchGamepadStick.x, -touchGamepadStick.y); // flip vertical
+
+            // read virtual gamepad buttons
+            const data = inputData[1] || (inputData[1] = []);
+            for (let i=10; i--;)
+            {
+                const j = i == 3 ? 2 : i == 2 ? 3 : i; // fix button locations
+                data[j] = touchGamepadButtons[i] ? 1 + 2*!gamepadIsDown(j,0) : 4*gamepadIsDown(j,0);
+            }
         }
     }
 
@@ -301,6 +309,10 @@
         // set was touching
         wasTouching = touching;
 
+        // prevent default handling like copy and magnifier lens
+        if (document.hasFocus()) // allow document to get focus
+            e.preventDefault();
+        
         // must return true so the document will get focus
         return true;
     }
@@ -313,7 +325,7 @@
 let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
 
 // create the touch gamepad, called automatically by the engine
-if (touchGamepadEnable)
+function createTouchGamepad()
 {
     // touch input internal variables
     touchGamepadButtons = [];
@@ -435,4 +447,4 @@
 
     // set canvas back to normal
     overlayContext.restore();
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineMedals.js.html b/docs/engineMedals.js.html index b4fd560d..fa141388 100644 --- a/docs/engineMedals.js.html +++ b/docs/engineMedals.js.html @@ -1,6 +1,6 @@ Source: engineMedals.js
On this page

engineMedals.js

/** 
+    
On this page

engineMedals.js

/** 
  * LittleJS Medal System
  * - Tracks and displays medals
  * - Saves medals to local storage
@@ -320,4 +320,4 @@
         // end of Crypto-JS
         ///////////////////////////////////////////////////////////////////////////////
     }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineObject.js.html b/docs/engineObject.js.html index a79a60be..7e33abb8 100644 --- a/docs/engineObject.js.html +++ b/docs/engineObject.js.html @@ -1,6 +1,6 @@ Source: engineObject.js
On this page

engineObject.js

/** 
+    
On this page

engineObject.js

/** 
  * LittleJS Object System
  */
 
@@ -377,4 +377,4 @@
             return text;
         }
     }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineParticles.js.html b/docs/engineParticles.js.html index a26d6195..9610d17b 100644 --- a/docs/engineParticles.js.html +++ b/docs/engineParticles.js.html @@ -1,6 +1,6 @@ Source: engineParticles.js
On this page

engineParticles.js

/** 
+    
On this page

engineParticles.js

/** 
  * LittleJS Particle System
  */
 
@@ -305,4 +305,4 @@
             this.destroyed = 1;
         }
     }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineSettings.js.html b/docs/engineSettings.js.html index e97a568e..3ab8bb72 100644 --- a/docs/engineSettings.js.html +++ b/docs/engineSettings.js.html @@ -1,6 +1,6 @@ Source: engineSettings.js
On this page

engineSettings.js

/**
+    
On this page

engineSettings.js

/**
  * LittleJS Engine Settings
  * - All settings for the engine are here
  * @namespace Settings
@@ -249,4 +249,4 @@
  *  @type {Boolean}
  *  @default 0
  *  @memberof Settings */
-let medalsPreventUnlock;
\ No newline at end of file +let medalsPreventUnlock;
\ No newline at end of file diff --git a/docs/engineTileLayer.js.html b/docs/engineTileLayer.js.html index 4c0d8c30..6792cac3 100644 --- a/docs/engineTileLayer.js.html +++ b/docs/engineTileLayer.js.html @@ -1,6 +1,6 @@ Source: engineTileLayer.js
On this page

engineTileLayer.js

/** 
+    
On this page

engineTileLayer.js

/** 
  * LittleJS Tile Layer System
  * - Caches arrays of tiles to off screen canvas for fast rendering
  * - Unlimted numbers of layers, allocates canvases as needed
@@ -360,4 +360,4 @@
      *  @param {Number}  [angle=0] */
     drawRect(pos, size, color, angle) 
     { this.drawTile(pos, size, -1, 0, color, angle); }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineUtilities.js.html b/docs/engineUtilities.js.html index 3997bb8d..1debddc6 100644 --- a/docs/engineUtilities.js.html +++ b/docs/engineUtilities.js.html @@ -1,6 +1,6 @@ Source: engineUtilities.js
On this page

engineUtilities.js

/**
+    
On this page

engineUtilities.js

/**
  * LittleJS Utility Classes and Functions
  * - General purpose math library
  * - Vector2 - fast, simple, easy 2D vector class
@@ -658,4 +658,4 @@
     /** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
      * @return {Number} */
     valueOf()               { return this.get(); }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/docs/engineWebGL.js.html b/docs/engineWebGL.js.html index e66abe81..95922868 100644 --- a/docs/engineWebGL.js.html +++ b/docs/engineWebGL.js.html @@ -1,6 +1,6 @@ Source: engineWebGL.js
On this page

engineWebGL.js

/** 
+    
On this page

engineWebGL.js

/** 
  * LittleJS WebGL Interface
  * - All webgl used by the engine is wrapped up here
  * - For normal stuff you won't need to see or call anything in this file
@@ -33,7 +33,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// Init WebGL, called automatically by the engine
+// Initalize WebGL, called automatically by the engine
 function glInit()
 {
     // create the canvas and tile texture
@@ -72,6 +72,48 @@
     glBatchCount = 0;
 }
 
+// Setup render each frame, called automatically by engine
+function glPreRender()
+{
+    // clear and set to same size as main canvas
+    glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
+    glContext.clear(gl_COLOR_BUFFER_BIT);
+
+    // set up the shader
+    glContext.useProgram(glShader);
+    glContext.activeTexture(gl_TEXTURE0);
+    glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
+    glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
+    glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
+    glSetBlendMode();
+    
+    // set vertex attributes
+    let offset = 0;
+    const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
+    {
+        const location = glContext.getAttribLocation(glShader, name);
+        glContext.enableVertexAttribArray(location);
+        glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
+        offset += size*typeSize;
+    }
+    initVertexAttribArray('p', gl_FLOAT, 4, 2);            // position
+    initVertexAttribArray('t', gl_FLOAT, 4, 2);            // texture coords
+    initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
+    initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
+
+    // build the transform matrix
+    const sx = 2 * cameraScale / mainCanvas.width;
+    const sy = 2 * cameraScale / mainCanvas.height;
+    glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
+        new Float32Array([
+            sx, 0, 0, 0,
+            0, sy, 0, 0,
+            1, 1, -1, 1,
+            -1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
+        ])
+    );
+}
+
 /** Set the WebGl blend mode, normally you should call setBlendMode instead
  *  @param {Boolean} [additive=0]
  *  @memberof WebGL */
@@ -151,48 +193,6 @@
     return texture;
 }
 
-// called automatically by engine before render
-function glPreRender()
-{
-    // clear and set to same size as main canvas
-    glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
-    glContext.clear(gl_COLOR_BUFFER_BIT);
-
-    // set up the shader
-    glContext.useProgram(glShader);
-    glContext.activeTexture(gl_TEXTURE0);
-    glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
-    glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
-    glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
-    glSetBlendMode();
-    
-    // set vertex attributes
-    let offset = 0;
-    const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
-    {
-        const location = glContext.getAttribLocation(glShader, name);
-        glContext.enableVertexAttribArray(location);
-        glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
-        offset += size*typeSize;
-    }
-    initVertexAttribArray('p', gl_FLOAT, 4, 2);            // position
-    initVertexAttribArray('t', gl_FLOAT, 4, 2);            // texture coords
-    initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
-    initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
-
-    // build the transform matrix
-    const sx = 2 * cameraScale / mainCanvas.width;
-    const sy = 2 * cameraScale / mainCanvas.height;
-    glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
-        new Float32Array([
-            sx, 0, 0, 0,
-            0, sy, 0, 0,
-            1, 1, -1, 1,
-            -1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
-        ])
-    );
-}
-
 /** Draw all sprites and clear out the buffer, called automatically by the system whenever necessary
  *  @memberof WebGL */
 function glFlush()
@@ -429,4 +429,4 @@
 gl_INDICIES_PER_VERT = 6,
 gl_MAX_BATCH = 1e5,
 gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2, // vec2 * 2 + (char * 4) * 2
-gl_VERTEX_BUFFER_SIZE = gl_MAX_BATCH * gl_VERTEX_BYTE_STRIDE;
\ No newline at end of file +gl_VERTEX_BUFFER_SIZE = gl_MAX_BATCH * gl_VERTEX_BYTE_STRIDE;
\ No newline at end of file diff --git a/docs/examples/screenshot.jpg b/docs/examples/screenshot.jpg index 614d80ed517cb2b7344032eecd5d1a248356497e..d5a4e779de105fe036af387247428c6b04a4a7aa 100644 GIT binary patch literal 166544 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

MMy5oNR>q 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 X{InlKWF3RtEBOORtbwn=-*f*3T0K1A literal 227698 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

gg67&6X~rUX{>9^R-n?bN=#mATo%khfssE}ShS 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 R#`|-T>>+OUC;e}8{{xQ0-1Yzf diff --git a/docs/index.html b/docs/index.html index 7cfe957f..40b0d648 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,6 +1,6 @@ Home

On this page

LittleJS Logo LittleJS - The Tiny JavaScript Game Engine That Can

NPM PackageBuild SizeNPM DownloadsDeepScanDiscord

🚂 All aboard!

LittleJS is a lightweight open source HTML5 game engine designed for modern web development. It's small footprint is packed with a comprehensive feature set, including hybrid rendering, physics, particles, sound effects, music, input handling, and debug tools. The code is very clean and well documented with a several examples to get you started. Choo-Choo! 🚂

LittleJS Screenshot

About LittleJS

LittleJS is a small but powerful game engine with many features and no depenencies.

✨ Graphics

  • Super fast sprite and tile map rendering engine with WebGL
  • Update and render 10,000+ objects at 60fps, often many times more
  • Particle effect system and design tool
  • Apply Shadertoy compatible shaders for post processinge effects

🔊 Audio

  • Positional sound effects with wav or ZzFX sound effect generator
  • Music with mp3, ogg, wave, or ZzFXM

🎮 Input

  • Input processing system for keyboard, mouse, gamepad, and touch
  • On screen touch gamepad for mobile devices

💥 Physics

  • 2D physics engine with collision handling for axis aligned boxes
  • Very fast collision handling and raycasting for tile maps

🚀 Flexability

  • Designed to work with all modern web bowsers and mobile devices
  • Compatible with TypeScript and Modules with example projects for both
  • For size coding competitions like js13kGames, a special example project builds to a 7KB zip file
  • Builds to a Windows executable with Electron for distribution on PC platforms like Steam
  • Open Source with the MIT license so it can be used for anything you want forever

🛠️ And more...

  • Node.js build system
  • 2D vector math library
  • Debug primitive rendering system
  • Particle effects system and design tool
  • Bitmap font rendering and includes a built in engine font
  • Medal system tracks and displays achievements with Newgrounds integration

Demos

Starter Project - Clean example with only a few things to get you started

Puzzle Game - Match 3 puzzle game with HD rendering and high score tracking

Platformer - Platformer/shooter with procedural generation and destruction

Breakout - Breakout game with post processing effect

Stress Test - Max sprite/object test and music system demo

Particle System Designer - Particle system editor and visualizer

How to use LittleJS

To use LittleJS download the latest package from GitHub or call npm install littlejsengine. This package contains the engine and several small examples.

You can use the empty example template as a starting point. This file contains just the minimal setup to start the engine. You can also download and include littlejs.js or littlejs.min.js.

If your game loads any files like images you will need to run a local web server. Some editors can do this automatically like Visual Studio Code with the Live Server plugin. You can also use http-server via npm.

The Breakout Tutorial is provided to demonstrate how to make a simple game from scratch. The tutorial is also available on YouTube.

Builds

To easily include LittleJS in your game, you can use one of the 3 pre-built js files. These are also built automatically by the build scripts.

LittleJS can also be imported as a module. There are two module flavors that are automatically built.

To rebuild the engine you must first run npm install to setup the necessary npm dependencies. Then call npm run build to build the engine.

The starter example project also includes a node js file build.js that compresses everything into a tiny zip file using Google Closure, UglifyJS, and ECT Zip.

Engine Source Code

This engine is made with simplicity in mind using clean easy to read code. There are only a few core files used by the entire engine.

Optional Components, these components are built to synergize with the rest of the engine but are not required.

LittleJS Setup

To start LittleJS, you must create 5 functions and pass them to engineInit. A canvas will automatically be created and added to the document.

function gameInit()
+    
On this page

LittleJS Logo LittleJS - The Tiny JavaScript Game Engine That Can

NPM PackageBuild SizeNPM DownloadsDeepScanDiscord

🚂 All aboard!

LittleJS is a lightweight open source HTML5 game engine designed for modern web development. It's small footprint is packed with a comprehensive feature set, including hybrid rendering, physics, particles, sound effects, music, input handling, and debug tools. The code is very clean and well documented with a several examples to get you started. Choo-Choo! 🚂

LittleJS Screenshot

About LittleJS

LittleJS is a small but powerful game engine with many features and no depenencies.

✨ Graphics

  • Super fast sprite and tile map rendering engine with WebGL
  • Update and render 10,000+ objects at 60fps, often many times more
  • Particle effect system and design tool
  • Apply Shadertoy compatible shaders for post processinge effects

🔊 Audio

  • Positional sound effects with wav or ZzFX sound effect generator
  • Music with mp3, ogg, wave, or ZzFXM

🎮 Input

  • Input processing system for keyboard, mouse, gamepad, and touch
  • On screen touch gamepad for mobile devices

💥 Physics

  • 2D physics engine with collision handling for axis aligned boxes
  • Very fast collision handling and raycasting for tile maps

🚀 Flexability

  • Designed to work with all modern web bowsers and mobile devices
  • Compatible with TypeScript and Modules with example projects for both
  • For size coding competitions like js13kGames, a special example project builds to a 7KB zip file
  • Builds to a Windows executable with Electron for distribution on PC platforms like Steam
  • Open Source with the MIT license so it can be used for anything you want forever

🛠️ And more...

  • Node.js build system
  • 2D vector math library
  • Debug primitive rendering system
  • Particle effects system and design tool
  • Bitmap font rendering and includes a built in engine font
  • Medal system tracks and displays achievements with Newgrounds integration

Demos

Starter Project - Clean example with only a few things to get you started

Puzzle Game - Match 3 puzzle game with HD rendering and high score tracking

Platformer - Platformer/shooter with procedural generation and destruction

Breakout - Breakout game with post processing effect

Stress Test - Max sprite/object test and music system demo

Particle System Designer - Particle system editor and visualizer

How to use LittleJS

To use LittleJS download the latest package from GitHub or call npm install littlejsengine. This package contains the engine and several small examples.

You can use the empty example template as a starting point. This file contains just the minimal setup to start the engine. You can also download and include littlejs.js or littlejs.min.js.

If your game loads any files like images you will need to run a local web server. Some editors can do this automatically like Visual Studio Code with the Live Server plugin. You can also use http-server via npm.

The Breakout Tutorial is provided to demonstrate how to make a simple game from scratch. The tutorial is also available on YouTube.

Builds

To easily include LittleJS in your game, you can use one of the 3 pre-built js files. These are also built automatically by the build scripts.

LittleJS can also be imported as a module. There are two module flavors that are automatically built.

To rebuild the engine you must first run npm install to setup the necessary npm dependencies. Then call npm run build to build the engine.

The starter example project also includes a node js file build.js that compresses everything into a tiny zip file using Google Closure, UglifyJS, and ECT Zip.

Engine Source Code

This engine is made with simplicity in mind using clean easy to read code. There are only a few core files used by the entire engine.

Optional Components, these components are built to synergize with the rest of the engine but are not required.

LittleJS Setup

To start LittleJS, you must create 5 functions and pass them to engineInit. A canvas will automatically be created and added to the document.

function gameInit()
 {
     // called once after the engine starts up
     // setup the game
@@ -51,4 +51,4 @@
         super.render();
     }
 }
-

Debugging

Debug builds of LittleJS have a special menu that can be opened by pressing the Esc key.

  • Esc: Debug Overlay
  • 1: Debug Physics
  • 2: Debug Particles
  • 3: Debug Gamepads
  • 4: Debug Raycasts
  • 5: Save Screenshot

Games Made With LittleJS

Here are a few of the amazing games people are making with LittleJS.

LittleJS Logo

\ No newline at end of file +

Debugging

Debug builds of LittleJS have a special menu that can be opened by pressing the Esc key.

  • Esc: Debug Overlay
  • 1: Debug Physics
  • 2: Debug Particles
  • 3: Debug Gamepads
  • 4: Debug Raycasts
  • 5: Save Screenshot

Games Made With LittleJS

Here are a few of the amazing games people are making with LittleJS.

LittleJS Logo

\ No newline at end of file