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.
@@ -12,7 +12,7 @@
12
12
  * @type {Vector2}
13
13
  * @default
14
14
  * @memberof Settings */
15
- const canvasMaxSize = vec2(1920, 1200);
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
- const tileSizeDefault = vec2(16);
40
+ let tileSizeDefault = vec2(16);
41
41
 
42
42
  /** Prevent tile bleeding from neighbors in pixels
43
43
  * @default
44
44
  * @memberof Settings */
45
- const tileBleedShrinkFix = .3;
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
- const objectDefaultSize = vec2(1);
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
- const objectDefaultMass = 1;
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
- const objectDefaultDamping = .99;
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
- const objectDefaultAngleDamping = .99;
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
- const objectDefaultElasticity = 0;
74
+ let objectDefaultElasticity = 0;
75
75
 
76
76
  /** How much to slow when touching (0-1)
77
77
  * @default
78
78
  * @memberof Settings */
79
- const objectDefaultFriction = .8;
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
- const objectMaxSpeed = 1;
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
- const glEnable = 1;
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
- const gamepadsEnable = 1;
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
- const gamepadDirectionEmulateStick = 1;
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
- const inputWASDEmulateDirection = 1;
139
+ let inputWASDEmulateDirection = 1;
135
140
 
136
- /** If true touch input is routed to mouse functions
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
- const touchMouseEnable = 1;
146
+ let touchGamepadEnable = 0;
140
147
 
141
- /** Size of virutal gamepad for touch devices in pixels, 80 recommended
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 = 0;
151
+ let touchGamepadSize = 80;
147
152
 
148
153
  /** Transparency of touch gamepad overlay
149
154
  * @default
150
155
  * @memberof Settings */
151
- let touchGamepadAlpha = .5;
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
- const soundEnable = 1;
174
+ let soundEnable = 1;
165
175
 
166
176
  /** Default range where sound no longer plays
167
177
  * @default
168
178
  * @memberof Settings */
169
- const soundDefaultRange = 30;
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
- const soundDefaultTaper = .7;
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
- const medalDisplayTime = 5;
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
- const medalDisplaySlideTime = .5;
197
+ let medalDisplaySlideTime = .5;
188
198
 
189
199
  /** Width of medal display
190
200
  * @default
191
201
  * @memberof Settings */
192
- const medalDisplayWidth = 640;
202
+ let medalDisplayWidth = 640;
193
203
 
194
204
  /** Height of medal display
195
205
  * @default
196
206
  * @memberof Settings */
197
- const medalDisplayHeight = 99;
207
+ let medalDisplayHeight = 80;
198
208
 
199
209
  /** Size of icon in medal display
200
210
  * @default
201
211
  * @memberof Settings */
202
- const medalDisplayIconSize = 80;
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> - Tile layers are not rendered using WebGL to allow modifications at run time
146
- * <br> - Tile layers are sorted
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(0,0)] - World space position
157
- * @param {Vector2} [size=objectDefaultSize] - World space size
158
- * @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
159
- * @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
160
- * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
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 main canvas
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 using webgl if possible */
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=1] - Should it clear the canvas before drawing */
230
- redrawStart(clear = 1)
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
- this.canvas.width = width;
238
- this.canvas.height = height;
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
- // set camera transform for renering
245
+ // use normal rendering system to render the tiles
245
246
  mainCanvas = this.canvas;
246
247
  mainContext = this.context;
247
- mainContext.imageSmoothingEnabled = !cavasPixelated; // disable smoothing for pixel art
248
- glPreRender(width, height, this.size.x/2, this.size.y/2, this.tileSize.x);
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 2d canvas in world space (bipass webgl)
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; // full color not supported in this mode
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, max=1, min=0)=> (ASSERT(max > min), v < min ? min : v > max ? max : 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, max=1, min=0)=> max-min ? clamp((v-min) / (max-min)) : 0;
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, max=1, min=0)=> min + clamp(p) * (max-min);
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 - 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
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, 0, this.setTime) : 0; }
480
+ getPercent() { return this.isSet()? percent(this.time - time, this.setTime, 0) : 0; }
479
481
  }
@@ -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
- if (glOverlay)
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 float a;'+ // angle
57
- 'attribute vec2 p,s,t;'+ // position, size, uv
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((s*cos(a)-vec2(-s.y,s)*sin(a))*.5+p,1,1);'+// transform position
63
- 'v=t;d=c;e=b;'+ // pass stuff to fragment shader
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 lowp float;'+ // use highp for better accuracy, lowp for better perf
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('b', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
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) return;
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++] = angle;
289
- glPositionData[offset++] = x; glPositionData[offset++] = y;
290
- glPositionData[offset++] = -sizeX; glPositionData[offset++] = -sizeY;
291
- glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
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++] = angle;
296
- glPositionData[offset++] = x; glPositionData[offset++] = y;
297
- glPositionData[offset++] = sizeX; glPositionData[offset++] = sizeY;
298
- glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
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++] = angle;
303
- glPositionData[offset++] = x; glPositionData[offset++] = y;
304
- glPositionData[offset++] = -sizeX; glPositionData[offset++] = sizeY;
305
- glPositionData[offset++] = uv0X; glPositionData[offset++] = uv0Y;
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++] = angle;
310
- glPositionData[offset++] = x; glPositionData[offset++] = y;
311
- glPositionData[offset++] = -sizeX; glPositionData[offset++] = -sizeY;
312
- glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
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++] = angle;
317
- glPositionData[offset++] = x; glPositionData[offset++] = y;
318
- glPositionData[offset++] = sizeX; glPositionData[offset++] = -sizeY;
319
- glPositionData[offset++] = uv1X; glPositionData[offset++] = uv1Y;
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++] = angle;
324
- glPositionData[offset++] = x; glPositionData[offset++] = y;
325
- glPositionData[offset++] = sizeX; glPositionData[offset++] = sizeY;
326
- glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
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 = 9,
350
+ gl_INDICIES_PER_VERT = 6,
360
351
  gl_MAX_BATCH = 1<<16,
361
- gl_VERTEX_BYTE_STRIDE = 4 + (4 * 2) * 3 + (4) * 2; // float + vec2 * 3 + (char * 4) * 2
352
+ gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2; // vec2 * 2 + (char * 4) * 2