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.
- package/dist/littlejs.d.ts +1418 -109
- package/dist/littlejs.esm.js +3495 -581
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +3258 -399
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +3147 -379
- package/examples/box2d/game.js +73 -45
- package/examples/box2d/gameObjects.js +96 -92
- package/examples/box2d/index.html +2 -7
- package/examples/box2d/scenes.js +82 -92
- package/examples/breakout/game.js +62 -30
- package/examples/breakout/gameObjects.js +45 -47
- package/examples/breakout/index.html +1 -5
- package/examples/breakoutTutorial/game.js +36 -29
- package/examples/breakoutTutorial/index.html +1 -3
- package/examples/empty/game.js +5 -2
- package/examples/empty/index.html +1 -3
- package/examples/htmlMenu/game.js +25 -19
- package/examples/htmlMenu/index.html +5 -7
- package/examples/index.html +2 -3
- package/examples/module/game.js +32 -34
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +27 -22
- package/examples/platformer/game.js +71 -48
- package/examples/platformer/gameCharacter.js +42 -34
- package/examples/platformer/gameEffects.js +82 -75
- package/examples/platformer/gameLevel.js +67 -38
- package/examples/platformer/{gameLevelData.js → gameLevelData.json} +1 -11
- package/examples/platformer/gameObjects.js +70 -64
- package/examples/platformer/gamePlayer.js +12 -7
- package/examples/platformer/index.html +1 -9
- package/examples/puzzle/game.js +58 -42
- package/examples/puzzle/index.html +1 -3
- package/examples/shorts/base.html +2 -2
- package/examples/shorts/particles.js +1 -1
- package/examples/shorts/platformer.js +1 -1
- package/examples/shorts/tileLayer.js +5 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/starter/build.js +4 -4
- package/examples/starter/game.js +9 -12
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +44 -43
- package/examples/typescript/build.js +17 -18
- package/examples/typescript/game.js +32 -34
- package/examples/typescript/game.ts +32 -34
- package/examples/typescript/index.html +1 -1
- package/examples/uiSystem/game.js +33 -36
- package/examples/uiSystem/index.html +1 -5
- package/package.json +3 -3
- package/plugins/box2d.js +1556 -640
- package/plugins/{Box2D_v2.3.1_min.wasm.js → box2d.wasm.js} +1 -1
- package/plugins/newgrounds.js +7 -8
- package/plugins/pluginExport.js +50 -0
- package/plugins/postProcess.js +94 -93
- package/plugins/uiSystem.js +145 -161
- package/plugins/zzfxm.js +163 -0
- package/reference.md +29 -27
- package/src/engine.js +15 -20
- package/src/engineAudio.js +74 -204
- package/src/engineBuild.js +29 -4
- package/src/engineDebug.js +105 -9
- package/src/engineDraw.js +27 -14
- package/src/engineExport.js +12 -8
- package/src/engineInput.js +3 -1
- package/src/engineObject.js +18 -14
- package/src/engineParticles.js +6 -1
- package/src/engineRelease.js +6 -1
- package/src/engineSettings.js +8 -8
- package/src/engineTileLayer.js +179 -96
- package/src/engineUtilities.js +5 -11
- package/src/engineWebGL.js +19 -7
- package/examples/starter/build/index.html +0 -2
- package/examples/starter/build/index.js +0 -1
- package/examples/starter/build/tiles.png +0 -0
- package/examples/starter/game.zip +0 -0
- package/examples/typescript/build/dist/littlejs.esm.js +0 -4834
- package/examples/typescript/build/examples/typescript/build.js +0 -24
- package/examples/typescript/build/examples/typescript/game.js +0 -102
- /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
|
-
|
|
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,
|
|
43
|
-
0,
|
|
44
|
-
color, color2,
|
|
45
|
-
color, color2,
|
|
46
|
-
3, size,size, .1, .05,
|
|
47
|
-
1, .95, .4,
|
|
48
|
-
.5, 1
|
|
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,
|
|
100
|
-
radius/2, .2, 50*radius,
|
|
101
|
-
0,
|
|
102
|
-
hsl(0,0,0), hsl(0,0,0),
|
|
103
|
-
hsl(0,0,0,0), hsl(0,0,0,0),
|
|
104
|
-
1, .5, 2, .2, .05,
|
|
105
|
-
.9, 1, -.3,
|
|
106
|
-
.5, 0, 0, 0, 1e8
|
|
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,
|
|
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,
|
|
117
|
-
.9, 1, -.2,
|
|
118
|
-
.5, 0, 1, 0, 1e9
|
|
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
|
|
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 =
|
|
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
|
-
|
|
146
|
-
|
|
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
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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 =
|
|
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
|
-
|
|
198
|
-
|
|
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
|
-
|
|
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)
|
|
247
|
-
.add(vec2(-scale.x/2,-scale.y/2))
|
|
248
|
-
.add(cameraDeltaFromCenter.scale(-.5))
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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
|
|
44
|
+
function buildLevelData()
|
|
42
45
|
{
|
|
43
46
|
// load level data from an exported Tiled js file
|
|
44
|
-
|
|
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
|
-
|
|
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 (
|
|
106
|
-
|
|
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 (
|
|
161
|
+
if (tileLayer == foregroundTileLayer)
|
|
140
162
|
{
|
|
141
|
-
const tileType =
|
|
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 =
|
|
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
|
|
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
|
+
}
|