littlejsengine 1.11.13 → 1.12.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.
Files changed (79) hide show
  1. package/dist/littlejs.d.ts +1418 -109
  2. package/dist/littlejs.esm.js +3495 -581
  3. package/dist/littlejs.esm.min.js +1 -1
  4. package/dist/littlejs.js +3258 -399
  5. package/dist/littlejs.min.js +1 -1
  6. package/dist/littlejs.release.js +3147 -379
  7. package/examples/box2d/game.js +73 -45
  8. package/examples/box2d/gameObjects.js +96 -92
  9. package/examples/box2d/index.html +2 -7
  10. package/examples/box2d/scenes.js +82 -92
  11. package/examples/breakout/game.js +62 -30
  12. package/examples/breakout/gameObjects.js +45 -47
  13. package/examples/breakout/index.html +1 -5
  14. package/examples/breakoutTutorial/game.js +36 -29
  15. package/examples/breakoutTutorial/index.html +1 -3
  16. package/examples/empty/game.js +5 -2
  17. package/examples/empty/index.html +1 -3
  18. package/examples/htmlMenu/game.js +25 -19
  19. package/examples/htmlMenu/index.html +5 -7
  20. package/examples/index.html +2 -3
  21. package/examples/module/game.js +32 -34
  22. package/examples/module/index.html +1 -1
  23. package/examples/particles/index.html +27 -22
  24. package/examples/platformer/game.js +71 -48
  25. package/examples/platformer/gameCharacter.js +42 -34
  26. package/examples/platformer/gameEffects.js +82 -75
  27. package/examples/platformer/gameLevel.js +67 -38
  28. package/examples/platformer/{gameLevelData.js → gameLevelData.json} +1 -11
  29. package/examples/platformer/gameObjects.js +70 -64
  30. package/examples/platformer/gamePlayer.js +12 -7
  31. package/examples/platformer/index.html +1 -9
  32. package/examples/puzzle/game.js +58 -42
  33. package/examples/puzzle/index.html +1 -3
  34. package/examples/shorts/base.html +2 -2
  35. package/examples/shorts/particles.js +1 -1
  36. package/examples/shorts/platformer.js +1 -1
  37. package/examples/shorts/tileLayer.js +5 -6
  38. package/examples/shorts/tiles.png +0 -0
  39. package/examples/starter/build.js +4 -4
  40. package/examples/starter/game.js +9 -12
  41. package/examples/starter/index.html +13 -13
  42. package/examples/stress/index.html +44 -43
  43. package/examples/typescript/build.js +17 -18
  44. package/examples/typescript/game.js +32 -34
  45. package/examples/typescript/game.ts +32 -34
  46. package/examples/typescript/index.html +1 -1
  47. package/examples/uiSystem/game.js +33 -36
  48. package/examples/uiSystem/index.html +1 -5
  49. package/package.json +3 -3
  50. package/plugins/box2d.js +1556 -640
  51. package/plugins/{Box2D_v2.3.1_min.wasm.js → box2d.wasm.js} +1 -1
  52. package/plugins/newgrounds.js +7 -8
  53. package/plugins/pluginExport.js +50 -0
  54. package/plugins/postProcess.js +94 -93
  55. package/plugins/uiSystem.js +145 -161
  56. package/plugins/zzfxm.js +163 -0
  57. package/reference.md +29 -27
  58. package/src/engine.js +15 -20
  59. package/src/engineAudio.js +74 -204
  60. package/src/engineBuild.js +29 -4
  61. package/src/engineDebug.js +105 -9
  62. package/src/engineDraw.js +27 -14
  63. package/src/engineExport.js +12 -8
  64. package/src/engineInput.js +3 -1
  65. package/src/engineObject.js +18 -14
  66. package/src/engineParticles.js +6 -1
  67. package/src/engineRelease.js +6 -1
  68. package/src/engineSettings.js +8 -8
  69. package/src/engineTileLayer.js +179 -96
  70. package/src/engineUtilities.js +5 -11
  71. package/src/engineWebGL.js +19 -7
  72. package/examples/starter/build/index.html +0 -2
  73. package/examples/starter/build/index.js +0 -1
  74. package/examples/starter/build/tiles.png +0 -0
  75. package/examples/starter/game.zip +0 -0
  76. package/examples/typescript/build/dist/littlejs.esm.js +0 -4834
  77. package/examples/typescript/build/examples/typescript/build.js +0 -24
  78. package/examples/typescript/build/examples/typescript/game.js +0 -102
  79. /package/plugins/{Box2D_v2.3.1_min.wasm.wasm → box2d.wasm.wasm} +0 -0
