littlejsengine 1.10.2 → 1.10.7
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 +15 -93
- package/dist/littlejs.d.ts +79 -17
- package/dist/littlejs.esm.js +179 -90
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +165 -90
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +165 -90
- package/examples/box2d/game.js +15 -1
- package/examples/box2d/gameObjects.js +10 -9
- package/examples/box2d/index.html +5 -5
- package/examples/box2d/scenes.js +4 -4
- package/examples/box2d/tiles.png +0 -0
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/README.md +9 -7
- package/examples/breakoutTutorial/game.js +6 -6
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/game.js +3 -0
- package/examples/electron/index.html +2 -2
- package/examples/htmlMenu/index.html +3 -3
- package/examples/js13k/game.js +3 -0
- package/examples/js13k/index.html +13 -13
- package/examples/module/game.js +3 -0
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +4 -1
- package/examples/platformer/game.js +21 -15
- package/examples/platformer/gameCharacter.js +15 -14
- package/examples/platformer/gameEffects.js +3 -4
- package/examples/platformer/gameLevel.js +18 -33
- package/examples/platformer/gameObjects.js +9 -14
- package/examples/platformer/index.html +8 -8
- package/examples/platformer/tiles.png +0 -0
- package/examples/puzzle/index.html +2 -2
- package/examples/starter/game.js +3 -0
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +1 -1
- package/examples/typescript/game.js +2 -0
- package/examples/typescript/game.ts +4 -1
- package/examples/typescript/index.html +1 -1
- package/examples/uiSystem/game.js +23 -16
- package/examples/uiSystem/index.html +3 -14
- package/package.json +1 -1
- package/plugins/postProcess.js +1 -1
- package/plugins/uiSystem.js +84 -24
- package/src/engine.js +14 -22
- package/src/engineAudio.js +7 -13
- package/src/engineDraw.js +20 -19
- package/src/engineExport.js +14 -0
- package/src/engineInput.js +8 -6
- package/src/engineMedals.js +19 -5
- package/src/engineObject.js +9 -5
- package/src/engineTileLayer.js +10 -8
- package/src/engineUtilities.js +60 -10
- package/src/engineWebGL.js +17 -2
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
function spawnBox(pos, size=1, color=WHITE, type=box2dBodyTypeDynamic, applyTexture=true, angle=0)
|
|
13
13
|
{
|
|
14
14
|
size = typeof size == 'number' ? vec2(size) : size; // square
|
|
15
|
-
const o = new Box2dObject(pos, size, applyTexture &&
|
|
15
|
+
const o = new Box2dObject(pos, size, applyTexture && spriteAtlas.squareOutline, angle, color, type);
|
|
16
|
+
o.drawSize = size.scale(1.02); // slightly enarge to cover gaps
|
|
16
17
|
o.addBox(size);
|
|
17
18
|
return o;
|
|
18
19
|
}
|
|
@@ -20,7 +21,7 @@ function spawnBox(pos, size=1, color=WHITE, type=box2dBodyTypeDynamic, applyText
|
|
|
20
21
|
function spawnCircle(pos, diameter=1, color=WHITE, type=box2dBodyTypeDynamic, applyTexture=true, angle=0)
|
|
21
22
|
{
|
|
22
23
|
const size = vec2(diameter);
|
|
23
|
-
const o = new Box2dObject(pos, size, applyTexture &&
|
|
24
|
+
const o = new Box2dObject(pos, size, applyTexture && spriteAtlas.circleOutline, angle, color, type);
|
|
24
25
|
o.addCircle(diameter);
|
|
25
26
|
return o;
|
|
26
27
|
}
|
|
@@ -115,7 +116,7 @@ class CarObject extends Box2dObject
|
|
|
115
116
|
const damping = .7;
|
|
116
117
|
const frequencyHz = 4;
|
|
117
118
|
const maxTorque = 50;
|
|
118
|
-
const sprite =
|
|
119
|
+
const sprite = spriteAtlas.wheel;
|
|
119
120
|
|
|
120
121
|
// create wheels
|
|
121
122
|
this.wheels = [];
|
|
@@ -208,7 +209,7 @@ class PulleyJointObjects extends Box2dObject
|
|
|
208
209
|
{
|
|
209
210
|
constructor(pos, size, color, connectionPos)
|
|
210
211
|
{
|
|
211
|
-
super(pos, size,
|
|
212
|
+
super(pos, size, spriteAtlas.squareOutline, 0, color);
|
|
212
213
|
this.addBox(size);
|
|
213
214
|
this.connectionPos = connectionPos;
|
|
214
215
|
}
|
|
@@ -228,7 +229,7 @@ class MotorJointObject extends Box2dObject
|
|
|
228
229
|
{
|
|
229
230
|
constructor(pos, size, color, otherObject)
|
|
230
231
|
{
|
|
231
|
-
super(pos, size,
|
|
232
|
+
super(pos, size, spriteAtlas.wheel, 0, color);
|
|
232
233
|
this.addCircle(size.x);
|
|
233
234
|
this.connectionPos = pos;
|
|
234
235
|
const joint = box2dCreateMotorJoint(otherObject, this);
|
|
@@ -265,7 +266,7 @@ class SoftBodyObject extends Box2dObject
|
|
|
265
266
|
const mass = .1;
|
|
266
267
|
const center = vec2(x-nodeSize.x/2, y-nodeSize.y/2);
|
|
267
268
|
const p = pos.add(center.multiply(spacing));
|
|
268
|
-
const o = new Box2dObject(p, vec2(objectDiameter*1.1),
|
|
269
|
+
const o = new Box2dObject(p, vec2(objectDiameter*1.1), spriteAtlas.circle, 0, color);
|
|
269
270
|
o.addCircle(objectDiameter);
|
|
270
271
|
o.setMass(mass);
|
|
271
272
|
o.setAngularDamping(10);
|
|
@@ -336,7 +337,7 @@ class ClothObject extends Box2dObject
|
|
|
336
337
|
const mass = .5;
|
|
337
338
|
const center = vec2(x-nodeSize.x/2, y-nodeSize.y/2);
|
|
338
339
|
const p = pos.add(center.multiply(spacing));
|
|
339
|
-
const o = new Box2dObject(p, vec2(.4),
|
|
340
|
+
const o = new Box2dObject(p, vec2(.4), spriteAtlas.circle, 0, color);
|
|
340
341
|
o.addCircle(objectDiameter);
|
|
341
342
|
o.setFilterData(2, 2);
|
|
342
343
|
o.setLinearDamping(1);
|
|
@@ -463,7 +464,7 @@ function explosion(pos, radius=3, strength=300)
|
|
|
463
464
|
new ParticleEmitter(
|
|
464
465
|
pos, 0, // pos, angle
|
|
465
466
|
radius/2, .2, 50*radius, PI,// emitSize, emitTime, emitRate, emiteCone
|
|
466
|
-
|
|
467
|
+
spriteAtlas.dot, // tileInfo
|
|
467
468
|
hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
|
|
468
469
|
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
469
470
|
1, 1, 2, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
@@ -475,7 +476,7 @@ function explosion(pos, radius=3, strength=300)
|
|
|
475
476
|
new ParticleEmitter(
|
|
476
477
|
pos, 0, // pos, angle
|
|
477
478
|
radius, .1, 100*radius, PI, // emitSize, emitTime, emitRate, emiteCone
|
|
478
|
-
|
|
479
|
+
spriteAtlas.dot, // tileInfo
|
|
479
480
|
hsl(0,1,.5), hsl(.15,1,.5), // colorStartA, colorStartB
|
|
480
481
|
hsl(0,1,.5,0), hsl(.1, 1,.5,0), // colorEndA, colorEndB
|
|
481
482
|
.7, 1, .5, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<script src=../../dist/littlejs.js></script>
|
|
10
|
-
<script src=../../plugins/Box2D_v2.3.1_min.wasm.js?
|
|
11
|
-
<script src=../../plugins/box2d.js?
|
|
12
|
-
<script src=scenes.js?
|
|
13
|
-
<script src=gameObjects.js?
|
|
14
|
-
<script src=game.js?
|
|
10
|
+
<script src=../../plugins/Box2D_v2.3.1_min.wasm.js?1105></script>
|
|
11
|
+
<script src=../../plugins/box2d.js?1105></script>
|
|
12
|
+
<script src=scenes.js?1105></script>
|
|
13
|
+
<script src=gameObjects.js?1105></script>
|
|
14
|
+
<script src=game.js?1105></script>
|
package/examples/box2d/scenes.js
CHANGED
|
@@ -132,7 +132,7 @@ function loadScene(_scene)
|
|
|
132
132
|
const o1 = spawnCircle(vec2(23.5,3), 3, randColor());
|
|
133
133
|
const j1 = box2dCreateRevoluteJoint(groundObject, o1, o1.pos);
|
|
134
134
|
const o2 = spawnCircle(vec2(28,3), 6, randColor());
|
|
135
|
-
o1.tileInfo = o2.tileInfo =
|
|
135
|
+
o1.tileInfo = o2.tileInfo = spriteAtlas.gear;
|
|
136
136
|
const j2 = box2dCreateRevoluteJoint(groundObject, o2, o2.pos);
|
|
137
137
|
box2dCreateGearJoint(o1, o2, j1, j2, 2);
|
|
138
138
|
}
|
|
@@ -144,21 +144,21 @@ function loadScene(_scene)
|
|
|
144
144
|
}
|
|
145
145
|
{
|
|
146
146
|
// distance joint
|
|
147
|
-
const o1 = new Box2dObject(vec2(30,11), vec2(4),
|
|
147
|
+
const o1 = new Box2dObject(vec2(30,11), vec2(4), spriteAtlas.circleOutline, 0, randColor(), box2dBodyTypeStatic);
|
|
148
148
|
o1.renderOrder = -2;
|
|
149
149
|
const o2 = spawnCircle(vec2(30,8), 2, randColor());
|
|
150
150
|
box2dCreateDistanceJoint(o1, o2);
|
|
151
151
|
}
|
|
152
152
|
{
|
|
153
153
|
// motor joint
|
|
154
|
-
const o = new Box2dObject(vec2(10,8), vec2(4),
|
|
154
|
+
const o = new Box2dObject(vec2(10,8), vec2(4), spriteAtlas.circleOutline, 0, randColor(), box2dBodyTypeStatic);
|
|
155
155
|
o.renderOrder = -2;
|
|
156
156
|
new MotorJointObject(vec2(10,8), vec2(2), randColor(), o);
|
|
157
157
|
}
|
|
158
158
|
{
|
|
159
159
|
// friction joint
|
|
160
160
|
const o = spawnBox(vec2(10,15), 3, randColor());
|
|
161
|
-
o.tileInfo =
|
|
161
|
+
o.tileInfo = spriteAtlas.squareOutline2;
|
|
162
162
|
const joint = box2dCreateFrictionJoint(groundObject, o);
|
|
163
163
|
joint.SetMaxForce(200);
|
|
164
164
|
joint.SetMaxTorque(200);
|
package/examples/box2d/tiles.png
CHANGED
|
Binary file
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<link rel=icon type=image/png href=../favicon.png>
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
|
-
<script src=../../dist/littlejs.js?
|
|
9
|
+
<script src=../../dist/littlejs.js?1105></script>
|
|
10
10
|
<script src=../../plugins/postProcess.js></script>
|
|
11
|
-
<script src=gameObjects.js?
|
|
12
|
-
<script src=game.js?
|
|
11
|
+
<script src=gameObjects.js?1105></script>
|
|
12
|
+
<script src=game.js?1105></script>
|
|
@@ -53,6 +53,8 @@ for(let y=0; y<=levelSize.y; y+=1)
|
|
|
53
53
|
## Move the Camera
|
|
54
54
|
|
|
55
55
|
Let’s move the camera to the center of our level by setting the cameraPos variable to half the level size.
|
|
56
|
+
You can also change the camera zoom by using camaraScale which controls the number of pixels for each world space unit.
|
|
57
|
+
For this example the camera will just remain stationary, but in other types of games it is very useful!
|
|
56
58
|
|
|
57
59
|
```javascript
|
|
58
60
|
setCameraPos(levelSize.scale(.5)); // center camera in level
|
|
@@ -307,7 +309,7 @@ collideWithObject(o)
|
|
|
307
309
|
But wait! This will cause the ball to careen through the bricks without bouncing. Maybe fun for a special powerup, but not our goal here. This function should return a Boolean value to indicate if the collision needs to be resolved, if it returns false then the ball will not bounce. So the answer is to just add another line of code to the collideWithObject function that returns a truthy value indicating that the collision should occur.
|
|
308
310
|
|
|
309
311
|
```javascript
|
|
310
|
-
return
|
|
312
|
+
return true; // allow object to collide
|
|
311
313
|
```
|
|
312
314
|
|
|
313
315
|

|
|
@@ -356,7 +358,7 @@ To play the sound we will override collideWithObject for the Ball class. Also re
|
|
|
356
358
|
collideWithObject(o)
|
|
357
359
|
{
|
|
358
360
|
sound_bounce.play(); // play bounce sound
|
|
359
|
-
return
|
|
361
|
+
return true; // allow object to collide
|
|
360
362
|
}
|
|
361
363
|
```
|
|
362
364
|
Let’s also make a brick break sound. You can use the ZzFX sound designer again to create your own sound, for this one try the Hit preset.
|
|
@@ -422,12 +424,12 @@ const color = this.color;
|
|
|
422
424
|
new ParticleEmitter(
|
|
423
425
|
this.pos, 0, // pos, angle
|
|
424
426
|
this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emiteCone
|
|
425
|
-
|
|
427
|
+
undefined, // tileInfo
|
|
426
428
|
color, color, // colorStartA, colorStartB
|
|
427
429
|
color.scale(1,0), color.scale(1,0), // colorEndA, colorEndB
|
|
428
430
|
.2, .5, 1, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
429
431
|
.99, .95, .4, PI, // damping, angleDamping, gravityScale, cone
|
|
430
|
-
.1, .5,
|
|
432
|
+
.1, .5, false, true // fadeRate, randomness, collide, additive
|
|
431
433
|
);
|
|
432
434
|
```
|
|
433
435
|
|
|
@@ -446,7 +448,7 @@ collideWithObject(o)
|
|
|
446
448
|
{
|
|
447
449
|
// prevent colliding with paddle if moving upwards
|
|
448
450
|
if (o == paddle && this.velocity.y > 0)
|
|
449
|
-
return
|
|
451
|
+
return false;
|
|
450
452
|
|
|
451
453
|
sound_bounce.play(); // play bounce sound
|
|
452
454
|
|
|
@@ -460,10 +462,10 @@ collideWithObject(o)
|
|
|
460
462
|
this.velocity.y = max(-this.velocity.y, .2);
|
|
461
463
|
|
|
462
464
|
// prevent default collision code
|
|
463
|
-
return
|
|
465
|
+
return false;
|
|
464
466
|
}
|
|
465
467
|
|
|
466
|
-
return
|
|
468
|
+
return true; // allow object to collide
|
|
467
469
|
}
|
|
468
470
|
```
|
|
469
471
|
|
|
@@ -54,7 +54,7 @@ class Ball extends EngineObject
|
|
|
54
54
|
{
|
|
55
55
|
// prevent colliding with paddle if moving upwards
|
|
56
56
|
if (o == paddle && this.velocity.y > 0)
|
|
57
|
-
return
|
|
57
|
+
return false;
|
|
58
58
|
|
|
59
59
|
// speed up
|
|
60
60
|
const speed = min(1.04*this.velocity.length(), .5);
|
|
@@ -73,10 +73,10 @@ class Ball extends EngineObject
|
|
|
73
73
|
this.velocity.y = max(-this.velocity.y, .2);
|
|
74
74
|
|
|
75
75
|
// prevent default collision code
|
|
76
|
-
return
|
|
76
|
+
return false;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
return
|
|
79
|
+
return true; // allow object to collide
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -114,15 +114,15 @@ class Brick extends EngineObject
|
|
|
114
114
|
new ParticleEmitter(
|
|
115
115
|
this.pos, 0, // pos, angle
|
|
116
116
|
this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emiteCone
|
|
117
|
-
|
|
117
|
+
undefined, // tileInfo
|
|
118
118
|
color, color, // colorStartA, colorStartB
|
|
119
119
|
color.scale(1,0), color.scale(1,0), // colorEndA, colorEndB
|
|
120
120
|
.2, .5, 1, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
121
121
|
.99, .95, .4, PI, // damp, angleDamp, gravity, cone
|
|
122
|
-
.1, .5,
|
|
122
|
+
.1, .5, false, true // fade, randomness, collide, additive
|
|
123
123
|
);
|
|
124
124
|
|
|
125
|
-
return
|
|
125
|
+
return true; // allow object to collide
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?
|
|
10
|
+
<script src=../../dist/littlejs.js?1105></script>
|
|
11
11
|
|
|
12
12
|
<!-- Add your game scripts here -->
|
|
13
|
-
<script src=game.js?
|
|
13
|
+
<script src=game.js?1105></script>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<!-- setup html menu system -->
|
|
33
33
|
<div class="topDiv">
|
|
34
34
|
<div id="menu" class="menuDiv">
|
|
35
|
-
<
|
|
35
|
+
<b style="font-size:50px">Test Menu</b>
|
|
36
36
|
This is an example menu using html elements.
|
|
37
37
|
<input value="Test Input" onchange="alert('New text: ' + this.value)">
|
|
38
38
|
<input type="range" onchange="alert('New value: ' + this.value)">
|
|
@@ -52,5 +52,5 @@ setMenuVisible(false);
|
|
|
52
52
|
</script>
|
|
53
53
|
|
|
54
54
|
<!-- Add your game scripts here -->
|
|
55
|
-
<script src=../../dist/littlejs.js?
|
|
56
|
-
<script src=game.js?
|
|
55
|
+
<script src=../../dist/littlejs.js?1105></script>
|
|
56
|
+
<script src=game.js?1105></script>
|
package/examples/js13k/game.js
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
</head><body>
|
|
5
5
|
|
|
6
6
|
<!-- LittleJS Engine -->
|
|
7
|
-
<script src=../../src/engineDebug.js?
|
|
8
|
-
<script src=../../src/engineUtilities.js?
|
|
9
|
-
<script src=../../src/engineSettings.js?
|
|
10
|
-
<script src=../../src/engineObject.js?
|
|
11
|
-
<script src=../../src/engineDraw.js?
|
|
12
|
-
<script src=../../src/engineInput.js?
|
|
13
|
-
<script src=../../src/engineAudio.js?
|
|
14
|
-
<script src=../../src/engineTileLayer.js?
|
|
15
|
-
<script src=../../src/engineParticles.js?
|
|
16
|
-
<script src=../../src/engineMedals.js?
|
|
17
|
-
<script src=../../src/engineWebGL.js?
|
|
18
|
-
<script src=../../src/engine.js?
|
|
7
|
+
<script src=../../src/engineDebug.js?1105></script>
|
|
8
|
+
<script src=../../src/engineUtilities.js?1105></script>
|
|
9
|
+
<script src=../../src/engineSettings.js?1105></script>
|
|
10
|
+
<script src=../../src/engineObject.js?1105></script>
|
|
11
|
+
<script src=../../src/engineDraw.js?1105></script>
|
|
12
|
+
<script src=../../src/engineInput.js?1105></script>
|
|
13
|
+
<script src=../../src/engineAudio.js?1105></script>
|
|
14
|
+
<script src=../../src/engineTileLayer.js?1105></script>
|
|
15
|
+
<script src=../../src/engineParticles.js?1105></script>
|
|
16
|
+
<script src=../../src/engineMedals.js?1105></script>
|
|
17
|
+
<script src=../../src/engineWebGL.js?1105></script>
|
|
18
|
+
<script src=../../src/engine.js?1105></script>
|
|
19
19
|
|
|
20
20
|
<!-- Add your game scripts here -->
|
|
21
|
-
<script src=game.js?
|
|
21
|
+
<script src=game.js?1105></script>
|
package/examples/module/game.js
CHANGED
|
@@ -13,6 +13,9 @@ const {tile, vec2, hsl} = LittleJS;
|
|
|
13
13
|
// show the LittleJS splash screen
|
|
14
14
|
LittleJS.setShowSplashScreen(true);
|
|
15
15
|
|
|
16
|
+
// fix texture bleeding by shrinking tile slightly
|
|
17
|
+
LittleJS.setTileFixBleedScale(.5);
|
|
18
|
+
|
|
16
19
|
// sound effects
|
|
17
20
|
const sound_click = new LittleJS.Sound([1,.5]);
|
|
18
21
|
|
|
@@ -10,11 +10,14 @@ button { margin:1px; }
|
|
|
10
10
|
</style>
|
|
11
11
|
</head><body>
|
|
12
12
|
|
|
13
|
-
<script src=../../dist/littlejs.js?
|
|
13
|
+
<script src=../../dist/littlejs.js?1105></script>
|
|
14
14
|
<script>
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
+
// fix texture bleeding by shrinking tiles slightly
|
|
19
|
+
tileFixBleedScale = .5;
|
|
20
|
+
|
|
18
21
|
let particleEditor = 0, particleSystem, particleSystemDiv, particleSystemCode;
|
|
19
22
|
let inputExpand;
|
|
20
23
|
let restartTimer = new Timer();
|
|
@@ -13,37 +13,39 @@ setShowSplashScreen(true);
|
|
|
13
13
|
|
|
14
14
|
let spriteAtlas, score, deaths;
|
|
15
15
|
|
|
16
|
+
// enable touch gamepad on touch devices
|
|
17
|
+
touchGamepadEnable = true;
|
|
18
|
+
|
|
16
19
|
///////////////////////////////////////////////////////////////////////////////
|
|
17
20
|
function gameInit()
|
|
18
21
|
{
|
|
22
|
+
// engine settings
|
|
23
|
+
gravity = -.01;
|
|
24
|
+
objectDefaultDamping = .99;
|
|
25
|
+
objectDefaultAngleDamping = .99;
|
|
26
|
+
cameraScale = 4*16;
|
|
27
|
+
|
|
19
28
|
// create a table of all sprites
|
|
29
|
+
const gameTile = (i, size=16)=> tile(i, size, 0, 1);
|
|
20
30
|
spriteAtlas =
|
|
21
31
|
{
|
|
22
32
|
// large tiles
|
|
23
|
-
circle:
|
|
24
|
-
crate:
|
|
25
|
-
player:
|
|
26
|
-
enemy:
|
|
27
|
-
coin:
|
|
33
|
+
circle: gameTile(0),
|
|
34
|
+
crate: gameTile(1),
|
|
35
|
+
player: gameTile(2),
|
|
36
|
+
enemy: gameTile(4),
|
|
37
|
+
coin: gameTile(5),
|
|
28
38
|
|
|
29
39
|
// small tiles
|
|
30
|
-
gun:
|
|
31
|
-
grenade:
|
|
40
|
+
gun: gameTile(vec2(0,2),8),
|
|
41
|
+
grenade: gameTile(vec2(1,2),8),
|
|
32
42
|
};
|
|
33
43
|
|
|
34
|
-
// enable touch gamepad on touch devices
|
|
35
|
-
touchGamepadEnable = true;
|
|
36
|
-
|
|
37
44
|
// setup level
|
|
38
45
|
buildLevel();
|
|
39
46
|
|
|
40
47
|
// init game
|
|
41
48
|
score = deaths = 0;
|
|
42
|
-
gravity = -.01;
|
|
43
|
-
objectDefaultDamping = .99;
|
|
44
|
-
objectDefaultAngleDamping = .99;
|
|
45
|
-
cameraScale = 4*16;
|
|
46
|
-
cameraPos = getCameraTarget();
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -75,6 +77,10 @@ function gameUpdate()
|
|
|
75
77
|
// M = move player to mouse
|
|
76
78
|
if (keyWasPressed('KeyM'))
|
|
77
79
|
player.pos = mousePos;
|
|
80
|
+
|
|
81
|
+
// R = restart level
|
|
82
|
+
if (keyWasPressed('KeyR'))
|
|
83
|
+
buildLevel();
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -15,7 +15,7 @@ class Character extends GameObject
|
|
|
15
15
|
{
|
|
16
16
|
constructor(pos)
|
|
17
17
|
{
|
|
18
|
-
super(pos, vec2(.6,.95)
|
|
18
|
+
super(pos, vec2(.6,.95));
|
|
19
19
|
|
|
20
20
|
this.weapon = new Weapon(pos, this);
|
|
21
21
|
this.lastPos = pos;
|
|
@@ -31,6 +31,7 @@ class Character extends GameObject
|
|
|
31
31
|
this.renderOrder = 10;
|
|
32
32
|
this.walkCyclePercent = 0;
|
|
33
33
|
this.health = 1;
|
|
34
|
+
this.climbingLadder = false;
|
|
34
35
|
this.setCollision(true,false);
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -102,9 +103,9 @@ class Character extends GameObject
|
|
|
102
103
|
touchingLadder ||= collisionData == tileType_ladder;
|
|
103
104
|
}
|
|
104
105
|
if (!touchingLadder)
|
|
105
|
-
this.climbingLadder =
|
|
106
|
+
this.climbingLadder = false;
|
|
106
107
|
else if (moveInput.y)
|
|
107
|
-
this.climbingLadder =
|
|
108
|
+
this.climbingLadder = true;
|
|
108
109
|
|
|
109
110
|
if (this.weapon) // update weapon trigger
|
|
110
111
|
this.weapon.triggerIsDown = this.holdingShoot && !this.dodgeTimer.active();
|
|
@@ -177,7 +178,7 @@ class Character extends GameObject
|
|
|
177
178
|
|
|
178
179
|
// apply movement acceleration and clamp
|
|
179
180
|
const maxCharacterSpeed = .2;
|
|
180
|
-
this.velocity.x = clamp(this.velocity.x + moveInput.x * .
|
|
181
|
+
this.velocity.x = clamp(this.velocity.x + moveInput.x * .04, -maxCharacterSpeed, maxCharacterSpeed);
|
|
181
182
|
|
|
182
183
|
// track last pos for ladder collision code
|
|
183
184
|
this.lastPos = this.pos.copy();
|
|
@@ -225,7 +226,7 @@ class Character extends GameObject
|
|
|
225
226
|
if (!this.isDead())
|
|
226
227
|
{
|
|
227
228
|
// bounce pos with walk cycle
|
|
228
|
-
bodyPos = bodyPos.add(vec2(0,.05*Math.sin(this.walkCyclePercent*PI)));
|
|
229
|
+
bodyPos = bodyPos.add(vec2(0,.01+.05*Math.sin(this.walkCyclePercent*PI)));
|
|
229
230
|
|
|
230
231
|
// make bottom flush
|
|
231
232
|
bodyPos = bodyPos.add(vec2(0,(this.drawSize.y-this.size.y)/2));
|
|
@@ -236,10 +237,10 @@ class Character extends GameObject
|
|
|
236
237
|
damage(damage, damagingObject)
|
|
237
238
|
{
|
|
238
239
|
if (this.isDead() || this.getAliveTime() < 1 || this.dodgeTimer.active())
|
|
239
|
-
return;
|
|
240
|
+
return 0;
|
|
240
241
|
|
|
241
242
|
makeBlood(damagingObject ? damagingObject.pos : this.pos);
|
|
242
|
-
super.damage(damage, damagingObject);
|
|
243
|
+
return super.damage(damage, damagingObject);
|
|
243
244
|
}
|
|
244
245
|
|
|
245
246
|
kill(damagingObject)
|
|
@@ -251,31 +252,31 @@ class Character extends GameObject
|
|
|
251
252
|
sound_die.play(this.pos);
|
|
252
253
|
|
|
253
254
|
this.health = 0;
|
|
254
|
-
if (this.weapon)
|
|
255
|
-
this.weapon.destroy();
|
|
256
255
|
this.deadTimer.set();
|
|
257
256
|
this.size = this.size.scale(.5);
|
|
258
257
|
const fallDirection = damagingObject ? sign(damagingObject.velocity.x) : randSign();
|
|
259
258
|
this.angleVelocity = fallDirection*rand(.22,.14);
|
|
260
259
|
this.angleDamping = .9;
|
|
261
260
|
this.renderOrder = -1; // move to back layer
|
|
261
|
+
if (this.weapon)
|
|
262
|
+
this.weapon.destroy();
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
collideWithTile(data, pos)
|
|
265
266
|
{
|
|
266
267
|
if (!data)
|
|
267
|
-
return;
|
|
268
|
+
return false;
|
|
268
269
|
|
|
269
270
|
if (data == tileType_ladder)
|
|
270
271
|
{
|
|
271
272
|
// handle ladder collisions
|
|
272
273
|
if (pos.y + 1 > this.lastPos.y - this.size.y/2)
|
|
273
|
-
return;
|
|
274
|
+
return false;
|
|
274
275
|
|
|
275
276
|
if (getTileCollisionData(pos.add(vec2(0,1))) // above
|
|
276
277
|
&& !getTileCollisionData(pos.add(vec2(1,0))) // left
|
|
277
278
|
&& !getTileCollisionData(pos.add(vec2(1,0)))) // right
|
|
278
|
-
return; // dont collide if something above it and nothing to left or right
|
|
279
|
+
return false; // dont collide if something above it and nothing to left or right
|
|
279
280
|
|
|
280
281
|
// allow standing on top of ladders
|
|
281
282
|
return !this.climbingLadder;
|
|
@@ -287,9 +288,9 @@ class Character extends GameObject
|
|
|
287
288
|
{
|
|
288
289
|
// break blocks above
|
|
289
290
|
this.velocity.y = 0;
|
|
290
|
-
return;
|
|
291
|
+
return false;
|
|
291
292
|
}
|
|
292
293
|
|
|
293
|
-
return
|
|
294
|
+
return true;
|
|
294
295
|
}
|
|
295
296
|
}
|
|
@@ -129,13 +129,13 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
129
129
|
// destroy tile
|
|
130
130
|
const tileType = getTileCollisionData(pos);
|
|
131
131
|
if (!tileType)
|
|
132
|
-
return
|
|
132
|
+
return true;
|
|
133
133
|
|
|
134
134
|
const tileLayer = tileLayers[foregroundLayerIndex];
|
|
135
135
|
const centerPos = pos.add(vec2(.5));
|
|
136
136
|
const layerData = tileLayer.getData(pos);
|
|
137
137
|
if (!layerData || tileType == tileType_solid)
|
|
138
|
-
return;
|
|
138
|
+
return false;
|
|
139
139
|
|
|
140
140
|
// create effects
|
|
141
141
|
makeDebris(centerPos, layerData.color.mutate());
|
|
@@ -144,7 +144,6 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
144
144
|
// set and clear tile
|
|
145
145
|
tileLayer.setData(pos, new TileLayerData, 1);
|
|
146
146
|
setTileCollisionData(pos, tileType_empty);
|
|
147
|
-
setTileData(pos, foregroundLayerIndex, 0);
|
|
148
147
|
|
|
149
148
|
// cleanup neighbors
|
|
150
149
|
if (cleanNeighbors)
|
|
@@ -154,7 +153,7 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
154
153
|
decorateTile(pos.add(vec2(i,j)));
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
return
|
|
156
|
+
return true;
|
|
158
157
|
}
|
|
159
158
|
|
|
160
159
|
///////////////////////////////////////////////////////////////////////////////
|