littlejsengine 1.1.18 → 1.2.3
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 +17 -11
- package/build.bat +1 -0
- package/engine/engine.all.js +495 -504
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +418 -259
- package/engine/engine.js +31 -23
- package/engine/engineAudio.js +21 -7
- package/engine/engineBuild.bat +9 -1
- package/engine/engineBuildSetup.bat +2 -1
- package/engine/engineDebug.js +81 -247
- package/engine/engineDraw.js +109 -21
- package/engine/engineFont.png +0 -0
- package/engine/engineInput.js +103 -50
- package/engine/engineMedals.js +17 -20
- package/engine/engineObject.js +14 -23
- package/engine/engineParticles.js +8 -6
- package/engine/engineRelease.js +3 -1
- package/engine/engineSettings.js +20 -10
- package/engine/engineTileLayer.js +19 -18
- package/engine/engineUtilities.js +14 -12
- package/engine/engineWebGL.js +59 -68
- package/engine/index.d.ts +1617 -0
- package/examples/breakout/game.js +9 -7
- package/examples/breakout/gameObjects.js +3 -3
- package/examples/breakout/index.html +6 -4
- package/examples/platformer/game.js +5 -5
- package/examples/platformer/gameEffects.js +11 -14
- package/examples/platformer/gameLevel.js +14 -7
- package/examples/platformer/gameObjects.js +3 -3
- package/examples/platformer/gamePlayer.js +13 -8
- package/examples/platformer/index.html +9 -7
- package/examples/platformer/tiles.png +0 -0
- package/examples/puzzle/game.js +2 -2
- package/examples/puzzle/index.html +5 -3
- package/examples/screenshot.jpg +0 -0
- package/examples/stress/index.html +7 -5
- package/game.js +9 -8
- package/index.html +16 -14
- package/package.json +1 -1
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* let pos = vec2(2,3);
|
|
16
16
|
* let particleEmiter = new ParticleEmitter
|
|
17
17
|
* (
|
|
18
|
-
* pos, 1, 0, 500, PI, // pos, emitSize, emitTime, emitRate, emiteCone
|
|
18
|
+
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
19
19
|
* 0, vec2(16), // tileIndex, tileSize
|
|
20
|
-
* new Color,
|
|
20
|
+
* new Color(1,1,1), new Color(0,0,0), // colorStartA, colorStartB
|
|
21
21
|
* new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
|
|
22
22
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
23
23
|
* .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
|
|
@@ -28,6 +28,7 @@ class ParticleEmitter extends EngineObject
|
|
|
28
28
|
{
|
|
29
29
|
/** Create a particle system with the given settings
|
|
30
30
|
* @param {Vector2} position - World space position of the emitter
|
|
31
|
+
* @param {Number} [angle=0] - Angle to rotate the object
|
|
31
32
|
* @param {Number} [emitSize=0] - World space size of the emitter (float for circle diameter, vec2 for rect)
|
|
32
33
|
* @param {Number} [emitTime=0] - How long to stay alive (0 is forever)
|
|
33
34
|
* @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
|
|
@@ -51,12 +52,13 @@ class ParticleEmitter extends EngineObject
|
|
|
51
52
|
* @param {Number} [randomness=.2] - Apply extra randomness percent
|
|
52
53
|
* @param {Boolean} [collideTiles=0] - Do particles collide against tiles
|
|
53
54
|
* @param {Boolean} [additive=0] - Should particles use addtive blend
|
|
54
|
-
* @param {Boolean} [randomColorLinear=
|
|
55
|
+
* @param {Boolean} [randomColorLinear=1] - Should color be randomized linearly or across each component
|
|
55
56
|
* @param {Number} [renderOrder=0] - Render order for particles (additive is above other stuff by default)
|
|
56
57
|
*/
|
|
57
58
|
constructor
|
|
58
59
|
(
|
|
59
60
|
pos,
|
|
61
|
+
angle,
|
|
60
62
|
emitSize = 0,
|
|
61
63
|
emitTime = 0,
|
|
62
64
|
emitRate = 100,
|
|
@@ -84,7 +86,7 @@ class ParticleEmitter extends EngineObject
|
|
|
84
86
|
renderOrder = additive ? 1e9 : 0
|
|
85
87
|
)
|
|
86
88
|
{
|
|
87
|
-
super(pos, new Vector2, tileIndex, tileSize,
|
|
89
|
+
super(pos, new Vector2, tileIndex, tileSize, angle, undefined, renderOrder);
|
|
88
90
|
|
|
89
91
|
// emitter settings
|
|
90
92
|
/** @property {Number} - World space size of the emitter (float for circle diameter, vec2 for rect) */
|
|
@@ -152,9 +154,9 @@ class ParticleEmitter extends EngineObject
|
|
|
152
154
|
if (!this.emitTime || this.getAliveTime() <= this.emitTime)
|
|
153
155
|
{
|
|
154
156
|
// emit particles
|
|
155
|
-
if (this.emitRate)
|
|
157
|
+
if (this.emitRate * particleEmitRateScale)
|
|
156
158
|
{
|
|
157
|
-
const rate = 1/this.emitRate;
|
|
159
|
+
const rate = 1/this.emitRate/particleEmitRateScale;
|
|
158
160
|
for (this.emitTimeBuffer += timeDelta; this.emitTimeBuffer > 0; this.emitTimeBuffer -= rate)
|
|
159
161
|
this.emitParticle();
|
|
160
162
|
}
|
package/engine/engineRelease.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
LittleJS - Release
|
|
2
|
+
LittleJS - Release Build
|
|
3
|
+
MIT License - Copyright 2021 Frank Force
|
|
4
|
+
|
|
3
5
|
- This file is used for release builds in place of engineDebug.js
|
|
4
6
|
- Debug functionality will be disabled to lower size and increase performance
|
|
5
7
|
*/
|
package/engine/engineSettings.js
CHANGED
|
@@ -42,7 +42,7 @@ let tileSizeDefault = vec2(16);
|
|
|
42
42
|
/** Prevent tile bleeding from neighbors in pixels
|
|
43
43
|
* @default
|
|
44
44
|
* @memberof Settings */
|
|
45
|
-
let
|
|
45
|
+
let tileFixBleedScale = .3;
|
|
46
46
|
|
|
47
47
|
///////////////////////////////////////////////////////////////////////////////
|
|
48
48
|
// Object settings
|
|
@@ -88,6 +88,11 @@ let objectMaxSpeed = 1;
|
|
|
88
88
|
* @memberof Settings */
|
|
89
89
|
let gravity = 0;
|
|
90
90
|
|
|
91
|
+
/** Scales emit rate of particles, useful for low graphics mode (0 disables particle emitters)
|
|
92
|
+
* @default
|
|
93
|
+
* @memberof Settings */
|
|
94
|
+
let particleEmitRateScale = 1;
|
|
95
|
+
|
|
91
96
|
///////////////////////////////////////////////////////////////////////////////
|
|
92
97
|
// Camera settings
|
|
93
98
|
|
|
@@ -133,11 +138,6 @@ let gamepadDirectionEmulateStick = 1;
|
|
|
133
138
|
* @memberof Settings */
|
|
134
139
|
let inputWASDEmulateDirection = 1;
|
|
135
140
|
|
|
136
|
-
/** If true touch input is routed to mouse functions
|
|
137
|
-
* @default
|
|
138
|
-
* @memberof Settings */
|
|
139
|
-
let touchMouseEnable = 1;
|
|
140
|
-
|
|
141
141
|
/** True if touch gamepad should appear on mobile devices
|
|
142
142
|
* <br> - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
143
143
|
* <br> - Must be set by end of gameInit to be activated
|
|
@@ -145,6 +145,11 @@ let touchMouseEnable = 1;
|
|
|
145
145
|
* @memberof Settings */
|
|
146
146
|
let touchGamepadEnable = 0;
|
|
147
147
|
|
|
148
|
+
/** True if touch gamepad should be analog stick or false to use if 8 way dpad
|
|
149
|
+
* @default
|
|
150
|
+
* @memberof Settings */
|
|
151
|
+
let touchGamepadAnalog = 1;
|
|
152
|
+
|
|
148
153
|
/** Size of virutal gamepad for touch devices in pixels
|
|
149
154
|
* @default
|
|
150
155
|
* @memberof Settings */
|
|
@@ -153,7 +158,12 @@ let touchGamepadSize = 80;
|
|
|
153
158
|
/** Transparency of touch gamepad overlay
|
|
154
159
|
* @default
|
|
155
160
|
* @memberof Settings */
|
|
156
|
-
let touchGamepadAlpha = .
|
|
161
|
+
let touchGamepadAlpha = .3;
|
|
162
|
+
|
|
163
|
+
/** Allow vibration hardware if it exists
|
|
164
|
+
* @default
|
|
165
|
+
* @memberof Settings */
|
|
166
|
+
let vibrateEnable = 1;
|
|
157
167
|
|
|
158
168
|
///////////////////////////////////////////////////////////////////////////////
|
|
159
169
|
// Audio settings
|
|
@@ -166,7 +176,7 @@ let soundVolume = .5;
|
|
|
166
176
|
/** All audio code can be disabled and removed from build
|
|
167
177
|
* @default
|
|
168
178
|
* @memberof Settings */
|
|
169
|
-
let soundEnable =
|
|
179
|
+
let soundEnable = 1;
|
|
170
180
|
|
|
171
181
|
/** Default range where sound no longer plays
|
|
172
182
|
* @default
|
|
@@ -199,9 +209,9 @@ let medalDisplayWidth = 640;
|
|
|
199
209
|
/** Height of medal display
|
|
200
210
|
* @default
|
|
201
211
|
* @memberof Settings */
|
|
202
|
-
let medalDisplayHeight =
|
|
212
|
+
let medalDisplayHeight = 80;
|
|
203
213
|
|
|
204
214
|
/** Size of icon in medal display
|
|
205
215
|
* @default
|
|
206
216
|
* @memberof Settings */
|
|
207
|
-
let medalDisplayIconSize =
|
|
217
|
+
let medalDisplayIconSize = 50;
|
|
@@ -142,8 +142,9 @@ class TileLayerData
|
|
|
142
142
|
/**
|
|
143
143
|
* Tile layer object - cached rendering system for tile layers
|
|
144
144
|
* <br> - Each Tile layer is rendered to an off screen canvas
|
|
145
|
-
* <br> -
|
|
146
|
-
* <br> -
|
|
145
|
+
* <br> - To allow dynamic modifications, layers are rendered using canvas 2d
|
|
146
|
+
* <br> - Some devices like mobile phones are limited to 4k texture resolution
|
|
147
|
+
* <br> - So with 16x16 tiles this limits layers to 256x256 on mobile devices
|
|
147
148
|
* @extends EngineObject
|
|
148
149
|
* @example
|
|
149
150
|
* // create tile collision and visible tile layer
|
|
@@ -153,11 +154,11 @@ class TileLayerData
|
|
|
153
154
|
class TileLayer extends EngineObject
|
|
154
155
|
{
|
|
155
156
|
/** Create a tile layer object
|
|
156
|
-
* @param {Vector2} [position=new Vector2(
|
|
157
|
-
* @param {Vector2} [size=objectDefaultSize]
|
|
158
|
-
* @param {Vector2} [tileSize=tileSizeDefault]
|
|
159
|
-
* @param {Vector2} [scale=new Vector2(1,1)]
|
|
160
|
-
* @param {Number} [renderOrder=0]
|
|
157
|
+
* @param {Vector2} [position=new Vector2()] - World space position
|
|
158
|
+
* @param {Vector2} [size=objectDefaultSize] - World space size
|
|
159
|
+
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
|
|
160
|
+
* @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
|
|
161
|
+
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
161
162
|
*/
|
|
162
163
|
constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
|
|
163
164
|
{
|
|
@@ -208,7 +209,7 @@ class TileLayer extends EngineObject
|
|
|
208
209
|
// flush and copy gl canvas because tile canvas does not use webgl
|
|
209
210
|
glEnable && !glOverlay && !this.isOverlay && glCopyToContext(mainContext);
|
|
210
211
|
|
|
211
|
-
// draw the entire cached level onto the
|
|
212
|
+
// draw the entire cached level onto the canvas
|
|
212
213
|
const pos = worldToScreen(this.pos.add(vec2(0,this.size.y*this.scale.y)));
|
|
213
214
|
(this.isOverlay ? overlayContext : mainContext).drawImage
|
|
214
215
|
(
|
|
@@ -217,25 +218,25 @@ class TileLayer extends EngineObject
|
|
|
217
218
|
);
|
|
218
219
|
}
|
|
219
220
|
|
|
220
|
-
/** Draw all the tile data to an offscreen canvas
|
|
221
|
+
/** Draw all the tile data to an offscreen canvas
|
|
222
|
+
* - This may be slow in some browsers
|
|
223
|
+
*/
|
|
221
224
|
redraw()
|
|
222
225
|
{
|
|
223
|
-
this.redrawStart();
|
|
226
|
+
this.redrawStart(1);
|
|
224
227
|
this.drawAllTileData();
|
|
225
228
|
this.redrawEnd();
|
|
226
229
|
}
|
|
227
230
|
|
|
228
231
|
/** Call to start the redraw process
|
|
229
|
-
* @param {Boolean} [clear=
|
|
230
|
-
redrawStart(clear =
|
|
232
|
+
* @param {Boolean} [clear=0] - Should it clear the canvas before drawing */
|
|
233
|
+
redrawStart(clear = 0)
|
|
231
234
|
{
|
|
232
|
-
// clear and set size
|
|
233
|
-
const width = this.size.x * this.tileSize.x;
|
|
234
|
-
const height = this.size.y * this.tileSize.y;
|
|
235
235
|
if (clear)
|
|
236
236
|
{
|
|
237
|
-
|
|
238
|
-
this.canvas.
|
|
237
|
+
// clear and set size
|
|
238
|
+
this.canvas.width = this.size.x * this.tileSize.x;
|
|
239
|
+
this.canvas.height = this.size.y * this.tileSize.y;
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
// save current render settings
|
|
@@ -325,7 +326,7 @@ class TileLayer extends EngineObject
|
|
|
325
326
|
else
|
|
326
327
|
{
|
|
327
328
|
const cols = tileImage.width/tileSize.x;
|
|
328
|
-
context.globalAlpha = color.a; //
|
|
329
|
+
context.globalAlpha = color.a; // only alpha, no color, is supported in this mode
|
|
329
330
|
context.drawImage(tileImage,
|
|
330
331
|
(tileIndex%cols)*tileSize.x, (tileIndex/cols|0)*tileSize.x,
|
|
331
332
|
tileSize.x, tileSize.y, -.5, -.5, 1, 1);
|
|
@@ -49,27 +49,27 @@ const mod = (a, b=1)=> ((a % b) + b) % b;
|
|
|
49
49
|
|
|
50
50
|
/** Clamps the value beween max and min
|
|
51
51
|
* @param {Number} value
|
|
52
|
-
* @param {Number} [max=1]
|
|
53
52
|
* @param {Number} [min=0]
|
|
53
|
+
* @param {Number} [max=1]
|
|
54
54
|
* @return {Number}
|
|
55
55
|
* @memberof Utilities */
|
|
56
|
-
const clamp = (v,
|
|
56
|
+
const clamp = (v, min=0, max=1)=> v < min ? min : v > max ? max : v;
|
|
57
57
|
|
|
58
58
|
/** Returns what percentage the value is between max and min
|
|
59
59
|
* @param {Number} value
|
|
60
|
-
* @param {Number} [max=1]
|
|
61
60
|
* @param {Number} [min=0]
|
|
61
|
+
* @param {Number} [max=1]
|
|
62
62
|
* @return {Number}
|
|
63
63
|
* @memberof Utilities */
|
|
64
|
-
const percent = (v,
|
|
64
|
+
const percent = (v, min=0, max=1)=> max-min ? clamp((v-min) / (max-min)) : 0;
|
|
65
65
|
|
|
66
66
|
/** Linearly interpolates the percent value between max and min
|
|
67
67
|
* @param {Number} percent
|
|
68
|
-
* @param {Number} [max=1]
|
|
69
68
|
* @param {Number} [min=0]
|
|
69
|
+
* @param {Number} [max=1]
|
|
70
70
|
* @return {Number}
|
|
71
71
|
* @memberof Utilities */
|
|
72
|
-
const lerp = (p,
|
|
72
|
+
const lerp = (p, min=0, max=1)=> min + clamp(p) * (max-min);
|
|
73
73
|
|
|
74
74
|
/** Applies smoothstep function to the percentage value
|
|
75
75
|
* @param {Number} value
|
|
@@ -84,11 +84,11 @@ const smoothStep = (p)=> p * p * (3 - 2 * p);
|
|
|
84
84
|
const nearestPowerOfTwo = (v)=> 2**Math.ceil(Math.log2(v));
|
|
85
85
|
|
|
86
86
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
87
|
-
* @param {Vector2} pointA
|
|
88
|
-
* @param {Vector2} sizeA
|
|
89
|
-
* @param {Vector2} pointB
|
|
90
|
-
* @param {Vector2} sizeB
|
|
91
|
-
* @return {Boolean}
|
|
87
|
+
* @param {Vector2} pointA - Center of box A
|
|
88
|
+
* @param {Vector2} sizeA - Size of box A
|
|
89
|
+
* @param {Vector2} pointB - Center of box B
|
|
90
|
+
* @param {Vector2} [sizeB] - Size of box B
|
|
91
|
+
* @return {Boolean} - True if overlapping
|
|
92
92
|
* @memberof Utilities */
|
|
93
93
|
const isOverlapping = (pA, sA, pB, sB)=> abs(pA.x - pB.x)*2 < sA.x + sB.x & abs(pA.y - pB.y)*2 < sA.y + sB.y;
|
|
94
94
|
|
|
@@ -185,10 +185,12 @@ const vec2 = (x=0, y)=> x.x == undefined ? new Vector2(x, y == undefined? x : y)
|
|
|
185
185
|
|
|
186
186
|
/**
|
|
187
187
|
* 2D Vector object with vector math library
|
|
188
|
+
* <br> - Functions do not change this so they can be chained together
|
|
188
189
|
* @example
|
|
189
190
|
* let a = new Vector2(2, 3); // vector with coordinates (2, 3)
|
|
190
191
|
* let b = new Vector2; // vector with coordinates (0, 0)
|
|
191
192
|
* let c = vec2(4, 2); // use the vec2 function to make a Vector2
|
|
193
|
+
* let d = a.add(b).scale(5); // operators can be chained
|
|
192
194
|
*/
|
|
193
195
|
class Vector2
|
|
194
196
|
{
|
|
@@ -475,5 +477,5 @@ class Timer
|
|
|
475
477
|
|
|
476
478
|
/** Get percentage elapsed based on time it was set to, returns 0 if not set
|
|
477
479
|
* @return {Number} */
|
|
478
|
-
getPercent() { return this.isSet()? percent(this.time - time,
|
|
480
|
+
getPercent() { return this.isSet()? percent(this.time - time, this.setTime, 0) : 0; }
|
|
479
481
|
}
|
package/engine/engineWebGL.js
CHANGED
|
@@ -38,38 +38,33 @@ function glInit()
|
|
|
38
38
|
|
|
39
39
|
// create the canvas and tile texture
|
|
40
40
|
glCanvas = document.createElement('canvas');
|
|
41
|
-
glContext = glCanvas.getContext('webgl');
|
|
42
|
-
|
|
41
|
+
glContext = glCanvas.getContext('webgl', {antialias: false});
|
|
42
|
+
glCanvas.style = styleCanvas;
|
|
43
43
|
glTileTexture = glCreateTexture(tileImage);
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// some browsers are much faster without copying the gl buffer so we just overlay it instead
|
|
48
|
-
document.body.appendChild(glCanvas);
|
|
49
|
-
glCanvas.style = mainCanvas.style.cssText;
|
|
50
|
-
}
|
|
45
|
+
// some browsers are much faster without copying the gl buffer so we just overlay it instead
|
|
46
|
+
glOverlay && document.body.appendChild(glCanvas);
|
|
51
47
|
|
|
52
48
|
// setup vertex and fragment shaders
|
|
53
49
|
glShader = glCreateProgram(
|
|
54
|
-
'precision highp float;'+
|
|
55
|
-
'uniform mat4 m;'+
|
|
56
|
-
'attribute
|
|
57
|
-
'attribute
|
|
58
|
-
'
|
|
59
|
-
'varying
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'}' // end of shader
|
|
50
|
+
'precision highp float;'+ // use highp for better accuracy, lowp for better perf
|
|
51
|
+
'uniform mat4 m;'+ // transform matrix
|
|
52
|
+
'attribute vec2 p,t;'+ // position, uv
|
|
53
|
+
'attribute vec4 c,a;'+ // color, additiveColor
|
|
54
|
+
'varying vec2 v;'+ // return uv
|
|
55
|
+
'varying vec4 d,e;'+ // return color, additiveColor
|
|
56
|
+
'void main(){'+ // shader entry point
|
|
57
|
+
'gl_Position=m*vec4(p,1,1);'+ // transform position
|
|
58
|
+
'v=t;d=c;e=a;'+ // pass stuff to fragment shader
|
|
59
|
+
'}' // end of shader
|
|
65
60
|
,
|
|
66
|
-
'precision
|
|
67
|
-
'varying vec2 v;'+
|
|
68
|
-
'varying vec4 d,e;'+
|
|
69
|
-
'uniform sampler2D
|
|
70
|
-
'void main(){'+
|
|
71
|
-
'gl_FragColor=texture2D(
|
|
72
|
-
'}'
|
|
61
|
+
'precision highp float;'+ // use highp for better accuracy, lowp for better perf
|
|
62
|
+
'varying vec2 v;'+ // uv
|
|
63
|
+
'varying vec4 d,e;'+ // color, additiveColor
|
|
64
|
+
'uniform sampler2D s;'+ // texture
|
|
65
|
+
'void main(){'+ // shader entry point
|
|
66
|
+
'gl_FragColor=texture2D(s,v)*d+e;'+ // modulate texture by color plus additive
|
|
67
|
+
'}' // end of shader
|
|
73
68
|
);
|
|
74
69
|
|
|
75
70
|
// init buffers
|
|
@@ -79,6 +74,7 @@ function glInit()
|
|
|
79
74
|
glColorData = new Uint32Array(glVertexData);
|
|
80
75
|
|
|
81
76
|
// setup the vertex data array
|
|
77
|
+
let offset = glBatchCount = 0;
|
|
82
78
|
const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
|
|
83
79
|
{
|
|
84
80
|
const location = glContext.getAttribLocation(glShader, name);
|
|
@@ -86,13 +82,10 @@ function glInit()
|
|
|
86
82
|
glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
|
|
87
83
|
offset += size*typeSize;
|
|
88
84
|
}
|
|
89
|
-
let offset = glBatchCount = 0;
|
|
90
|
-
initVertexAttribArray('a', gl_FLOAT, 4, 1); // angle
|
|
91
85
|
initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
|
|
92
|
-
initVertexAttribArray('s', gl_FLOAT, 4, 2); // size
|
|
93
86
|
initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
|
|
94
87
|
initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
|
|
95
|
-
initVertexAttribArray('
|
|
88
|
+
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
96
89
|
}
|
|
97
90
|
|
|
98
91
|
/** Set the WebGl blend mode, normally you should call setBlendMode instead
|
|
@@ -113,7 +106,8 @@ function glSetBlendMode(additive)
|
|
|
113
106
|
function glSetTexture(texture=glTileTexture)
|
|
114
107
|
{
|
|
115
108
|
if (!glEnable) return;
|
|
116
|
-
|
|
109
|
+
|
|
110
|
+
// must flush cache with the old texture to set a new one
|
|
117
111
|
if (texture != glActiveTexture)
|
|
118
112
|
glFlush();
|
|
119
113
|
|
|
@@ -206,6 +200,7 @@ function glPreRender(width, height, cameraX, cameraY, cameraScale)
|
|
|
206
200
|
|
|
207
201
|
// clear and set to same size as main canvas
|
|
208
202
|
glContext.viewport(0, 0, glCanvas.width = width, glCanvas.height = height);
|
|
203
|
+
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
209
204
|
|
|
210
205
|
// set up the shader
|
|
211
206
|
glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
|
|
@@ -249,15 +244,13 @@ function glFlush()
|
|
|
249
244
|
* @memberof WebGL */
|
|
250
245
|
function glCopyToContext(context, forceDraw)
|
|
251
246
|
{
|
|
252
|
-
if (!glEnable || !glBatchCount)
|
|
247
|
+
if (!glEnable || !glBatchCount) return;
|
|
253
248
|
|
|
254
249
|
glFlush();
|
|
250
|
+
|
|
251
|
+
// do not draw in overlay mode because the canvas is visible
|
|
255
252
|
if (!glOverlay || forceDraw)
|
|
256
|
-
{
|
|
257
|
-
// do not draw/clear in overlay mode because the canvas is visible
|
|
258
253
|
context.drawImage(glCanvas, 0, 0);
|
|
259
|
-
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
260
|
-
}
|
|
261
254
|
}
|
|
262
255
|
|
|
263
256
|
/** Add a sprite to the gl draw list, used by all gl draw functions
|
|
@@ -280,51 +273,49 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=0xffffff
|
|
|
280
273
|
// flush if there is no room for more verts or if different blend mode
|
|
281
274
|
if (glBatchCount == gl_MAX_BATCH || glBatchAdditive != glAdditive)
|
|
282
275
|
glFlush();
|
|
276
|
+
|
|
277
|
+
// prepare to create the verts from size and angle
|
|
278
|
+
const c = Math.cos(angle)/2, s = Math.sin(angle)/2;
|
|
279
|
+
const cx = c*sizeX, cy = c*sizeY, sx = s*sizeX, sy = s*sizeY;
|
|
283
280
|
|
|
284
281
|
// setup 2 triangles to form a quad
|
|
285
282
|
let offset = glBatchCount++ * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT;
|
|
286
283
|
|
|
287
284
|
// vertex 0
|
|
288
|
-
glPositionData[offset++] =
|
|
289
|
-
glPositionData[offset++] =
|
|
290
|
-
glPositionData[offset++] =
|
|
291
|
-
|
|
292
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
285
|
+
glPositionData[offset++] = x - cx - sy;
|
|
286
|
+
glPositionData[offset++] = y - cy + sx;
|
|
287
|
+
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
288
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
293
289
|
|
|
294
290
|
// vertex 1
|
|
295
|
-
glPositionData[offset++] =
|
|
296
|
-
glPositionData[offset++] =
|
|
297
|
-
glPositionData[offset++] =
|
|
298
|
-
|
|
299
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
291
|
+
glPositionData[offset++] = x + cx + sy;
|
|
292
|
+
glPositionData[offset++] = y + cy - sx;
|
|
293
|
+
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
294
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
300
295
|
|
|
301
296
|
// vertex 2
|
|
302
|
-
glPositionData[offset++] =
|
|
303
|
-
glPositionData[offset++] =
|
|
304
|
-
glPositionData[offset++] =
|
|
305
|
-
|
|
306
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
297
|
+
glPositionData[offset++] = x - cx + sy;
|
|
298
|
+
glPositionData[offset++] = y + cy + sx;
|
|
299
|
+
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv0Y;
|
|
300
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
307
301
|
|
|
308
302
|
// vertex 0
|
|
309
|
-
glPositionData[offset++] =
|
|
310
|
-
glPositionData[offset++] =
|
|
311
|
-
glPositionData[offset++] =
|
|
312
|
-
|
|
313
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
303
|
+
glPositionData[offset++] = x - cx - sy;
|
|
304
|
+
glPositionData[offset++] = y - cy + sx;
|
|
305
|
+
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
306
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
314
307
|
|
|
315
308
|
// vertex 3
|
|
316
|
-
glPositionData[offset++] =
|
|
317
|
-
glPositionData[offset++] =
|
|
318
|
-
glPositionData[offset++] =
|
|
319
|
-
|
|
320
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
309
|
+
glPositionData[offset++] = x + cx - sy;
|
|
310
|
+
glPositionData[offset++] = y - cy - sx;
|
|
311
|
+
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv1Y;
|
|
312
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
321
313
|
|
|
322
314
|
// vertex 1
|
|
323
|
-
glPositionData[offset++] =
|
|
324
|
-
glPositionData[offset++] =
|
|
325
|
-
glPositionData[offset++] =
|
|
326
|
-
|
|
327
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
315
|
+
glPositionData[offset++] = x + cx + sy;
|
|
316
|
+
glPositionData[offset++] = y + cy - sx;
|
|
317
|
+
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
318
|
+
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
328
319
|
}
|
|
329
320
|
|
|
330
321
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -356,6 +347,6 @@ gl_LINK_STATUS = 35714,
|
|
|
356
347
|
|
|
357
348
|
// constants for batch rendering
|
|
358
349
|
gl_VERTICES_PER_QUAD = 6,
|
|
359
|
-
gl_INDICIES_PER_VERT =
|
|
350
|
+
gl_INDICIES_PER_VERT = 6,
|
|
360
351
|
gl_MAX_BATCH = 1<<16,
|
|
361
|
-
gl_VERTEX_BYTE_STRIDE =
|
|
352
|
+
gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2; // vec2 * 2 + (char * 4) * 2
|