@@ -10,42 +10,47 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ // import LittleJS module
14
+ import * as LJS from '../../dist/littlejs.esm.js';
15
+ import * as GameLevel from './gameLevel.js';
16
+ const {vec2, hsl, rgb} = LJS;
17
+
13
18
  ///////////////////////////////////////////////////////////////////////////////
14
19
  // sound effects
15
20
 
16
- const sound_shoot = new Sound([,,90,,.01,.03,4,,,,,,,9,50,.2,,.2,.01]);
17
- const sound_destroyObject =new Sound([.5,,1e3,.02,,.2,1,3,.1,,,,,1,-30,.5,,.5]);
18
- const sound_die = new Sound([.5,.4,126,.05,,.2,1,2.09,,-4,,,1,1,1,.4,.03]);
19
- const sound_jump = new Sound([.4,.2,250,.04,,.04,,,1,,,,,3]);
20
- const sound_dodge = new Sound([.4,.2,150,.05,,.05,,,-1,,,,,4,,,,,.02]);
21
- const sound_walk = new Sound([.3,.1,50,.005,,.01,4,,,,,,,,10,,,.5]);
22
- const sound_explosion = new Sound([2,.2,72,.01,.01,.2,4,,,,,,,1,,.5,.1,.5,.02]);
23
- const sound_grenade = new Sound([.5,.01,300,,,.02,3,.22,,,-9,.2,,,,,,.5]);
24
- const sound_score = new Sound([,,783,,.03,.02,1,2,,,940,.03,,,,,.2,.6,,.06]);
21
+ export const sound_shoot = new LJS.Sound([,,90,,.01,.03,4,,,,,,,9,50,.2,,.2,.01]);
22
+ export const sound_destroyObject =new LJS.Sound([.5,,1e3,.02,,.2,1,3,.1,,,,,1,-30,.5,,.5]);
23
+ export const sound_die = new LJS.Sound([.5,.4,126,.05,,.2,1,2.09,,-4,,,1,1,1,.4,.03]);
24
+ export const sound_jump = new LJS.Sound([.4,.2,250,.04,,.04,,,1,,,,,3]);
25
+ export const sound_dodge = new LJS.Sound([.4,.2,150,.05,,.05,,,-1,,,,,4,,,,,.02]);
26
+ export const sound_walk = new LJS.Sound([.3,.1,50,.005,,.01,4,,,,,,,,10,,,.5]);
27
+ export const sound_explosion = new LJS.Sound([2,.2,72,.01,.01,.2,4,,,,,,,1,,.5,.1,.5,.02]);
28
+ export const sound_grenade = new LJS.Sound([.5,.01,300,,,.02,3,.22,,,-9,.2,,,,,,.5]);
29
+ export const sound_score = new LJS.Sound([,,783,,.03,.02,1,2,,,940,.03,,,,,.2,.6,,.06]);
25
30
 
26
31
  ///////////////////////////////////////////////////////////////////////////////
27
32
  // special effects
28
33
 
