littlejsengine 1.13.4 → 1.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/littlejs.d.ts +395 -249
- package/dist/littlejs.esm.js +1550 -754
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1528 -744
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1504 -720
- package/examples/box2d/game.js +4 -4
- package/examples/box2d/gameObjects.js +1 -1
- package/examples/breakout/game.js +30 -25
- package/examples/breakoutTutorial/README.md +1 -1
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/electron/build.js +1 -1
- package/examples/electron/index.html +2 -2
- package/examples/empty/game.js +1 -1
- package/examples/htmlMenu/index.html +7 -7
- package/examples/index.html +208 -97
- package/examples/platformer/gameEffects.js +20 -25
- package/examples/platformer/gameLevel.js +6 -1
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/flappyGame.js +2 -1
- package/examples/shorts/helloWorld.js +1 -1
- package/examples/shorts/music.js +106 -0
- package/examples/shorts/parallax.js +71 -0
- package/examples/shorts/piano.js +7 -8
- package/examples/shorts/postProcess.js +25 -8
- package/examples/shorts/shapes.js +12 -18
- package/examples/shorts/song.mp3 +0 -0
- package/examples/shorts/uiSystem.js +15 -8
- package/examples/starter/index.html +2 -2
- package/examples/stress/index.html +14 -7
- package/examples/style.css +14 -4
- package/examples/typescript/build.js +1 -1
- package/examples/uiSystem/game.js +11 -11
- package/package.json +1 -1
- package/plugins/box2d.js +12 -10
- package/plugins/drawUtilities.js +5 -5
- package/plugins/newgrounds.js +6 -6
- package/plugins/pluginExport.js +1 -1
- package/plugins/uiSystem.js +103 -79
- package/plugins/zzfxm.js +10 -10
- package/reference.md +94 -56
- package/src/engine.js +28 -24
- package/src/engineAudio.js +284 -109
- package/src/engineBuild.js +11 -11
- package/src/engineDebug.js +29 -29
- package/src/engineDraw.js +285 -112
- package/src/engineExport.js +28 -16
- package/src/engineInput.js +57 -67
- package/src/engineMedals.js +25 -25
- package/src/engineObject.js +28 -25
- package/src/engineParticles.js +59 -59
- package/src/engineRelease.js +1 -1
- package/src/engineSettings.js +20 -13
- package/src/engineTileLayer.js +34 -35
- package/src/engineUtilities.js +66 -59
- package/src/engineWebGL.js +466 -66
- /package/examples/shorts/{playSound.js → sound.js} +0 -0
package/reference.md
CHANGED
|
@@ -13,7 +13,7 @@ To start LittleJS, you need to create a few functions and pass them to engineIni
|
|
|
13
13
|
|
|
14
14
|
```javascript
|
|
15
15
|
// Start up LittleJS engine with your callback functions
|
|
16
|
-
engineInit(
|
|
16
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## LittleJS Utilities Classes and Functions
|
|
@@ -33,13 +33,14 @@ tile(pos, size=(16,16), texture=0, padding=0) // Create a tile info object
|
|
|
33
33
|
|
|
34
34
|
// Helper functions
|
|
35
35
|
abs(value) // Get absolute value
|
|
36
|
-
min(
|
|
37
|
-
max(
|
|
36
|
+
min(...values) // Get lowest of values
|
|
37
|
+
max(...values) // Get highest of values
|
|
38
38
|
sign(value) // Get the sign of value
|
|
39
39
|
mod(dividend, divisor=1) // Get remainder of division
|
|
40
40
|
clamp(value, min=0, max=1) // Clamps between values
|
|
41
41
|
percent(value, valueA, valueB) // Get percentage between values
|
|
42
42
|
lerp(valueA, valueB, percent) // Linearly interpolates between values
|
|
43
|
+
percentLerp(value, percentA, percentB, lerpA, lerpB) // Lerp that remaps the percent
|
|
43
44
|
distanceWrap(valueA, valueB, wrapSize=1) // Signed wrapped distance between values
|
|
44
45
|
lerpWrap(valueA, valueB, percent, wrapSize=1) // Linearly interpolates with wrapping
|
|
45
46
|
distanceAngle(angleA, angleB) // Signed wrapped distance between angles
|
|
@@ -54,7 +55,8 @@ formatTime(t) // Formats seconds for display
|
|
|
54
55
|
// Random functions
|
|
55
56
|
rand(valueA=1, valueB=0) // Random float between values
|
|
56
57
|
randInt(valueA, valueB=0) // Random integer between values
|
|
57
|
-
|
|
58
|
+
randBool(chance=.5) // Random boolean with given chance (0 to 1)
|
|
59
|
+
randSign() // Randomly either -1 or 1
|
|
58
60
|
randVec2(length=1) // Random Vector2 with the passed in length
|
|
59
61
|
randInCircle(radius=1, minRadius=0) // Random Vector2 within a circle
|
|
60
62
|
randColor(colorA, colorB, linear) // Random color between values
|
|
@@ -111,16 +113,16 @@ RandomGenerator.int(valueA, valueB=0) // Random integer between values
|
|
|
111
113
|
RandomGenerator.sign() // Randomly either -1 or 1
|
|
112
114
|
|
|
113
115
|
// Time tracking system
|
|
114
|
-
Timer(timeLeft)
|
|
115
|
-
Timer.set(timeLeft=0)
|
|
116
|
-
Timer.unset()
|
|
117
|
-
Timer.isSet()
|
|
118
|
-
Timer.active()
|
|
119
|
-
Timer.elapsed()
|
|
120
|
-
Timer.get()
|
|
121
|
-
Timer.getPercent()
|
|
122
|
-
Timer.toString()
|
|
123
|
-
Timer.valueOf()
|
|
116
|
+
Timer(timeLeft) // Create a timer object
|
|
117
|
+
Timer.set(timeLeft=0) // Set the timer with seconds passed in
|
|
118
|
+
Timer.unset() // Unset the timer
|
|
119
|
+
Timer.isSet() // Returns true if set
|
|
120
|
+
Timer.active() // Returns true if set and has not elapsed
|
|
121
|
+
Timer.elapsed() // Returns true if set and elapsed
|
|
122
|
+
Timer.get() // Get how long since elapsed, 0 if not set
|
|
123
|
+
Timer.getPercent() // Get percent elapsed, 0 if not set
|
|
124
|
+
Timer.toString() // Get this timer expressed as a string
|
|
125
|
+
Timer.valueOf() // Get how long since elapsed, 0 if not set
|
|
124
126
|
```
|
|
125
127
|
|
|
126
128
|
## LittleJS Drawing System
|
|
@@ -131,35 +133,48 @@ Timer.valueOf() // Get how long since elapsed, 0 if not set
|
|
|
131
133
|
|
|
132
134
|
```javascript
|
|
133
135
|
// Drawing functions
|
|
134
|
-
drawTile(pos, size
|
|
135
|
-
drawRect(pos, size
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
drawTile(pos, size, tileInfo, color=WHITE, angle=0, mirror, additiveColor)
|
|
137
|
+
drawRect(pos, size, color=WHITE, angle=0)
|
|
138
|
+
drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0)
|
|
139
|
+
drawLine(posA, posB, width=.1, color=WHITE, pos=(0,0), angle=0)
|
|
140
|
+
drawLineList(points, width=.1, color, wrap=false, pos=(0,0), angle=0)
|
|
141
|
+
drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos, angle=0)
|
|
142
|
+
drawRegularPoly(pos, size=(1,1), sides=3, color=WHITE, lineWidth=0, lineColor=BLACK, angle=0)
|
|
143
|
+
drawEllipse(pos, size=(1,1), color=WHITE, angle=0, lineWidth=0, lineColor=BLACK)
|
|
144
|
+
drawCircle(pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
145
|
+
drawCanvas2D(pos, size, angle=0, mirror, drawFunction, screenSpace, context)
|
|
146
|
+
|
|
147
|
+
// Text functions
|
|
148
|
+
drawText(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
149
|
+
drawTextOverlay(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
150
|
+
drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
|
|
151
|
+
|
|
152
|
+
// Utility drawing functions
|
|
140
153
|
setBlendMode(additive)
|
|
141
|
-
toggleFullscreen()
|
|
142
154
|
isFullscreen()
|
|
155
|
+
toggleFullscreen()
|
|
143
156
|
|
|
144
157
|
// Tile Info Object
|
|
145
|
-
TileInfo(pos
|
|
146
|
-
TileInfo.pos
|
|
147
|
-
TileInfo.size
|
|
148
|
-
TileInfo.textureIndex
|
|
149
|
-
TileInfo.
|
|
150
|
-
TileInfo.
|
|
151
|
-
TileInfo.
|
|
158
|
+
TileInfo(pos, size, textureIndex=0, padding=0) // Create a tile info object
|
|
159
|
+
TileInfo.pos // Top left corner of tile in pixels
|
|
160
|
+
TileInfo.size // Size of tile in pixels
|
|
161
|
+
TileInfo.textureIndex // Texture index to use
|
|
162
|
+
TileInfo.padding // How many pixels padding around tiles
|
|
163
|
+
TileInfo.offset(offset) // Offset this tile by a certain amount in pixels
|
|
164
|
+
TileInfo.frame(frame) // Offset this tile by a number of animation frames
|
|
165
|
+
TileInfo.textureInfo // The texture info for this tile
|
|
152
166
|
|
|
153
167
|
// Texture Info Object
|
|
154
|
-
TextureInfo(image)
|
|
155
|
-
TextureInfo.image
|
|
156
|
-
TextureInfo.size
|
|
157
|
-
TextureInfo.glTexture
|
|
168
|
+
TextureInfo(image) // Created automatically for each image
|
|
169
|
+
TextureInfo.image // Image source
|
|
170
|
+
TextureInfo.size // Size of the image
|
|
171
|
+
TextureInfo.glTexture // WebGL texture
|
|
158
172
|
|
|
159
173
|
// Font Image Object draws text using characters in an image
|
|
160
174
|
FontImage(image, tileSize=(8,8), paddingSize=(0,1)) // Create an image font
|
|
161
175
|
FontImage.drawText(text, pos, scale, center) // Draw text in world space
|
|
162
176
|
FontImage.drawTextScreen(text, pos, scale, center) // Draw text in screen space
|
|
177
|
+
FontImage.drawTextOverlay(text, pos, scale, center) // Draw text to overlay canvas
|
|
163
178
|
|
|
164
179
|
// Camera settings
|
|
165
180
|
cameraPos = (0,0) // Position of camera in world space
|
|
@@ -183,31 +198,45 @@ tileFixBleedScale = .3 // How much smaller to draw tiles to prevent bleeding
|
|
|
183
198
|
```
|
|
184
199
|
|
|
185
200
|
## LittleJS Audio System
|
|
186
|
-
- Caches sounds and music for fast playback
|
|
201
|
+
- Caches sounds and music for fast playback with frame-spread loading
|
|
202
|
+
- Individual sound instance control with pause/resume capabilities
|
|
187
203
|
- Can attenuate and apply stereo panning to sounds
|
|
188
|
-
- Ability to play mp3, ogg, and wave
|
|
204
|
+
- Ability to play mp3, ogg, and wave files with loading progress tracking
|
|
189
205
|
- [ZzFX Sound Effect Generator](https://killedbyapixel.github.io/ZzFX)
|
|
190
206
|
- [ZzFXM Music System](https://keithclark.github.io/ZzFXM)
|
|
191
207
|
|
|
192
208
|
```javascript
|
|
193
209
|
// Sound Object
|
|
194
|
-
Sound(zzfxSound)
|
|
195
|
-
SoundWave(filename, randomness=0)
|
|
196
|
-
Sound.play(pos, volume=1, pitch=1, randomness=1, loop)
|
|
197
|
-
Sound.
|
|
198
|
-
Sound.
|
|
199
|
-
Sound.
|
|
200
|
-
Sound.
|
|
201
|
-
Sound.
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
210
|
+
Sound(zzfxSound, range, taper) // Create a zzfx sound
|
|
211
|
+
SoundWave(filename, randomness=0, range, taper) // Load a wave, mp3, or ogg
|
|
212
|
+
Sound.play(pos, volume=1, pitch=1, randomness=1, loop) // Play a sound, returns SoundInstance
|
|
213
|
+
Sound.playMusic(volume=1, loop=true) // Play as music with looping
|
|
214
|
+
Sound.playNote(semitoneOffset, pos, volume=1) // Play as note with a semitone offset
|
|
215
|
+
Sound.getDuration() // Get length of sound in seconds
|
|
216
|
+
Sound.isLoaded() // Check if sound is currently loading
|
|
217
|
+
Sound.loadedPercent // Get loading progress (0 to 1)
|
|
218
|
+
|
|
219
|
+
// SoundInstance
|
|
220
|
+
SoundInstance.start() // Start playing the sound
|
|
221
|
+
SoundInstance.setVolume(volume) // Change volume during playback
|
|
222
|
+
SoundInstance.stop(fadeTime=0) // Stop with optional fade out
|
|
223
|
+
SoundInstance.pause() // Pause the sound
|
|
224
|
+
SoundInstance.unpause() // Resume paused sound
|
|
225
|
+
SoundInstance.isPlaying() // Check if currently playing
|
|
226
|
+
SoundInstance.isPaused() // Check if paused
|
|
227
|
+
SoundInstance.isStopped() // Check if stopped
|
|
228
|
+
SoundInstance.getCurrentTime() // Get current playback position
|
|
229
|
+
SoundInstance.getDuration() // Get total duration
|
|
230
|
+
SoundInstance.getSource() // Get AudioBufferSourceNode
|
|
231
|
+
|
|
232
|
+
// ZzFXM - Tiny music playing system
|
|
233
|
+
Music(..zzfxMusic) // Create a zzfx music object
|
|
234
|
+
Music.playMusic(volume=1, loop=true) // Play the music
|
|
206
235
|
|
|
207
236
|
// Audio functions
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
237
|
+
speak(text, language='', volume=1, rate=1, pitch=1) // Speak text line
|
|
238
|
+
speakStop() // Stop all queued speech
|
|
239
|
+
getNoteFrequency(semitoneOffset, rootFrequency=220) // Get frequency for musical notes
|
|
211
240
|
|
|
212
241
|
// Audio settings
|
|
213
242
|
soundEnable = true // Should sound be enabled?
|
|
@@ -228,11 +257,13 @@ soundDefaultTaper = .7 // Default range percent to taper off sound (0-1)
|
|
|
228
257
|
keyIsDown(key) // Is key down?
|
|
229
258
|
keyWasPressed(key) // Was key pressed this frame?
|
|
230
259
|
keyWasReleased(key) // Was key released this frame?
|
|
231
|
-
keyDirection(up, down, left, right)
|
|
260
|
+
keyDirection(up, down, left, right) // Get input vector from arrow keys or wasd
|
|
232
261
|
|
|
233
262
|
// Mouse / Touch
|
|
234
263
|
mousePos // World space mouse position
|
|
235
264
|
mousePosScreen // Screen space mouse position
|
|
265
|
+
mouseDelta // World space mouse movement delta
|
|
266
|
+
mouseDeltaScreen // Screen space mouse movement delta
|
|
236
267
|
mouseWheel // Delta mouse wheel this frame
|
|
237
268
|
mouseIsDown(button) // Is mouse button down?
|
|
238
269
|
mouseWasPressed(button) // Was mouse button pressed this frame?
|
|
@@ -286,7 +317,7 @@ EngineObject.render() // Render object, called auto
|
|
|
286
317
|
EngineObject.destroy() // Destroy this object and children
|
|
287
318
|
EngineObject.collideWithTile(tileData, pos) // Tile collision resolve check
|
|
288
319
|
EngineObject.collideWithObject(object) // Object collision resolve check
|
|
289
|
-
EngineObject.getAliveTime(
|
|
320
|
+
EngineObject.getAliveTime() // How long since object was created
|
|
290
321
|
EngineObject.applyAcceleration(acceleration) // Apply acceleration
|
|
291
322
|
EngineObject.applyForce(force) // Apply force
|
|
292
323
|
EngineObject.getMirrorSign() // Get mirror direction (1 or -1)
|
|
@@ -324,7 +355,7 @@ objectMaxSpeed = 1 // Clamp max speed to avoid fast objects missing c
|
|
|
324
355
|
gravity = (0,0) // How much gravity to apply to objects
|
|
325
356
|
|
|
326
357
|
// Engine Object functions
|
|
327
|
-
engineObjectsCollect(pos, size, objects=engineObjects)
|
|
358
|
+
engineObjectsCollect(pos, size, objects=engineObjects)
|
|
328
359
|
engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
|
|
329
360
|
engineObjectsRaycast(start, end, objects=engineObjects)
|
|
330
361
|
engineObjectsDestroy()
|
|
@@ -341,6 +372,13 @@ engineObjectsDestroy()
|
|
|
341
372
|
|
|
342
373
|
```javascript
|
|
343
374
|
|
|
375
|
+
// Canvas Layer
|
|
376
|
+
CanvasLayer(position, size) // Create a canvas layer object
|
|
377
|
+
CanvasLayer.canvas // The canvas used by this layer
|
|
378
|
+
CanvasLayer.context // The 2D context of the canvas
|
|
379
|
+
CanvasLayer.getImageData() // Get image data from canvas
|
|
380
|
+
CanvasLayer.useWebGL() // Creates or updates WebGL texture
|
|
381
|
+
|
|
344
382
|
// LittleJS Layer System
|
|
345
383
|
TileLayer(position, size, tileInfo, scale) // Create a tile layer object
|
|
346
384
|
TileLayer.setData(layerPos, data, redraw) // Set data at position
|
|
@@ -353,7 +391,7 @@ TileLayer.drawCanvas2D(pos, size, angle, mirror, drawFunction) // Draw to 2
|
|
|
353
391
|
|
|
354
392
|
// Tile Layer Data Object
|
|
355
393
|
TileLayerData(tile, direction=0, mirror=false, color=WHITE) // Create tile data object
|
|
356
|
-
TileLayerData.clear()
|
|
394
|
+
TileLayerData.clear() // Clear this tile data
|
|
357
395
|
|
|
358
396
|
// Tile Collision Layer
|
|
359
397
|
TileCollisionLayer(position, size, tileInfo=tile()) // Create a tile collision layer object
|
|
@@ -387,10 +425,10 @@ particleEmitRateScale = 1 // Scales particles emit rate
|
|
|
387
425
|
|
|
388
426
|
```javascript
|
|
389
427
|
ASSERT(assert, output) // Asserts if the expression is false
|
|
390
|
-
debugRect(pos, size, color='#fff', time=0, angle=0, fill)
|
|
391
|
-
debugCircle(pos, radius, color='#fff', time=0, fill)
|
|
428
|
+
debugRect(pos, size, color='#fff', time=0, angle=0, fill) // Draw debug rectangle
|
|
429
|
+
debugCircle(pos, radius, color='#fff', time=0, fill) // Draw debug circle
|
|
392
430
|
debugPoint(pos, color, time, angle) // Draw debug point
|
|
393
|
-
debugLine(posA, posB, color,
|
|
431
|
+
debugLine(posA, posB, color, width=.1, time) // Draw debug line
|
|
394
432
|
debugText(text, pos, size=1, color='#fff', time=0, angle=0) // Draw debug text
|
|
395
433
|
debugAABB(pA, sA, pB, sB, color) // Draw a debug axis aligned box
|
|
396
434
|
debugClear() // Clear all debug primitives
|
package/src/engine.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
2
|
* LittleJS - The Tiny Fast JavaScript Game Engine
|
|
3
3
|
* MIT License - Copyright 2021 Frank Force
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* Engine Features
|
|
6
6
|
* - Object oriented system with base class engine object
|
|
7
7
|
* - Base class object handles update, physics, collision, rendering, etc
|
|
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
|
|
|
30
30
|
* @type {string}
|
|
31
31
|
* @default
|
|
32
32
|
* @memberof Engine */
|
|
33
|
-
const engineVersion = '1.
|
|
33
|
+
const engineVersion = '1.14.4';
|
|
34
34
|
|
|
35
35
|
/** Frames per second to update
|
|
36
36
|
* @type {number}
|
|
@@ -120,7 +120,7 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
120
120
|
* // Basic engine startup
|
|
121
121
|
* engineInit(
|
|
122
122
|
* () => { console.log('Game initialized!'); }, // gameInit
|
|
123
|
-
* () => {
|
|
123
|
+
* () => { updateGameLogic(); }, // gameUpdate
|
|
124
124
|
* () => { updateUI(); }, // gameUpdatePost
|
|
125
125
|
* () => { drawBackground(); }, // gameRender
|
|
126
126
|
* () => { drawHUD(); }, // gameRenderPost
|
|
@@ -146,7 +146,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
146
146
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
147
147
|
|
|
148
148
|
// disable smoothing for pixel art
|
|
149
|
-
overlayContext.imageSmoothingEnabled =
|
|
149
|
+
overlayContext.imageSmoothingEnabled =
|
|
150
150
|
mainContext.imageSmoothingEnabled = !tilesPixelated;
|
|
151
151
|
|
|
152
152
|
// setup gl rendering if enabled
|
|
@@ -194,7 +194,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
194
194
|
deltaSmooth = frameTimeBufferMS;
|
|
195
195
|
frameTimeBufferMS = 0;
|
|
196
196
|
}
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
// update multiple frames if necessary in case of slow framerate
|
|
199
199
|
for (;frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
|
|
200
200
|
{
|
|
@@ -239,15 +239,14 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
239
239
|
overlayContext.textBaseline = 'top';
|
|
240
240
|
overlayContext.font = '1em monospace';
|
|
241
241
|
overlayContext.fillStyle = '#000';
|
|
242
|
-
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
242
|
+
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
243
243
|
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
244
244
|
+ (glEnable ? ' GL' : ' 2D') ;
|
|
245
245
|
overlayContext.fillText(text, mainCanvas.width-3, 3);
|
|
246
246
|
overlayContext.fillStyle = '#fff';
|
|
247
247
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
248
248
|
}
|
|
249
|
-
|
|
250
|
-
drawCount = 0;
|
|
249
|
+
drawCount = 0;
|
|
251
250
|
}
|
|
252
251
|
requestAnimationFrame(engineUpdate);
|
|
253
252
|
}
|
|
@@ -255,13 +254,13 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
255
254
|
function updateCanvas()
|
|
256
255
|
{
|
|
257
256
|
if (headlessMode) return;
|
|
258
|
-
|
|
257
|
+
|
|
259
258
|
if (canvasFixedSize.x)
|
|
260
259
|
{
|
|
261
260
|
// clear canvas and set fixed size
|
|
262
261
|
mainCanvas.width = canvasFixedSize.x;
|
|
263
262
|
mainCanvas.height = canvasFixedSize.y;
|
|
264
|
-
|
|
263
|
+
|
|
265
264
|
// fit to window by adding space on top or bottom if necessary
|
|
266
265
|
const aspect = innerWidth / innerHeight;
|
|
267
266
|
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
@@ -271,16 +270,21 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
271
270
|
else
|
|
272
271
|
{
|
|
273
272
|
// clear canvas and set size to same as window
|
|
274
|
-
mainCanvas.width
|
|
273
|
+
mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
275
274
|
mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
276
275
|
}
|
|
277
|
-
|
|
276
|
+
|
|
278
277
|
// clear overlay canvas and set size
|
|
279
278
|
overlayCanvas.width = mainCanvas.width;
|
|
280
279
|
overlayCanvas.height = mainCanvas.height;
|
|
281
280
|
|
|
282
281
|
// save canvas size
|
|
283
282
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
283
|
+
|
|
284
|
+
// set default line join and cap
|
|
285
|
+
const lineJoin = 'round', lineCap = 'round';
|
|
286
|
+
mainContext.lineJoin = overlayContext.lineJoin = lineJoin;
|
|
287
|
+
mainContext.lineCap = overlayContext.lineCap = lineCap;
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
// wait for gameInit to load
|
|
@@ -293,15 +297,14 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
293
297
|
return startEngine();
|
|
294
298
|
|
|
295
299
|
// setup html
|
|
296
|
-
const styleRoot =
|
|
300
|
+
const styleRoot =
|
|
297
301
|
'margin:0;' + // fill the window
|
|
298
302
|
'overflow:hidden;' + // no scroll bars
|
|
299
303
|
'background:#000;' + // set background color
|
|
300
304
|
'user-select:none;' + // prevent hold to select
|
|
301
305
|
'-webkit-user-select:none;' + // compatibility for ios
|
|
302
|
-
(!touchInputEnable ? '' : // no touch css settings
|
|
303
306
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
304
|
-
'-webkit-touch-callout:none'
|
|
307
|
+
'-webkit-touch-callout:none';// compatibility for ios
|
|
305
308
|
rootElement.style.cssText = styleRoot;
|
|
306
309
|
drawCanvas = mainCanvas = document.createElement('canvas');
|
|
307
310
|
rootElement.appendChild(mainCanvas);
|
|
@@ -318,7 +321,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
318
321
|
rootElement.appendChild(overlayCanvas);
|
|
319
322
|
overlayContext = overlayCanvas.getContext('2d');
|
|
320
323
|
|
|
321
|
-
// set
|
|
324
|
+
// set canvases
|
|
322
325
|
const styleCanvas = 'position:absolute;'+ // allow canvases to overlap
|
|
323
326
|
'top:50%;left:50%;transform:translate(-50%,-50%)'; // center on screen
|
|
324
327
|
mainCanvas.style.cssText = overlayCanvas.style.cssText = styleCanvas;
|
|
@@ -327,17 +330,18 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
327
330
|
setCanvasPixelated(canvasPixelated);
|
|
328
331
|
setOverlayCanvasPixelated(overlayCanvasPixelated);
|
|
329
332
|
updateCanvas();
|
|
333
|
+
glPreRender();
|
|
330
334
|
|
|
331
335
|
// create offscreen canvas for image processing
|
|
332
336
|
workCanvas = new OffscreenCanvas(256, 256);
|
|
333
337
|
workContext = workCanvas.getContext('2d', { willReadFrequently: true });
|
|
334
|
-
|
|
338
|
+
|
|
335
339
|
// create promises for loading images
|
|
336
340
|
const promises = imageSources.map((src, textureIndex)=>
|
|
337
|
-
new Promise(resolve =>
|
|
341
|
+
new Promise(resolve =>
|
|
338
342
|
{
|
|
339
343
|
const image = new Image;
|
|
340
|
-
image.onerror = image.onload = ()=>
|
|
344
|
+
image.onerror = image.onload = ()=>
|
|
341
345
|
{
|
|
342
346
|
const textureInfo = new TextureInfo(image);
|
|
343
347
|
textureInfo.createWebGLTexture();
|
|
@@ -352,7 +356,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
352
356
|
if (!imageSources.length)
|
|
353
357
|
{
|
|
354
358
|
// no images to load
|
|
355
|
-
promises.push(new Promise(resolve =>
|
|
359
|
+
promises.push(new Promise(resolve =>
|
|
356
360
|
{
|
|
357
361
|
const textureInfo = new TextureInfo(new Image);
|
|
358
362
|
textureInfos[0] = textureInfo;
|
|
@@ -364,7 +368,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
364
368
|
if (showSplashScreen)
|
|
365
369
|
{
|
|
366
370
|
// draw splash screen
|
|
367
|
-
promises.push(new Promise(resolve =>
|
|
371
|
+
promises.push(new Promise(resolve =>
|
|
368
372
|
{
|
|
369
373
|
let t = 0;
|
|
370
374
|
console.log(`${engineName} Engine v${engineVersion}`);
|
|
@@ -596,7 +600,7 @@ function drawEngineSplashScreen(t)
|
|
|
596
600
|
line(36,20,60,20);
|
|
597
601
|
|
|
598
602
|
// engine front light
|
|
599
|
-
circle(60,30,4,PI,3*PI,color(3,2));
|
|
603
|
+
circle(60,30,4,PI,3*PI,color(3,2));
|
|
600
604
|
circle(60,30,4,PI,2*PI,color(3,3));
|
|
601
605
|
circle(60,30,4,PI,3*PI);
|
|
602
606
|
|
|
@@ -645,6 +649,6 @@ function drawEngineSplashScreen(t)
|
|
|
645
649
|
x[j?'strokeText':'fillText'](s[i],X+w/2,55.5,17*p);
|
|
646
650
|
X += w;
|
|
647
651
|
}
|
|
648
|
-
|
|
652
|
+
|
|
649
653
|
x.restore();
|
|
650
654
|
}
|