littlejsengine 1.9.2 → 1.9.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/README.md +4 -2
- package/dist/littlejs.d.ts +31 -26
- package/dist/littlejs.esm.js +145 -122
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +145 -122
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +140 -121
- package/examples/logo.png +0 -0
- package/examples/module/game.js +1 -1
- package/examples/platformer/data/{gameTileData.tmx → gameLevelData.tmx} +3 -3
- package/examples/platformer/game.js +31 -10
- package/examples/platformer/gameCharacter.js +7 -6
- package/examples/platformer/gameEffects.js +77 -68
- package/examples/platformer/gameLevel.js +33 -17
- package/examples/platformer/{gameTileData.js → gameLevelData.js} +3 -3
- package/examples/platformer/gameObjects.js +14 -14
- package/examples/platformer/index.html +1 -1
- package/examples/platformer/tiles.png +0 -0
- package/examples/screenshot.jpg +0 -0
- package/examples/stress/index.html +1 -1
- package/examples/typescript/game.js +1 -1
- package/examples/typescript/game.ts +1 -1
- package/package.json +1 -1
- package/reference.md +409 -0
- package/src/engine.js +47 -42
- package/src/engineAudio.js +19 -10
- package/src/engineDebug.js +5 -1
- package/src/engineDraw.js +19 -23
- package/src/engineInput.js +31 -17
- package/src/engineMedals.js +1 -1
- package/src/engineObject.js +2 -2
- package/src/engineParticles.js +11 -10
- package/src/engineSettings.js +3 -3
- package/src/engineTileLayer.js +2 -2
- package/src/engineUtilities.js +4 -4
- package/src/engineWebGL.js +1 -7
- /package/examples/platformer/data/{gameTileData.tsx → gameLevelData.tsx} +0 -0
|
@@ -11,21 +11,39 @@
|
|
|
11
11
|
// show the LittleJS splash screen
|
|
12
12
|
setShowSplashScreen(true);
|
|
13
13
|
|
|
14
|
-
let score, deaths;
|
|
14
|
+
let spriteAtlas, score, deaths;
|
|
15
15
|
|
|
16
16
|
///////////////////////////////////////////////////////////////////////////////
|
|
17
17
|
function gameInit()
|
|
18
18
|
{
|
|
19
|
+
// create a table of all sprites
|
|
20
|
+
spriteAtlas =
|
|
21
|
+
{
|
|
22
|
+
// large tiles
|
|
23
|
+
circle: tile(0),
|
|
24
|
+
crate: tile(2),
|
|
25
|
+
player: tile(3),
|
|
26
|
+
enemy: tile(5),
|
|
27
|
+
coin: tile(6),
|
|
28
|
+
|
|
29
|
+
// small tiles
|
|
30
|
+
gun: tile(2,8),
|
|
31
|
+
grenade: tile(3,8),
|
|
32
|
+
};
|
|
33
|
+
|
|
19
34
|
// enable touch gamepad on touch devices
|
|
20
35
|
touchGamepadEnable = true;
|
|
21
36
|
|
|
22
|
-
// setup
|
|
37
|
+
// setup level
|
|
38
|
+
buildLevel();
|
|
39
|
+
|
|
40
|
+
// init game
|
|
23
41
|
score = deaths = 0;
|
|
24
42
|
gravity = -.01;
|
|
25
43
|
objectDefaultDamping = .99;
|
|
26
44
|
objectDefaultAngleDamping = .99;
|
|
27
45
|
cameraScale = 4*16;
|
|
28
|
-
|
|
46
|
+
cameraPos = getCameraTarget();
|
|
29
47
|
}
|
|
30
48
|
|
|
31
49
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -60,20 +78,23 @@ function gameUpdate()
|
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
///////////////////////////////////////////////////////////////////////////////
|
|
63
|
-
function
|
|
81
|
+
function getCameraTarget()
|
|
64
82
|
{
|
|
65
|
-
//
|
|
66
|
-
|
|
83
|
+
// camera is above player
|
|
84
|
+
const offset = 3*percent(mainCanvasSize.y, 300, 600);
|
|
85
|
+
return player.pos.add(vec2(0, offset));
|
|
86
|
+
}
|
|
67
87
|
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
89
|
+
function gameUpdatePost()
|
|
90
|
+
{
|
|
91
|
+
// update camera
|
|
92
|
+
cameraPos = cameraPos.lerp(getCameraTarget(), clamp(player.getAliveTime()/2));
|
|
70
93
|
}
|
|
71
94
|
|
|
72
95
|
///////////////////////////////////////////////////////////////////////////////
|
|
73
96
|
function gameRender()
|
|
74
97
|
{
|
|
75
|
-
drawSky();
|
|
76
|
-
drawStars();
|
|
77
98
|
}
|
|
78
99
|
|
|
79
100
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -210,15 +210,16 @@ class Character extends GameObject
|
|
|
210
210
|
// update mirror
|
|
211
211
|
if (moveInput.x && !this.dodgeTimer.active())
|
|
212
212
|
this.mirror = moveInput.x < 0;
|
|
213
|
-
|
|
214
|
-
// set tile to use
|
|
215
|
-
const tile = this.isDead() ? 3 :
|
|
216
|
-
this.climbingLadder || this.groundTimer.active() ? 3 + 2*this.walkCyclePercent|0 : 4;
|
|
217
|
-
this.tileInfo.pos.x = tile * 16;
|
|
218
213
|
}
|
|
219
214
|
|
|
220
215
|
render()
|
|
221
216
|
{
|
|
217
|
+
// update animation
|
|
218
|
+
const animationFrame = this.isDead() ? 0 :
|
|
219
|
+
this.climbingLadder || this.groundTimer.active() ?
|
|
220
|
+
2*this.walkCyclePercent|0 : 1;
|
|
221
|
+
this.tileInfo = spriteAtlas.player.frame(animationFrame);
|
|
222
|
+
|
|
222
223
|
let bodyPos = this.pos;
|
|
223
224
|
if (!this.isDead())
|
|
224
225
|
{
|
|
@@ -245,7 +246,7 @@ class Character extends GameObject
|
|
|
245
246
|
if (this.isDead())
|
|
246
247
|
return;
|
|
247
248
|
|
|
248
|
-
makeBlood(this.pos,
|
|
249
|
+
makeBlood(this.pos, 100);
|
|
249
250
|
sound_die.play(this.pos);
|
|
250
251
|
|
|
251
252
|
this.health = 0;
|
|
@@ -34,12 +34,12 @@ const persistentParticleDestroyCallback = (particle)=>
|
|
|
34
34
|
tileLayers[foregroundLayerIndex].drawTile(particle.pos, particle.size, particle.tileInfo, particle.color, particle.angle, particle.mirror);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function makeBlood(pos, amount) { makeDebris(pos, hsl(0,1,.5),
|
|
38
|
-
function makeDebris(pos, color = hsl(), amount =
|
|
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)
|
|
39
39
|
{
|
|
40
40
|
const color2 = color.lerp(hsl(), .5);
|
|
41
41
|
const emitter = new ParticleEmitter(
|
|
42
|
-
pos, 0, 1, .1,
|
|
42
|
+
pos, 0, 1, .1, amount/.1, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
43
43
|
0, // tileInfo
|
|
44
44
|
color, color2, // colorStartA, colorStartB
|
|
45
45
|
color, color2, // colorEndA, colorEndB
|
|
@@ -163,87 +163,96 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
163
163
|
///////////////////////////////////////////////////////////////////////////////
|
|
164
164
|
// sky with background gradient, stars, and planets
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
function initSky()
|
|
166
|
+
class Sky extends EngineObject
|
|
169
167
|
{
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
168
|
+
constructor()
|
|
169
|
+
{
|
|
170
|
+
super();
|
|
174
171
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
gradient.addColorStop(1, horizonColor);
|
|
181
|
-
mainContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height);
|
|
182
|
-
}
|
|
172
|
+
this.renderOrder = -1e4;
|
|
173
|
+
this.seed = randInt(1e9);
|
|
174
|
+
this.skyColor = randColor(hsl(0,0,.5), hsl(0,0,.9));
|
|
175
|
+
this.horizonColor = this.skyColor.subtract(hsl(0,0,.05,0)).mutate(.3);
|
|
176
|
+
}
|
|
183
177
|
|
|
184
|
-
|
|
185
|
-
{
|
|
186
|
-
// draw stars and planets
|
|
187
|
-
const random = new RandomGenerator(skySeed);
|
|
188
|
-
for (let i = 1e3; i--;)
|
|
178
|
+
render()
|
|
189
179
|
{
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
180
|
+
// fill background with a gradient
|
|
181
|
+
const gradient = mainContext.createLinearGradient(0, 0, 0, mainCanvas.height);
|
|
182
|
+
gradient.addColorStop(0, this.skyColor);
|
|
183
|
+
gradient.addColorStop(1, this.horizonColor);
|
|
184
|
+
mainContext.save();
|
|
185
|
+
mainContext.fillStyle = gradient;
|
|
186
|
+
mainContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height);
|
|
187
|
+
mainContext.globalCompositeOperation = 'lighter';
|
|
188
|
+
|
|
189
|
+
// draw stars
|
|
190
|
+
const random = new RandomGenerator(this.seed);
|
|
191
|
+
for (let i=1e3; i--;)
|
|
192
|
+
{
|
|
193
|
+
const size = random.float(.5,2)**2;
|
|
194
|
+
const speed = random.float() < .9 ? random.float(5) : random.float(9,99);
|
|
195
|
+
const color = hsl(random.float(-.3,.2), random.float(), random.float());
|
|
196
|
+
const extraSpace = 50;
|
|
197
|
+
const w = mainCanvas.width+2*extraSpace, h = mainCanvas.height+2*extraSpace;
|
|
198
|
+
const screenPos = vec2(
|
|
199
|
+
(random.float(w)+time*speed)%w-extraSpace,
|
|
200
|
+
(random.float(h)+time*speed*random.float())%h-extraSpace);
|
|
201
|
+
mainContext.fillStyle = color;
|
|
202
|
+
mainContext.fillRect(screenPos.x, screenPos.y, size, size);
|
|
203
|
+
}
|
|
204
|
+
mainContext.restore();
|
|
201
205
|
}
|
|
202
206
|
}
|
|
203
207
|
|
|
204
208
|
///////////////////////////////////////////////////////////////////////////////
|
|
205
209
|
// parallax background mountain ranges
|
|
206
210
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
function initParallaxLayers()
|
|
211
|
+
class ParallaxLayer extends EngineObject
|
|
210
212
|
{
|
|
211
|
-
|
|
212
|
-
for (let i=3; i--;)
|
|
213
|
+
constructor(index)
|
|
213
214
|
{
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
super();
|
|
216
|
+
|
|
217
|
+
const size = vec2(1024,512);
|
|
218
|
+
this.size = size;
|
|
219
|
+
this.index = index;
|
|
220
|
+
this.renderOrder = -3e3 + index;
|
|
221
|
+
this.canvas = document.createElement('canvas');
|
|
222
|
+
this.context = this.canvas.getContext('2d');
|
|
223
|
+
this.canvas.width = size.x;
|
|
224
|
+
this.canvas.height = size.y;
|
|
219
225
|
|
|
220
226
|
// create a gradient
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
-
|
|
227
|
+
const o1 = 40-20*index;
|
|
228
|
+
const o2 = 100-30*index;
|
|
229
|
+
const gradient = this.context.createLinearGradient(0,size.y/2-o1,0,size.y/2+o2);
|
|
230
|
+
const layerColor = levelColor.mutate(.1).lerp(sky.skyColor,1-index*.15);
|
|
224
231
|
gradient.addColorStop(0,layerColor);
|
|
225
|
-
gradient.addColorStop(1,layerColor.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
gradient.addColorStop(1,layerColor.mutate(.5).scale(.1,1));
|
|
233
|
+
this.context.fillStyle = gradient;
|
|
234
|
+
|
|
235
|
+
// draw procedural mountains ranges
|
|
236
|
+
let groundLevel = size.y/2, groundSlope = rand(-1,1);
|
|
237
|
+
for (let i=size.x; i--;)
|
|
238
|
+
this.context.fillRect(i, groundLevel += groundSlope = rand() < .3 ? rand(1,-1) :
|
|
239
|
+
groundSlope + (size.y/2 - groundLevel)/300, 1, size.y);
|
|
232
240
|
}
|
|
233
|
-
}
|
|
234
241
|
|
|
235
|
-
|
|
236
|
-
{
|
|
237
|
-
tileParallaxLayers.forEach((tileParallaxLayer, i)=>
|
|
242
|
+
render()
|
|
238
243
|
{
|
|
239
|
-
// position layer
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
244
|
+
// position layer based on camera distance from center of level
|
|
245
|
+
const parallax = vec2(1e3,-100).scale(this.index**2);
|
|
246
|
+
const cameraDeltaFromCenter = cameraPos
|
|
247
|
+
.subtract(levelSize.scale(.5))
|
|
248
|
+
.divide(levelSize.divide(parallax));
|
|
249
|
+
const scale = this.size.scale(2+2*this.index);
|
|
250
|
+
const pos = mainCanvasSize.scale(.5) // center screen
|
|
251
|
+
.add(vec2(-scale.x/2,-scale.y/2)) // center layer
|
|
252
|
+
.add(cameraDeltaFromCenter.scale(-.5)) // apply parallax
|
|
253
|
+
.add(vec2(0,(this.index*.1)*this.size.y)); // separate layers
|
|
254
|
+
|
|
255
|
+
// draw the parallax layer onto the main canvas
|
|
256
|
+
mainContext.drawImage(this.canvas, pos.x, pos.y, scale.x, scale.y);
|
|
257
|
+
}
|
|
249
258
|
}
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
-
const tileType_ladder
|
|
12
|
-
const tileType_empty
|
|
13
|
-
const tileType_solid
|
|
14
|
-
const tileType_breakable
|
|
11
|
+
const tileType_ladder = -1;
|
|
12
|
+
const tileType_empty = 0;
|
|
13
|
+
const tileType_solid = 1;
|
|
14
|
+
const tileType_breakable = 2;
|
|
15
15
|
|
|
16
|
-
let player, playerStartPos, tileData, tileLayers, foregroundLayerIndex;
|
|
16
|
+
let player, playerStartPos, tileData, tileLayers, foregroundLayerIndex, sky;
|
|
17
17
|
let levelSize, levelColor, levelBackgroundColor, levelOutlineColor, warmup;
|
|
18
18
|
|
|
19
19
|
const setTileData = (pos, layer, data)=>
|
|
@@ -27,10 +27,14 @@ function buildLevel()
|
|
|
27
27
|
levelColor = randColor(hsl(0,0,.2), hsl(0,0,.8));
|
|
28
28
|
levelBackgroundColor = levelColor.mutate().scale(.4,1);
|
|
29
29
|
levelOutlineColor = levelColor.mutate().add(hsl(0,0,.4)).clamp();
|
|
30
|
-
|
|
31
30
|
loadLevel();
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
|
|
32
|
+
// create sky object with gradient and stars
|
|
33
|
+
sky = new Sky;
|
|
34
|
+
|
|
35
|
+
// create parallax layers
|
|
36
|
+
for (let i=3; i--;)
|
|
37
|
+
new ParallaxLayer(i);
|
|
34
38
|
|
|
35
39
|
// apply decoration to all level tiles
|
|
36
40
|
const pos = vec2();
|
|
@@ -47,7 +51,7 @@ function buildLevel()
|
|
|
47
51
|
warmup = 0;
|
|
48
52
|
|
|
49
53
|
// spawn player
|
|
50
|
-
player = new Player(
|
|
54
|
+
player = new Player(playerStartPos);
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
function loadLevel()
|
|
@@ -59,6 +63,19 @@ function loadLevel()
|
|
|
59
63
|
initTileCollision(levelSize);
|
|
60
64
|
engineObjectsDestroy();
|
|
61
65
|
|
|
66
|
+
// create table for tiles in the level tilemap
|
|
67
|
+
const tileLookup =
|
|
68
|
+
{
|
|
69
|
+
circle: 1,
|
|
70
|
+
ground: 2,
|
|
71
|
+
ladder: 4,
|
|
72
|
+
metal: 5,
|
|
73
|
+
player: 17,
|
|
74
|
+
crate: 18,
|
|
75
|
+
enemy: 19,
|
|
76
|
+
coin: 20,
|
|
77
|
+
}
|
|
78
|
+
|
|
62
79
|
// set all level data tiles
|
|
63
80
|
tileData = [];
|
|
64
81
|
tileLayers = [];
|
|
@@ -79,19 +96,18 @@ function loadLevel()
|
|
|
79
96
|
const pos = vec2(x,levelSize.y-1-y);
|
|
80
97
|
const tile = layerData[y*levelSize.x+x];
|
|
81
98
|
|
|
82
|
-
if (tile >=
|
|
99
|
+
if (tile >= tileLookup.player)
|
|
83
100
|
{
|
|
84
101
|
// create object instead of tile
|
|
85
102
|
const objectPos = pos.add(vec2(.5));
|
|
86
|
-
if (tile ==
|
|
103
|
+
if (tile == tileLookup.player)
|
|
87
104
|
playerStartPos = objectPos;
|
|
88
|
-
if (tile ==
|
|
105
|
+
if (tile == tileLookup.crate)
|
|
89
106
|
new Crate(objectPos);
|
|
90
|
-
if (tile ==
|
|
107
|
+
if (tile == tileLookup.enemy)
|
|
91
108
|
new Enemy(objectPos);
|
|
92
|
-
if (tile ==
|
|
109
|
+
if (tile == tileLookup.coin)
|
|
93
110
|
new Coin(objectPos);
|
|
94
|
-
setTileData(pos, layer, 0);
|
|
95
111
|
continue;
|
|
96
112
|
}
|
|
97
113
|
|
|
@@ -102,9 +118,9 @@ function loadLevel()
|
|
|
102
118
|
let tileType = tileType_empty;
|
|
103
119
|
if (tile > 0)
|
|
104
120
|
tileType = tileType_breakable;
|
|
105
|
-
if (tile ==
|
|
121
|
+
if (tile == tileLookup.ladder)
|
|
106
122
|
tileType = tileType_ladder;
|
|
107
|
-
if (tile ==
|
|
123
|
+
if (tile == tileLookup.metal)
|
|
108
124
|
tileType = tileType_solid;
|
|
109
125
|
if (tileType)
|
|
110
126
|
{
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
}
|
|
8
8
|
if(typeof module === 'object' && module && module.exports) {
|
|
9
9
|
module.exports = data;
|
|
10
|
-
}})("
|
|
10
|
+
}})("gameLevelData",
|
|
11
11
|
{ "compressionlevel":-1,
|
|
12
12
|
"height":64,
|
|
13
13
|
"infinite":false,
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 5, 2, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 5, 0, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
119
119
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
120
120
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 18, 0, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 18, 0, 0, 0, 0, 0, 0, 5, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
121
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 18, 18, 0, 5, 5, 0, 0, 19, 0, 0, 0, 5, 5, 0, 18, 18, 18, 0, 19,
|
|
121
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 4, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 18, 18, 0, 5, 5, 0, 0, 19, 0, 0, 0, 5, 5, 0, 18, 18, 18, 0, 19, 0, 0, 0, 5, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 4, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 0, 19, 0, 0, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
122
122
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
123
123
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 3, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
124
124
|
2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
"tilesets":[
|
|
173
173
|
{
|
|
174
174
|
"firstgid":1,
|
|
175
|
-
"source":"data\/
|
|
175
|
+
"source":"data\/gameLevelData.tsx"
|
|
176
176
|
}],
|
|
177
177
|
"tilewidth":16,
|
|
178
178
|
"type":"map",
|
|
@@ -66,7 +66,7 @@ class Crate extends GameObject
|
|
|
66
66
|
{
|
|
67
67
|
constructor(pos)
|
|
68
68
|
{
|
|
69
|
-
super(pos, vec2(1),
|
|
69
|
+
super(pos, vec2(1), spriteAtlas.crate, (randInt(4))*PI/2);
|
|
70
70
|
|
|
71
71
|
this.color = hsl(rand(),1,.8);
|
|
72
72
|
this.health = 5;
|
|
@@ -81,7 +81,7 @@ class Crate extends GameObject
|
|
|
81
81
|
return;
|
|
82
82
|
|
|
83
83
|
sound_destroyObject.play(this.pos);
|
|
84
|
-
makeDebris(this.pos, this.color,
|
|
84
|
+
makeDebris(this.pos, this.color, 30);
|
|
85
85
|
this.destroy();
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -92,7 +92,7 @@ class Coin extends EngineObject
|
|
|
92
92
|
{
|
|
93
93
|
constructor(pos)
|
|
94
94
|
{
|
|
95
|
-
super(pos, vec2(1),
|
|
95
|
+
super(pos, vec2(1), spriteAtlas.coin);
|
|
96
96
|
this.color = hsl(.15,1,.5);
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -127,7 +127,7 @@ class Enemy extends GameObject
|
|
|
127
127
|
{
|
|
128
128
|
constructor(pos)
|
|
129
129
|
{
|
|
130
|
-
super(pos, vec2(.9,.9),
|
|
130
|
+
super(pos, vec2(.9,.9), spriteAtlas.enemy);
|
|
131
131
|
|
|
132
132
|
this.drawSize = vec2(1);
|
|
133
133
|
this.color = hsl(rand(), 1, .7);
|
|
@@ -147,7 +147,7 @@ class Enemy extends GameObject
|
|
|
147
147
|
if (this.groundObject && rand() < .01 && this.pos.distance(player.pos) < 20)
|
|
148
148
|
{
|
|
149
149
|
this.velocity = vec2(rand(.1,-.1), rand(.4,.2));
|
|
150
|
-
sound_jump.play(this.pos);
|
|
150
|
+
sound_jump.play(this.pos, .4, 2);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// damage player if touching
|
|
@@ -162,7 +162,7 @@ class Enemy extends GameObject
|
|
|
162
162
|
|
|
163
163
|
++score;
|
|
164
164
|
sound_score.play(this.pos);
|
|
165
|
-
makeDebris(this.pos, this.color
|
|
165
|
+
makeDebris(this.pos, this.color);
|
|
166
166
|
this.destroy();
|
|
167
167
|
}
|
|
168
168
|
|
|
@@ -185,7 +185,7 @@ class Grenade extends GameObject
|
|
|
185
185
|
{
|
|
186
186
|
constructor(pos)
|
|
187
187
|
{
|
|
188
|
-
super(pos, vec2(.2),
|
|
188
|
+
super(pos, vec2(.2), spriteAtlas.grenade);
|
|
189
189
|
|
|
190
190
|
this.beepTimer = new Timer(1);
|
|
191
191
|
this.elasticity = .3;
|
|
@@ -218,7 +218,7 @@ class Grenade extends GameObject
|
|
|
218
218
|
// draw additive flash exploding
|
|
219
219
|
setBlendMode(true);
|
|
220
220
|
const flash = Math.cos(this.getAliveTime()*2*PI);
|
|
221
|
-
drawTile(this.pos, vec2(2),
|
|
221
|
+
drawTile(this.pos, vec2(2), spriteAtlas.circle, hsl(0,1,.5,.2-.2*flash));
|
|
222
222
|
setBlendMode(false);
|
|
223
223
|
}
|
|
224
224
|
}
|
|
@@ -229,7 +229,7 @@ class Weapon extends EngineObject
|
|
|
229
229
|
{
|
|
230
230
|
constructor(pos, parent)
|
|
231
231
|
{
|
|
232
|
-
super(pos, vec2(.6),
|
|
232
|
+
super(pos, vec2(.6), spriteAtlas.gun);
|
|
233
233
|
|
|
234
234
|
// weapon settings
|
|
235
235
|
this.fireRate = 8;
|
|
@@ -263,7 +263,7 @@ class Weapon extends EngineObject
|
|
|
263
263
|
|
|
264
264
|
// update recoil
|
|
265
265
|
if (this.recoilTimer.active())
|
|
266
|
-
this.localAngle = lerp(this.recoilTimer.getPercent(),
|
|
266
|
+
this.localAngle = lerp(this.recoilTimer.getPercent(), this.localAngle, 0);
|
|
267
267
|
|
|
268
268
|
this.mirror = this.parent.mirror;
|
|
269
269
|
this.fireTimeBuffer += timeDelta;
|
|
@@ -274,8 +274,8 @@ class Weapon extends EngineObject
|
|
|
274
274
|
{
|
|
275
275
|
// create bullet
|
|
276
276
|
sound_shoot.play(this.pos);
|
|
277
|
-
this.localAngle = -rand(.2,.
|
|
278
|
-
this.recoilTimer.set(.
|
|
277
|
+
this.localAngle = -rand(.2,.25);
|
|
278
|
+
this.recoilTimer.set(.1);
|
|
279
279
|
const direction = vec2(this.bulletSpeed*this.getMirrorSign(), 0);
|
|
280
280
|
const velocity = direction.rotate(rand(-1,1)*this.bulletSpread);
|
|
281
281
|
new Bullet(this.pos, this.parent, velocity, this.damage);
|
|
@@ -323,8 +323,8 @@ class Bullet extends EngineObject
|
|
|
323
323
|
this.range -= this.velocity.length();
|
|
324
324
|
if (this.range < 0)
|
|
325
325
|
{
|
|
326
|
-
|
|
327
|
-
this.pos, 0, .2, .1, 50, PI,
|
|
326
|
+
new ParticleEmitter(
|
|
327
|
+
this.pos, 0, .2, .1, 50, PI, spriteAtlas.circle, // pos, emit info, tileInfo
|
|
328
328
|
rgb(1,1,.1), rgb(1,1,1), // colorStartA, colorStartB
|
|
329
329
|
rgb(1,1,.1,0), rgb(1,1,1,0),// colorEndA, colorEndB
|
|
330
330
|
.1, .5, .1, .05, 0, // particleTime, sizeStart, sizeEnd, speed, angleSpeed
|
|
Binary file
|
package/examples/screenshot.jpg
CHANGED
|
Binary file
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
// import module
|
|
8
8
|
import * as LittleJS from '../../dist/littlejs.esm.js';
|
|
9
|
-
const {
|
|
9
|
+
const { tile, vec2, hsl } = LittleJS;
|
|
10
10
|
// show the LittleJS splash screen
|
|
11
11
|
LittleJS.setShowSplashScreen(true);
|
|
12
12
|
// sound effects
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
// import module
|
|
10
10
|
import * as LittleJS from '../../dist/littlejs.esm.js';
|
|
11
|
-
const {
|
|
11
|
+
const {tile, vec2, hsl} = LittleJS;
|
|
12
12
|
|
|
13
13
|
// show the LittleJS splash screen
|
|
14
14
|
LittleJS.setShowSplashScreen(true);
|