29
- const persistentParticleDestroyCallback = (particle)=>
34
+ export const persistentParticleDestroyCallback = (particle)=>
30
35
  {
31
36
  // copy particle to tile layer on death
32
- ASSERT(!particle.tileInfo, 'quick draw to tile layer uses canvas 2d so must be untextured');
37
+ LJS.ASSERT(!particle.tileInfo, 'quick draw to tile layer uses canvas 2d so must be untextured');
33
38
  if (particle.groundObject)
34
- tileLayers[foregroundLayerIndex].drawTile(particle.pos, particle.size, particle.tileInfo, particle.color, particle.angle, particle.mirror);
39
+ GameLevel.foregroundTileLayer.drawTile(particle.pos, particle.size, particle.tileInfo, particle.color, particle.angle, particle.mirror);
35
40
  }
36
41
 
37
- function makeBlood(pos, amount) { makeDebris(pos, hsl(0,1,.5), amount, .1, 0); }
38
- function makeDebris(pos, color = hsl(), amount = 50, size=.2, elasticity = .3)
42
+ export function makeBlood(pos, amount) { makeDebris(pos, hsl(0,1,.5), amount, .1, 0); }
43
+ export function makeDebris(pos, color = hsl(), amount = 50, size=.2, elasticity = .3)
39
44
  {
40
45
  const color2 = color.lerp(hsl(), .5);
41
- const emitter = new ParticleEmitter(
42
- pos, 0, 1, .1, amount/.1, PI, // pos, angle, emitSize, emitTime, emitRate, emitCone
43
- 0, // tileInfo
44
- color, color2, // colorStartA, colorStartB
45
- color, color2, // colorEndA, colorEndB
46
- 3, size,size, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
47
- 1, .95, .4, PI, 0, // damp, angleDamp, gravity, particleCone, fade
48
- .5, 1 // randomness, collide, additive, colorLinear, renderOrder
46
+ const emitter = new LJS.ParticleEmitter(
47
+ pos, 0, 1, .1, amount/.1, 3.14, // pos, angle, emitSize, emitTime, emitRate, emitCone
48
+ 0, // tileInfo
49
+ color, color2, // colorStartA, colorStartB
50
+ color, color2, // colorEndA, colorEndB
51
+ 3, size,size, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
52
+ 1, .95, .4, 3.14, 0, // damp, angleDamp, gravity, particleCone, fade
53
+ .5, 1 // randomness, collide, additive, colorLinear, renderOrder
49
54
  );
50
55
  emitter.elasticity = elasticity;
51
56
  emitter.particleDestroyCallback = persistentParticleDestroyCallback;
@@ -54,9 +59,9 @@ function makeDebris(pos, color = hsl(), amount = 50, size=.2, elasticity = .3)
54
59
 
55
60
  ///////////////////////////////////////////////////////////////////////////////
56
61
 
57
- function explosion(pos, radius=3)
62
+ export function explosion(pos, radius=3)
58
63
  {
59
- ASSERT(radius > 0);
64
+ LJS.ASSERT(radius > 0);
60
65
 
61
66
  sound_explosion.play(pos);
62
67
 
@@ -74,11 +79,11 @@ function explosion(pos, radius=3)
74
79
  {
75
80
  const h = (cleanupRadius**2 - x**2)**.5;
76
81
  for (let y = -h; y < h; ++y)
77
- decorateTile(pos.add(vec2(x,y)).floor());
82
+ GameLevel.decorateTile(pos.add(vec2(x,y)).floor());
78
83
  }
79
84
 
80
85
  // kill/push objects
81
- engineObjectsCallback(pos, radius*3, (o)=>
86
+ LJS.engineObjectsCallback(pos, radius*3, (o)=>
82
87
  {
83
88
  const damage = radius*2;
84
89
  const d = o.pos.distance(pos);
@@ -89,52 +94,52 @@ function explosion(pos, radius=3)
89
94
  }
90
95
 
91
96
  // push
92
- const p = percent(d, 2*radius, radius);
97
+ const p = LJS.percent(d, 2*radius, radius);
93
98
  const force = o.pos.subtract(pos).normalize(p*radius*.2);
94
99
  o.applyForce(force);
95
100
  });
96
101
 
97
102
  // smoke
98
- new ParticleEmitter(
99
- pos, 0, // pos, angle
100
- radius/2, .2, 50*radius, PI,// emitSize, emitTime, emitRate, emitCone
101
- 0, // tileInfo
102
- hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
103
- hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
104
- 1, .5, 2, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
105
- .9, 1, -.3, PI, .1, // damp, angleDamp, gravity, particleCone, fade
106
- .5, 0, 0, 0, 1e8 // randomness, collide, additive, colorLinear, renderOrder
103
+ new LJS.ParticleEmitter(
104
+ pos, 0, // pos, angle
105
+ radius/2, .2, 50*radius, 3.14,// emitSize, emitTime, emitRate, emitCone
106
+ 0, // tileInfo
107
+ hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
108
+ hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
109
+ 1, .5, 2, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
110
+ .9, 1, -.3, 3.14, .1, // damp, angleDamp, gravity, particleCone, fade
111
+ .5, 0, 0, 0, 1e8 // randomness, collide, additive, colorLinear, renderOrder
107
112
  );
108
113
 
109
114
  // fire
110
- new ParticleEmitter(
115
+ new LJS.ParticleEmitter(
111
116
  pos, 0, // pos, angle
112
- radius/2, .1, 100*radius, PI, // emitSize, emitTime, emitRate, emitCone
117
+ radius/2, .1, 100*radius, 3.14, // emitSize, emitTime, emitRate, emitCone
113
118
  0, // tileInfo
114
119
  rgb(1,.5,.1), rgb(1,.1,.1), // colorStartA, colorStartB
115
120
  rgb(1,.5,.1,0), rgb(1,.1,.1,0), // colorEndA, colorEndB
116
- .7, .8, .2, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
117
- .9, 1, -.2, PI, .05, // damp, angleDamp, gravity, particleCone, fade
118
- .5, 0, 1, 0, 1e9 // randomness, collide, additive, colorLinear, renderOrder
121
+ .7, .8, .2, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
122
+ .9, 1, -.2, 3.14, .05, // damp, angleDamp, gravity, particleCone, fade
123
+ .5, 0, 1, 0, 1e9 // randomness, collide, additive, colorLinear, renderOrder
119
124
  );
120
125
  }
121
126
 
122
127
  ///////////////////////////////////////////////////////////////////////////////
123
128
 
124
- function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
129
+ export function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
125
130
  {
126
131
  // pos must be an int
127
132
  pos = pos.floor();
128
133
 
129
134
  // destroy tile
130
- const tileType = getTileCollisionData(pos);
135
+ const layer = GameLevel.foregroundTileLayer;
136
+ const tileType = layer.getCollisionData(pos);
131
137
  if (!tileType)
132
138
  return true;
133
139
 
134
- const tileLayer = tileLayers[foregroundLayerIndex];
135
140
  const centerPos = pos.add(vec2(.5));
136
- const layerData = tileLayer.getData(pos);
137
- if (!layerData || tileType == tileType_solid)
141
+ const layerData = layer.getData(pos);
142
+ if (!layerData || tileType == GameLevel.tileType_solid)
138
143
  return false;
139
144
 
140
145
  // create effects
@@ -142,15 +147,15 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
142
147
  makeSound && sound_destroyObject.play(centerPos);
143
148
 
144
149
  // set and clear tile
145
- tileLayer.setData(pos, new TileLayerData, 1);
146
- setTileCollisionData(pos, tileType_empty);
150
+ layer.setData(pos, new LJS.TileLayerData, 1);
151
+ layer.setCollisionData(pos, GameLevel.tileType_empty);
147
152
 
148
153
  // cleanup neighbors
149
154
  if (cleanNeighbors)
150
155
  {
151
156
  for (let i=-1;i<=1;++i)
152
157
  for (let j=-1;j<=1;++j)
153
- decorateTile(pos.add(vec2(i,j)));
158
+ GameLevel.decorateTile(pos.add(vec2(i,j)));
154
159
  }
155
160
 
156
161
  return true;
@@ -159,52 +164,54 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
159
164
  ///////////////////////////////////////////////////////////////////////////////
160
165
  // sky with background gradient, stars, and planets
161
166
 
162
- class Sky extends EngineObject
167
+ export class Sky extends LJS.EngineObject
163
168
  {
164
169
  constructor()
165
170
  {
166
171
  super();
167
172
 
168
173
  this.renderOrder = -1e4;
169
- this.seed = randInt(1e9);
170
- this.skyColor = randColor(hsl(0,0,.5), hsl(0,0,.9));
174
+ this.seed = LJS.randInt(1e9);
175
+ this.skyColor = LJS.randColor(hsl(0,0,.5), hsl(0,0,.9));
171
176
  this.horizonColor = this.skyColor.subtract(hsl(0,0,.05,0)).mutate(.3);
172
177
  }
173
178
 
174
179
  render()
175
180
  {
176
181
  // fill background with a gradient
177
- const gradient = mainContext.createLinearGradient(0, 0, 0, mainCanvas.height);
182
+ const canvas = LJS.mainCanvas;
183
+ const context = LJS.mainContext;
184
+ const gradient = context.createLinearGradient(0, 0, 0, canvas.height);
178
185
  gradient.addColorStop(0, this.skyColor);
179
186
  gradient.addColorStop(1, this.horizonColor);
180
- mainContext.save();
181
- mainContext.fillStyle = gradient;
182
- mainContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height);
183
- mainContext.globalCompositeOperation = 'lighter';
187
+ context.save();
188
+ context.fillStyle = gradient;
189
+ context.fillRect(0, 0, canvas.width, canvas.height);
190
+ context.globalCompositeOperation = 'lighter';
184
191
 
185
192
  // draw stars
186
- const random = new RandomGenerator(this.seed);
193
+ const random = new LJS.RandomGenerator(this.seed);
187
194
  for (let i=1e3; i--;)
188
195
  {
189
196
  const size = random.float(.5,2)**2;
190
197
  const speed = random.float() < .9 ? random.float(5) : random.float(9,99);
191
198
  const color = hsl(random.float(-.3,.2), random.float(), random.float());
192
199
  const extraSpace = 50;
193
- const w = mainCanvas.width+2*extraSpace, h = mainCanvas.height+2*extraSpace;
200
+ const w = canvas.width+2*extraSpace, h = canvas.height+2*extraSpace;
194
201
  const screenPos = vec2(
195
- (random.float(w)+time*speed)%w-extraSpace,
196
- (random.float(h)+time*speed*random.float())%h-extraSpace);
197
- mainContext.fillStyle = color;
198
- mainContext.fillRect(screenPos.x, screenPos.y, size, size);
202
+ (random.float(w)+LJS.time*speed)%w-extraSpace,
203
+ (random.float(h)+LJS.time*speed*random.float())%h-extraSpace);
204
+ context.fillStyle = color;
205
+ context.fillRect(screenPos.x, screenPos.y, size, size);
199
206
  }
200
- mainContext.restore();
207
+ context.restore();
201
208
  }
202
209
  }
203
210
 
204
211
  ///////////////////////////////////////////////////////////////////////////////
205
212
  // parallax background mountain ranges
206
213
 
207
- class ParallaxLayer extends EngineObject
214
+ export class ParallaxLayer extends LJS.EngineObject
208
215
  {
209
216
  constructor(index)
210
217
  {
@@ -223,15 +230,15 @@ class ParallaxLayer extends EngineObject
223
230
  const o1 = 40-20*index;
224
231
  const o2 = 100-30*index;
225
232
  const gradient = this.context.createLinearGradient(0,size.y/2-o1,0,size.y/2+o2);
226
- const layerColor = levelColor.mutate(.1).lerp(sky.skyColor,1-index*.15);
233
+ const layerColor = GameLevel.levelColor.mutate(.1).lerp(GameLevel.sky.skyColor,1-index*.15);
227
234
  gradient.addColorStop(0,layerColor);
228
235
  gradient.addColorStop(1,layerColor.mutate(.5).scale(.1,1));
229
236
  this.context.fillStyle = gradient;
230
237
 
231
238
  // draw procedural mountains ranges
232
- let groundLevel = size.y/2, groundSlope = rand(-1,1);
239
+ let groundLevel = size.y/2, groundSlope = LJS.rand(-1,1);
233
240
  for (let i=size.x; i--;)
234
- this.context.fillRect(i, groundLevel += groundSlope = rand() < .3 ? rand(1,-1) :
241
+ this.context.fillRect(i, groundLevel += groundSlope = LJS.rand() < .3 ? LJS.rand(1,-1) :
235
242
  groundSlope + (size.y/2 - groundLevel)/300, 1, size.y);
236
243
  }
237
244
 
@@ -239,16 +246,16 @@ class ParallaxLayer extends EngineObject
239
246
  {
240
247
  // position layer based on camera distance from center of level
241
248
  const parallax = vec2(1e3,-100).scale(this.index**2);
242
- const cameraDeltaFromCenter = cameraPos
243
- .subtract(levelSize.scale(.5))
244
- .divide(levelSize.divide(parallax));
249
+ const cameraDeltaFromCenter = LJS.cameraPos
250
+ .subtract(GameLevel.levelSize.scale(.5))
251
+ .divide(GameLevel.levelSize.divide(parallax));
245
252
  const scale = this.size.scale(2+2*this.index);
246
- const pos = mainCanvasSize.scale(.5) // center screen
247
- .add(vec2(-scale.x/2,-scale.y/2)) // center layer
248
- .add(cameraDeltaFromCenter.scale(-.5)) // apply parallax
253
+ const pos = LJS.mainCanvasSize.scale(.5) // center screen
254
+ .add(vec2(-scale.x/2,-scale.y/2)) // center layer
255
+ .add(cameraDeltaFromCenter.scale(-.5)) // apply parallax
249
256
  .add(vec2(0,(this.index*.1)*this.size.y)); // separate layers
250
257
 
251
258
  // draw the parallax layer onto the main canvas
252
- mainContext.drawImage(this.canvas, pos.x, pos.y, scale.x, scale.y);
259
+ LJS.mainContext.drawImage(this.canvas, pos.x, pos.y, scale.x, scale.y);
253
260
  }
254
261
  }
@@ -7,43 +7,56 @@
7
7
 
8
8
  'use strict';
9
9
 
10
- const tileType_ladder = -1;
11
- const tileType_empty = 0;
12
- const tileType_solid = 1;
13
- const tileType_breakable = 2;
14
-
15
- let player, playerStartPos, tileLayers, foregroundLayerIndex, sky;
16
- let levelSize, levelColor, levelBackgroundColor, levelOutlineColor;
17
-
18
- function buildLevel()
10
+ // import LittleJS module
11
+ import * as LJS from '../../dist/littlejs.esm.js';
12
+ import * as GameObjects from './gameObjects.js';
13
+ import * as GameEffects from './gameEffects.js';
14
+ import * as Game from './game.js';
15
+ const {vec2, hsl, tile} = LJS;
16
+
17
+ export const tileType_ladder = -1;
18
+ export const tileType_empty = 0;
19
+ export const tileType_solid = 1;
20
+ export const tileType_breakable = 2;
21
+
22
+ export let playerStartPos, tileLayers, foregroundTileLayer, sky;
23
+ export let levelSize, levelColor, levelBackgroundColor, levelOutlineColor;
24
+
25
+ export function buildLevel()
19
26
  {
20
27
  // destroy all objects
21
- engineObjectsDestroy();
28
+ LJS.engineObjectsDestroy();
22
29
 
23
30
  // create the level
24
- levelColor = randColor(hsl(0,0,.2), hsl(0,0,.8));
31
+ levelColor = LJS.randColor(hsl(0,0,.2), hsl(0,0,.8));
25
32
  levelBackgroundColor = levelColor.mutate().scale(.4,1);
26
33
  levelOutlineColor = levelColor.mutate().add(hsl(0,0,.4)).clamp();
27
- loadLevel();
34
+ buildLevelData();
28
35
 
29
36
  // create sky object with gradient and stars
30
- sky = new Sky;
37
+ sky = new GameEffects.Sky;
31
38
 
32
39
  // create parallax layers
33
40
  for (let i=3; i--;)
34
- new ParallaxLayer(i);
35
-
36
- // spawn player
37
- player = new Player(playerStartPos);
38
- cameraPos = getCameraTarget();
41
+ new GameEffects.ParallaxLayer(i);
39
42
  }
40
43
 
41
- function loadLevel(level=0)
44
+ function buildLevelData()
42
45
  {
43
46
  // load level data from an exported Tiled js file
44
- const tileMapData = TileMaps['gameLevelData'];
47
+ let tileMapData = Game.gameLevelData;
48
+ if (!tileMapData)
49
+ {
50
+ // default level data if loading failed
51
+ tileMapData = {};
52
+ tileMapData.width = 100;
53
+ tileMapData.height = 20;
54
+ tileMapData.layers = [{data:[]}];
55
+ for(let i=100*20;i--;)
56
+ tileMapData.layers[0].data[i] = i>100 ? 2 : 0;
57
+ }
58
+
45
59
  levelSize = vec2(tileMapData.width, tileMapData.height);
46
- initTileCollision(levelSize);
47
60
 
48
61
  // create table for tiles in the level tilemap
49
62
  const tileLookup =
@@ -62,11 +75,18 @@ function loadLevel(level=0)
62
75
  tileLayers = [];
63
76
  playerStartPos = vec2(1, levelSize.y);
64
77
  const layerCount = tileMapData.layers.length;
65
- foregroundLayerIndex = layerCount-1;
66
78
  for (let layer=layerCount; layer--;)
67
79
  {
68
80
  const layerData = tileMapData.layers[layer].data;
69
- const tileLayer = new TileLayer(vec2(), levelSize, tile(0,16,1));
81
+ let tileLayer;
82
+ if (layer < layerCount-1)
83
+ tileLayer = new LJS.TileLayer(vec2(), levelSize, tile(0,16,1));
84
+ else
85
+ {
86
+ // only foreground layer has collision
87
+ tileLayer = new LJS.TileCollisionLayer(vec2(), levelSize, tile(0,16,1));
88
+ foregroundTileLayer = tileLayer;
89
+ }
70
90
  tileLayer.renderOrder = -1e3+layer;
71
91
  tileLayers[layer] = tileLayer;
72
92
 
@@ -83,11 +103,11 @@ function loadLevel(level=0)
83
103
  if (tile == tileLookup.player)
84
104
  playerStartPos = objectPos;
85
105
  if (tile == tileLookup.crate)
86
- new Crate(objectPos);
106
+ new GameObjects.Crate(objectPos);
87
107
  if (tile == tileLookup.enemy)
88
- new Enemy(objectPos);
108
+ new GameObjects.Enemy(objectPos);
89
109
  if (tile == tileLookup.coin)
90
- new Coin(objectPos);
110
+ new GameObjects.Coin(objectPos);
91
111
  continue;
92
112
  }
93
113
 
@@ -102,21 +122,21 @@ function loadLevel(level=0)
102
122
  if (tileType)
103
123
  {
104
124
  // set collision for solid tiles
105
- if (layer == foregroundLayerIndex)
106
- setTileCollisionData(pos, tileType);
125
+ if (tileLayer == foregroundTileLayer)
126
+ tileLayer.setCollisionData(pos, tileType);
107
127
 
108
128
  // randomize tile appearance
109
129
  let direction, mirror, color;
110
130
  if (tileType == tileType_breakable)
111
131
  {
112
- direction = randInt(4);
113
- mirror = randInt(2);
132
+ direction = LJS.randInt(4);
133
+ mirror = LJS.randInt(2);
114
134
  color = layer ? levelColor : levelBackgroundColor;
115
135
  color = color.mutate(.03);
116
136
  }
117
137
 
118
138
  // set tile layer data
119
- const data = new TileLayerData(tile-1, direction, mirror, color);
139
+ const data = new LJS.TileLayerData(tile-1, direction, mirror, color);
120
140
  tileLayer.setData(pos, data);
121
141
  }
122
142
  }
@@ -131,25 +151,27 @@ function loadLevel(level=0)
131
151
  decorateTile(pos, layer);
132
152
  }
133
153
 
134
- function decorateTile(pos, layer=1)
154
+ export function decorateTile(pos, layer=1)
135
155
  {
136
- ASSERT((pos.x|0) == pos.x && (pos.y|0)== pos.y);
156
+ LJS.ASSERT((pos.x|0) == pos.x && (pos.y|0)== pos.y);
137
157
  const tileLayer = tileLayers[layer];
158
+ if (!tileLayer)
159
+ return;
138
160
 
139
- if (layer == foregroundLayerIndex)
161
+ if (tileLayer == foregroundTileLayer)
140
162
  {
141
- const tileType = getTileCollisionData(pos);
163
+ const tileType = tileLayer.getCollisionData(pos);
142
164
  if (tileType <= 0)
143
165
  {
144
166
  // force it to clear if it is empty
145
- tileType || tileLayer.setData(pos, new TileLayerData, 1);
167
+ tileType || tileLayer.setData(pos, new LJS.TileLayerData, 1);
146
168
  return;
147
169
  }
148
170
  if (tileType == tileType_breakable)
149
171
  for (let i=4;i--;)
150
172
  {
151
173
  // outline towards neighbors of differing type
152
- const neighborTileType = getTileCollisionData(pos.add(vec2().setDirection(i)));
174
+ const neighborTileType = tileLayer.getCollisionData(pos.add(vec2().setDirection(i)));
153
175
  if (neighborTileType == tileType)
154
176
  continue;
155
177
 
@@ -174,7 +196,7 @@ function decorateTile(pos, layer=1)
174
196
  if (neighborTileDataA > 0 || neighborTileDataB > 0)
175
197
  continue;
176
198
 
177
- const directionVector = vec2().setAngle(i*PI/2+PI/4, 10).floor();
199
+ const directionVector = vec2().setAngle((i+.5)*LJS.PI/2, 10).floor();
178
200
  const drawPos = pos.add(vec2(.5)) // center
179
201
  .scale(16).add(directionVector).floor(); // direction offset
180
202
 
@@ -185,3 +207,10 @@ function decorateTile(pos, layer=1)
185
207
  }
186
208
  }
187
209
  }
210
+
211
+ export function getCameraTarget()
212
+ {
213
+ // camera is above player
214
+ const offset = 100/LJS.cameraScale*LJS.percent(LJS.mainCanvasSize.y, 300, 600);
215
+ return Game.player.pos.add(vec2(0, offset));
216
+ }
@@ -1,13 +1,3 @@
1
- (function(name,data){
2
- if(typeof onTileMapLoaded === 'undefined') {
3
- if(typeof TileMaps === 'undefined') TileMaps = {};
4
- TileMaps[name] = data;
5
- } else {
6
- onTileMapLoaded(name,data);
7
- }
8
- if(typeof module === 'object' && module && module.exports) {
9
- module.exports = data;
10
- }})("gameLevelData",
11
1
  { "compressionlevel":-1,
12
2
  "height":64,
13
3
  "infinite":false,
@@ -178,4 +168,4 @@
178
168
  "type":"map",
179
169
  "version":"1.10",
180
170
  "width":256
181
- });
171
+ }