littlejsengine 1.1.17 → 1.2.0
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 +13 -3
- package/build.bat +1 -0
- package/engine/engine.all.js +520 -522
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +444 -278
- package/engine/engine.js +68 -33
- package/engine/engineAudio.js +21 -7
- package/engine/engineBuild.bat +9 -1
- package/engine/engineBuildSetup.bat +2 -1
- package/engine/engineDebug.js +80 -246
- package/engine/engineDraw.js +106 -21
- package/engine/engineInput.js +89 -52
- package/engine/engineMedals.js +14 -17
- package/engine/engineObject.js +14 -23
- package/engine/engineParticles.js +3 -3
- package/engine/engineRelease.js +3 -1
- package/engine/engineSettings.js +39 -29
- package/engine/engineTileLayer.js +26 -24
- package/engine/engineUtilities.js +14 -12
- package/engine/engineWebGL.js +47 -56
- package/engine/index.d.ts +1612 -0
- package/examples/breakout/game.js +9 -7
- package/examples/breakout/gameObjects.js +1 -1
- package/examples/breakout/index.html +6 -4
- package/examples/platformer/game.js +2 -2
- package/examples/platformer/gameEffects.js +8 -11
- package/examples/platformer/gameLevel.js +14 -7
- package/examples/platformer/gameObjects.js +1 -1
- 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 +1 -1
- package/examples/puzzle/index.html +5 -3
- package/examples/stress/index.html +6 -4
- package/game.js +5 -4
- package/index.html +16 -14
- package/package.json +1 -1
package/engine/engineSettings.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @type {Vector2}
|
|
13
13
|
* @default
|
|
14
14
|
* @memberof Settings */
|
|
15
|
-
|
|
15
|
+
let canvasMaxSize = vec2(1920, 1200);
|
|
16
16
|
|
|
17
17
|
/** Fixed size of the canvas, if enabled cavnvas size never changes
|
|
18
18
|
* @type {Vector2}
|
|
@@ -37,12 +37,12 @@ let fontDefault = 'arial';
|
|
|
37
37
|
* @type {Vector2}
|
|
38
38
|
* @default
|
|
39
39
|
* @memberof Settings */
|
|
40
|
-
|
|
40
|
+
let tileSizeDefault = vec2(16);
|
|
41
41
|
|
|
42
42
|
/** Prevent tile bleeding from neighbors in pixels
|
|
43
43
|
* @default
|
|
44
44
|
* @memberof Settings */
|
|
45
|
-
|
|
45
|
+
let tileFixBleedScale = .3;
|
|
46
46
|
|
|
47
47
|
///////////////////////////////////////////////////////////////////////////////
|
|
48
48
|
// Object settings
|
|
@@ -51,43 +51,48 @@ const tileBleedShrinkFix = .3;
|
|
|
51
51
|
* @type {Vector2}
|
|
52
52
|
* @default
|
|
53
53
|
* @memberof Settings */
|
|
54
|
-
|
|
54
|
+
let objectDefaultSize = vec2(1);
|
|
55
55
|
|
|
56
56
|
/** Default object mass for collison calcuations (how heavy objects are)
|
|
57
57
|
* @default
|
|
58
58
|
* @memberof Settings */
|
|
59
|
-
|
|
59
|
+
let objectDefaultMass = 1;
|
|
60
60
|
|
|
61
61
|
/** How much to slow velocity by each frame (0-1)
|
|
62
62
|
* @default
|
|
63
63
|
* @memberof Settings */
|
|
64
|
-
|
|
64
|
+
let objectDefaultDamping = .99;
|
|
65
65
|
|
|
66
66
|
/** How much to slow angular velocity each frame (0-1)
|
|
67
67
|
* @default
|
|
68
68
|
* @memberof Settings */
|
|
69
|
-
|
|
69
|
+
let objectDefaultAngleDamping = .99;
|
|
70
70
|
|
|
71
71
|
/** How much to bounce when a collision occurs (0-1)
|
|
72
72
|
* @default
|
|
73
73
|
* @memberof Settings */
|
|
74
|
-
|
|
74
|
+
let objectDefaultElasticity = 0;
|
|
75
75
|
|
|
76
76
|
/** How much to slow when touching (0-1)
|
|
77
77
|
* @default
|
|
78
78
|
* @memberof Settings */
|
|
79
|
-
|
|
79
|
+
let objectDefaultFriction = .8;
|
|
80
80
|
|
|
81
81
|
/** Clamp max speed to avoid fast objects missing collisions
|
|
82
82
|
* @default
|
|
83
83
|
* @memberof Settings */
|
|
84
|
-
|
|
84
|
+
let objectMaxSpeed = 1;
|
|
85
85
|
|
|
86
86
|
/** How much gravity to apply to objects along the Y axis, negative is down
|
|
87
87
|
* @default
|
|
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
|
|
|
@@ -108,7 +113,7 @@ let cameraScale = max(tileSizeDefault.x, tileSizeDefault.y);
|
|
|
108
113
|
/** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
|
|
109
114
|
* @default
|
|
110
115
|
* @memberof Settings */
|
|
111
|
-
|
|
116
|
+
let glEnable = 1;
|
|
112
117
|
|
|
113
118
|
/** Fixes slow rendering in some browsers by not compositing the WebGL canvas
|
|
114
119
|
* @default
|
|
@@ -121,34 +126,39 @@ let glOverlay = 1;
|
|
|
121
126
|
/** Should gamepads be allowed
|
|
122
127
|
* @default
|
|
123
128
|
* @memberof Settings */
|
|
124
|
-
|
|
129
|
+
let gamepadsEnable = 1;
|
|
125
130
|
|
|
126
131
|
/** If true, the dpad input is also routed to the left analog stick (for better accessability)
|
|
127
132
|
* @default
|
|
128
133
|
* @memberof Settings */
|
|
129
|
-
|
|
134
|
+
let gamepadDirectionEmulateStick = 1;
|
|
130
135
|
|
|
131
136
|
/** If true the WASD keys are also routed to the direction keys (for better accessability)
|
|
132
137
|
* @default
|
|
133
138
|
* @memberof Settings */
|
|
134
|
-
|
|
139
|
+
let inputWASDEmulateDirection = 1;
|
|
135
140
|
|
|
136
|
-
/**
|
|
141
|
+
/** True if touch gamepad should appear on mobile devices
|
|
142
|
+
* <br> - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
143
|
+
* <br> - Must be set by end of gameInit to be activated
|
|
137
144
|
* @default
|
|
138
145
|
* @memberof Settings */
|
|
139
|
-
|
|
146
|
+
let touchGamepadEnable = 0;
|
|
140
147
|
|
|
141
|
-
/** Size of virutal gamepad for touch devices in pixels
|
|
142
|
-
* <br> - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
143
|
-
* <br> - Must be set by end of gameInit to be activated
|
|
148
|
+
/** Size of virutal gamepad for touch devices in pixels
|
|
144
149
|
* @default
|
|
145
150
|
* @memberof Settings */
|
|
146
|
-
let touchGamepadSize =
|
|
151
|
+
let touchGamepadSize = 80;
|
|
147
152
|
|
|
148
153
|
/** Transparency of touch gamepad overlay
|
|
149
154
|
* @default
|
|
150
155
|
* @memberof Settings */
|
|
151
|
-
let touchGamepadAlpha = .
|
|
156
|
+
let touchGamepadAlpha = .3;
|
|
157
|
+
|
|
158
|
+
/** Allow vibration hardware if it exists
|
|
159
|
+
* @default
|
|
160
|
+
* @memberof Settings */
|
|
161
|
+
let vibrateEnable = 1;
|
|
152
162
|
|
|
153
163
|
///////////////////////////////////////////////////////////////////////////////
|
|
154
164
|
// Audio settings
|
|
@@ -161,17 +171,17 @@ let soundVolume = .5;
|
|
|
161
171
|
/** All audio code can be disabled and removed from build
|
|
162
172
|
* @default
|
|
163
173
|
* @memberof Settings */
|
|
164
|
-
|
|
174
|
+
let soundEnable = 1;
|
|
165
175
|
|
|
166
176
|
/** Default range where sound no longer plays
|
|
167
177
|
* @default
|
|
168
178
|
* @memberof Settings */
|
|
169
|
-
|
|
179
|
+
let soundDefaultRange = 30;
|
|
170
180
|
|
|
171
181
|
/** Default range percent to start tapering off sound (0-1)
|
|
172
182
|
* @default
|
|
173
183
|
* @memberof Settings */
|
|
174
|
-
|
|
184
|
+
let soundDefaultTaper = .7;
|
|
175
185
|
|
|
176
186
|
///////////////////////////////////////////////////////////////////////////////
|
|
177
187
|
// Medals settings
|
|
@@ -179,24 +189,24 @@ const soundDefaultTaper = .7;
|
|
|
179
189
|
/** How long to show medals for in seconds
|
|
180
190
|
* @default
|
|
181
191
|
* @memberof Settings */
|
|
182
|
-
|
|
192
|
+
let medalDisplayTime = 5;
|
|
183
193
|
|
|
184
194
|
/** How quickly to slide on/off medals in seconds
|
|
185
195
|
* @default
|
|
186
196
|
* @memberof Settings */
|
|
187
|
-
|
|
197
|
+
let medalDisplaySlideTime = .5;
|
|
188
198
|
|
|
189
199
|
/** Width of medal display
|
|
190
200
|
* @default
|
|
191
201
|
* @memberof Settings */
|
|
192
|
-
|
|
202
|
+
let medalDisplayWidth = 640;
|
|
193
203
|
|
|
194
204
|
/** Height of medal display
|
|
195
205
|
* @default
|
|
196
206
|
* @memberof Settings */
|
|
197
|
-
|
|
207
|
+
let medalDisplayHeight = 80;
|
|
198
208
|
|
|
199
209
|
/** Size of icon in medal display
|
|
200
210
|
* @default
|
|
201
211
|
* @memberof Settings */
|
|
202
|
-
|
|
212
|
+
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,35 +218,36 @@ 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
|
|
242
|
-
this.savedRenderSettings = [mainCanvas, mainContext];
|
|
243
|
+
this.savedRenderSettings = [mainCanvas, mainContext, cameraPos, cameraScale];
|
|
243
244
|
|
|
244
|
-
//
|
|
245
|
+
// use normal rendering system to render the tiles
|
|
245
246
|
mainCanvas = this.canvas;
|
|
246
247
|
mainContext = this.context;
|
|
247
|
-
|
|
248
|
-
|
|
248
|
+
cameraPos = this.size.scale(.5);
|
|
249
|
+
cameraScale = this.tileSize.x;
|
|
250
|
+
enginePreRender();
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
/** Call to end the redraw process */
|
|
@@ -256,7 +258,7 @@ class TileLayer extends EngineObject
|
|
|
256
258
|
//debugSaveCanvas(this.canvas);
|
|
257
259
|
|
|
258
260
|
// set stuff back to normal
|
|
259
|
-
[mainCanvas, mainContext] = this.savedRenderSettings;
|
|
261
|
+
[mainCanvas, mainContext, cameraPos, cameraScale] = this.savedRenderSettings;
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
/** Draw the tile at a given position
|
|
@@ -284,7 +286,7 @@ class TileLayer extends EngineObject
|
|
|
284
286
|
this.drawTileData(vec2(x,y));
|
|
285
287
|
}
|
|
286
288
|
|
|
287
|
-
/** Draw directly to the
|
|
289
|
+
/** Draw directly to the 2D canvas in world space (bipass webgl)
|
|
288
290
|
* @param {Vector2} pos
|
|
289
291
|
* @param {Vector2} size
|
|
290
292
|
* @param {Number} [angle=0]
|
|
@@ -324,7 +326,7 @@ class TileLayer extends EngineObject
|
|
|
324
326
|
else
|
|
325
327
|
{
|
|
326
328
|
const cols = tileImage.width/tileSize.x;
|
|
327
|
-
context.globalAlpha = color.a; //
|
|
329
|
+
context.globalAlpha = color.a; // only alpha, no color, is supported in this mode
|
|
328
330
|
context.drawImage(tileImage,
|
|
329
331
|
(tileIndex%cols)*tileSize.x, (tileIndex/cols|0)*tileSize.x,
|
|
330
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,32 +38,27 @@ 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
50
|
'precision highp float;'+ // use highp for better accuracy, lowp for better perf
|
|
55
51
|
'uniform mat4 m;'+ // transform matrix
|
|
56
|
-
'attribute
|
|
57
|
-
'attribute
|
|
58
|
-
'attribute vec4 c,b;'+ // color, additiveColor
|
|
52
|
+
'attribute vec2 p,t;'+ // position, uv
|
|
53
|
+
'attribute vec4 c,a;'+ // color, additiveColor
|
|
59
54
|
'varying vec2 v;'+ // return uv
|
|
60
55
|
'varying vec4 d,e;'+ // return color, additiveColor
|
|
61
56
|
'void main(){'+ // shader entry point
|
|
62
|
-
'gl_Position=m*vec4(
|
|
63
|
-
'v=t;d=c;e=
|
|
57
|
+
'gl_Position=m*vec4(p,1,1);'+// transform position
|
|
58
|
+
'v=t;d=c;e=a;'+ // pass stuff to fragment shader
|
|
64
59
|
'}' // end of shader
|
|
65
60
|
,
|
|
66
|
-
'precision
|
|
61
|
+
'precision highp float;'+ // use highp for better accuracy, lowp for better perf
|
|
67
62
|
'varying vec2 v;'+ // uv
|
|
68
63
|
'varying vec4 d,e;'+ // color, additiveColor
|
|
69
64
|
'uniform sampler2D j;'+ // texture
|
|
@@ -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
|