littlejsengine 1.11.5 → 1.11.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 +11 -16
- package/dist/littlejs.d.ts +14 -1
- package/dist/littlejs.esm.js +40 -26
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +37 -26
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +33 -25
- package/examples/box2d/game.js +2 -2
- package/examples/box2d/index.html +5 -5
- package/examples/breakout/game.js +6 -5
- package/examples/breakout/gameObjects.js +1 -1
- package/examples/breakout/index.html +4 -4
- package/examples/breakoutTutorial/README.md +1 -1
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/htmlMenu/index.html +2 -2
- package/examples/index.html +300 -32
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +1 -1
- package/examples/platformer/gamePlayer.js +2 -7
- package/examples/platformer/index.html +8 -8
- package/examples/puzzle/index.html +2 -2
- package/examples/shorts/animation.js +18 -0
- package/examples/shorts/base.html +26 -0
- package/examples/shorts/blending.js +16 -0
- package/examples/shorts/clock.js +21 -0
- package/examples/shorts/colors.js +25 -0
- package/examples/shorts/helloWorld.js +8 -0
- package/examples/shorts/platformer.js +42 -0
- package/{shortExamples/code → examples/shorts}/playSound.js +4 -3
- package/{shortExamples/code → examples/shorts}/pong.js +3 -3
- package/{shortExamples/code → examples/shorts}/shapes.js +1 -1
- package/examples/shorts/spriteAtlas.js +34 -0
- package/examples/shorts/systemFont.js +16 -0
- package/{shortExamples/code → examples/shorts}/tileLayer.js +1 -1
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/tiltedView.js +44 -0
- package/examples/shorts/timers.js +40 -0
- package/examples/shorts/topDown.js +44 -0
- package/examples/starter/game.js +3 -3
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +2 -2
- package/examples/uiSystem/game.js +6 -1
- package/examples/uiSystem/index.html +3 -3
- package/package.json +1 -1
- package/plugins/Box2D_License.txt +17 -0
- package/plugins/uiSystem.js +2 -1
- package/reference.md +2 -1
- package/src/engine.js +1 -1
- package/src/engineDebug.js +5 -1
- package/src/engineDraw.js +4 -1
- package/src/engineExport.js +3 -0
- package/src/engineInput.js +19 -15
- package/src/engineObject.js +4 -4
- package/src/engineRelease.js +1 -0
- package/src/engineTileLayer.js +2 -2
- package/src/engineUtilities.js +2 -2
- package/shortExamples/base.html +0 -36
- package/shortExamples/code/blending.js +0 -12
- package/shortExamples/code/helloWorld.js +0 -7
- package/shortExamples/code/spriteAtlas.js +0 -27
- package/shortExamples/code/systemFont.js +0 -14
- package/shortExamples/index.html +0 -242
- package/shortExamples/tiles.png +0 -0
- /package/{shortExamples/code → examples/shorts}/particles.js +0 -0
- /package/{shortExamples/code → examples/shorts}/texture.js +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
class PhysicsObject extends EngineObject
|
|
2
|
+
{
|
|
3
|
+
constructor(pos, size, color)
|
|
4
|
+
{
|
|
5
|
+
super(pos, size, 0, 0, color);
|
|
6
|
+
this.setCollision(); // make object collide
|
|
7
|
+
this.mass = 0; // make object have static physics
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class Player extends PhysicsObject
|
|
12
|
+
{
|
|
13
|
+
constructor(pos)
|
|
14
|
+
{
|
|
15
|
+
super(pos, vec2(2,4), RED);
|
|
16
|
+
this.mass = 1; // make object have dynamic physics
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
update()
|
|
20
|
+
{
|
|
21
|
+
// apply movement controls
|
|
22
|
+
const moveInput = keyDirection();
|
|
23
|
+
this.velocity.x += moveInput.x * (this.groundObject ? .1: .01);
|
|
24
|
+
if (this.groundObject && moveInput.y > 0)
|
|
25
|
+
this.velocity.y = .9; // jump
|
|
26
|
+
|
|
27
|
+
super.update(); // call parent update function
|
|
28
|
+
cameraPos = vec2(this.pos.x, 9); // move camera with player
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function gameInit()
|
|
33
|
+
{
|
|
34
|
+
// setup level
|
|
35
|
+
gravity = -.05;
|
|
36
|
+
new Player(vec2(0,4));
|
|
37
|
+
|
|
38
|
+
// create random objects
|
|
39
|
+
new PhysicsObject(vec2(), vec2(1e3,4), GRAY); // ground
|
|
40
|
+
for (let i = 1; i < 500; ++i)
|
|
41
|
+
new PhysicsObject(vec2(i*10+randInt(4), 0), vec2(2+randInt(20),4+randInt(8)), GREEN);
|
|
42
|
+
}
|
|
@@ -9,12 +9,14 @@ class SoundButton extends EngineObject
|
|
|
9
9
|
|
|
10
10
|
update()
|
|
11
11
|
{
|
|
12
|
+
// play sound when clicked
|
|
12
13
|
if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
|
|
13
14
|
this.sound.play(this.pos);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
render()
|
|
17
18
|
{
|
|
19
|
+
// draw the button and icon
|
|
18
20
|
drawRect(this.pos, this.size, hsl(0,0,.8));
|
|
19
21
|
drawTextOverlay(this.icon, this.pos, 3);
|
|
20
22
|
}
|
|
@@ -22,14 +24,13 @@ class SoundButton extends EngineObject
|
|
|
22
24
|
|
|
23
25
|
function gameInit()
|
|
24
26
|
{
|
|
27
|
+
// create a grid of buttons with different sounds
|
|
25
28
|
new SoundButton(vec2(-6, 5),'💰', new Sound([,,1675,,.06,.24,1,1.82,,,837,.06]));
|
|
26
29
|
new SoundButton(vec2( 0, 5),'🥊', new Sound([,,925,.04,.3,.6,1,.3,,6.27,-184,.09,.17]));
|
|
27
30
|
new SoundButton(vec2( 6, 5),'✨', new Sound([,,539,0,.04,.29,1,1.92,,,567,.02,.02,,,,.04]));
|
|
28
|
-
|
|
29
31
|
new SoundButton(vec2(-6, 0),'🐁', new Sound([,.2,1e3,.02,,.01,2,,18,,475,.01,.01]));
|
|
30
32
|
new SoundButton(vec2( 0, 0),'🎹', new Sound([1.5,.5,270,,.1,,1,1.5,,,,,,,,.1,.01]));
|
|
31
|
-
new SoundButton(vec2( 6, 0),'🏌️', new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
|
|
32
|
-
|
|
33
|
+
new SoundButton(vec2( 6, 0),'🏌️', new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
|
|
33
34
|
new SoundButton(vec2(-6,-5),'🌊', new Sound([,.2,40,.5,,1.5,,11,,,,,,199]));
|
|
34
35
|
new SoundButton(vec2( 0,-5),'🛰️', new Sound([,.5,847,.02,.3,.9,1,1.67,,,-294,.04,.13,,,,.1]));
|
|
35
36
|
new SoundButton(vec2( 6,-5),'⚡', new Sound([,,471,,.09,.47,4,1.06,-6.7,,,,,.9,61,.1,,.82,.1]));
|
|
@@ -20,9 +20,9 @@ function gameInit()
|
|
|
20
20
|
|
|
21
21
|
// create objects
|
|
22
22
|
paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); // create player's paddle
|
|
23
|
-
new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)) //
|
|
24
|
-
new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)) //
|
|
25
|
-
new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)) //
|
|
23
|
+
new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)); // left wall
|
|
24
|
+
new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)); // right wall
|
|
25
|
+
new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)); // top wall
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function gameUpdate()
|
|
@@ -17,7 +17,7 @@ function gameRender()
|
|
|
17
17
|
drawEllipse(vec2(-5,5), 2, 1, 0, hsl(0,1,.5));
|
|
18
18
|
drawEllipse(vec2(5,5), 1, .5, 0, hsl(.55,1,.5));
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// rects and lines
|
|
21
21
|
drawRect(vec2(0,-5), vec2(13,2), hsl(.6,1,.5));
|
|
22
22
|
drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1));
|
|
23
23
|
drawLine(vec2(-5,-3), vec2(5,-7), .2, hsl(1,1,.5));
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
let spriteAtlas;
|
|
2
|
+
|
|
3
|
+
function gameInit()
|
|
4
|
+
{
|
|
5
|
+
// create a table of all sprites
|
|
6
|
+
const gameTile = (i, size=16)=> tile(i, size);
|
|
7
|
+
spriteAtlas =
|
|
8
|
+
{
|
|
9
|
+
circle: gameTile(0),
|
|
10
|
+
crate: gameTile(1),
|
|
11
|
+
icon: gameTile(2),
|
|
12
|
+
circleBig: gameTile(2, 128),
|
|
13
|
+
iconBig: gameTile(3, 128),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function gameRender()
|
|
18
|
+
{
|
|
19
|
+
drawRect(vec2(0,0), vec2(100), GRAY); // draw background
|
|
20
|
+
|
|
21
|
+
// draw a sprite from the atlas
|
|
22
|
+
let pos = vec2(Math.sin(time)*5,-3);// world position to draw
|
|
23
|
+
let angle = 0; // world space angle to draw the tile
|
|
24
|
+
let size = vec2(9); // world size of the tile
|
|
25
|
+
let mirror = 0; // should tile be mirrored?
|
|
26
|
+
let color = hsl(0,0,1); // color to multiply the tile by
|
|
27
|
+
let additiveColor = hsl(0,0,0,0); // color to add to
|
|
28
|
+
drawTile(pos, size, spriteAtlas.iconBig, color, angle, mirror, additiveColor);
|
|
29
|
+
|
|
30
|
+
// draw more sprites from the atlas
|
|
31
|
+
drawTile(vec2(-7,4), vec2(5), spriteAtlas.crate);
|
|
32
|
+
drawTile(vec2( 0,4), vec2(5), spriteAtlas.circle);
|
|
33
|
+
drawTile(vec2( 7,4), vec2(5), spriteAtlas.circleBig);
|
|
34
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function gameRender()
|
|
2
|
+
{
|
|
3
|
+
// draw text with built in font image system font
|
|
4
|
+
const font = new FontImage;
|
|
5
|
+
font.drawText('System Font Test', cameraPos.add(vec2(0,3)), .2, true);
|
|
6
|
+
|
|
7
|
+
// show every character in the system font
|
|
8
|
+
let s = '';
|
|
9
|
+
for(let i=32; i<128; ++i)
|
|
10
|
+
{
|
|
11
|
+
if (i%32 == 0)
|
|
12
|
+
s += '\n';
|
|
13
|
+
s += String.fromCharCode(i);
|
|
14
|
+
}
|
|
15
|
+
font.drawText(s, cameraPos, .1, true);
|
|
16
|
+
}
|
|
@@ -34,7 +34,7 @@ function gameUpdate()
|
|
|
34
34
|
{
|
|
35
35
|
// create particle emitter
|
|
36
36
|
const hue = rand();
|
|
37
|
-
|
|
37
|
+
const particleEmitter = new ParticleEmitter(
|
|
38
38
|
mousePos, 0, // emitPos, emitAngle
|
|
39
39
|
0, 0.1, 500, PI, // emitSize, emitTime, emitRate, emitCone
|
|
40
40
|
tile(0, 16), // tileIndex, tileSize
|
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class GameObject extends EngineObject
|
|
2
|
+
{
|
|
3
|
+
update()
|
|
4
|
+
{
|
|
5
|
+
this.renderOrder = -this.pos.y; // sort by y position
|
|
6
|
+
super.update();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
render()
|
|
10
|
+
{
|
|
11
|
+
// adjust draw postion to be at the bottom of the object
|
|
12
|
+
const pos = this.pos.add(vec2(0,this.size.y/2).rotate(this.angle));
|
|
13
|
+
drawTile(pos, this.size, this.tileInfo, this.color, this.angle);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class Player extends GameObject
|
|
18
|
+
{
|
|
19
|
+
update()
|
|
20
|
+
{
|
|
21
|
+
// apply movement controls
|
|
22
|
+
const moveInput = keyDirection().clampLength(1).scale(.2); // clamp and scale input
|
|
23
|
+
this.velocity = this.velocity.add(moveInput); // apply movement
|
|
24
|
+
|
|
25
|
+
super.update(); // call parent update function
|
|
26
|
+
cameraPos = this.pos.add(vec2(0,2)); // move camera with player
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
function gameInit()
|
|
32
|
+
{
|
|
33
|
+
// setup level
|
|
34
|
+
objectDefaultDamping = .7;
|
|
35
|
+
new Player(vec2(), vec2(3), tile(5), 0, RED);
|
|
36
|
+
|
|
37
|
+
// create background objects
|
|
38
|
+
for (let i = 1; i < 300; ++i)
|
|
39
|
+
new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, 0, hsl(.4,.3,rand(.1,.2),.8), -1e5);
|
|
40
|
+
|
|
41
|
+
// create world objects
|
|
42
|
+
for (let i = 1; i < 1e3; ++i)
|
|
43
|
+
new GameObject(randInCircle(7+i,7), vec2(rand(1,2),rand(4,9)), 0, 0, hsl(.1,.5,rand(.2,.3)));
|
|
44
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class TimerButton extends EngineObject
|
|
2
|
+
{
|
|
3
|
+
constructor(pos, time)
|
|
4
|
+
{
|
|
5
|
+
super(pos, vec2(5.5));
|
|
6
|
+
this.time = time;
|
|
7
|
+
this.timer = new Timer;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
update()
|
|
11
|
+
{
|
|
12
|
+
// start or stop the timer when clicked
|
|
13
|
+
if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
|
|
14
|
+
this.timer.isSet() ? this.timer.unset() : this.timer.set(this.time);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
render()
|
|
18
|
+
{
|
|
19
|
+
// get color based on timer state
|
|
20
|
+
this.color = this.timer.isSet() ? this.timer.active() ? BLUE : RED : GRAY;
|
|
21
|
+
|
|
22
|
+
// draw the button and timer text
|
|
23
|
+
drawRect(this.pos, this.size, this.color);
|
|
24
|
+
if (this.timer.isSet())
|
|
25
|
+
{
|
|
26
|
+
drawTextOverlay(this.timer.get().toFixed(1), this.pos.add(vec2(0,1)), 2);
|
|
27
|
+
const percent = this.timer.getPercent()*100|0;
|
|
28
|
+
drawTextOverlay(percent+'%', this.pos.add(vec2(0,-1)), 2);
|
|
29
|
+
}
|
|
30
|
+
else
|
|
31
|
+
drawTextOverlay('Click\nto set', this.pos, 2);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function gameInit()
|
|
36
|
+
{
|
|
37
|
+
// create some timer buttons
|
|
38
|
+
new TimerButton(vec2(-5, 0), 3);
|
|
39
|
+
new TimerButton(vec2( 5, 0), 0);
|
|
40
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class PhysicsObject extends EngineObject
|
|
2
|
+
{
|
|
3
|
+
constructor(pos, size, color)
|
|
4
|
+
{
|
|
5
|
+
super(pos, size, 0, 0, color);
|
|
6
|
+
this.setCollision(); // make object collide
|
|
7
|
+
this.mass = 0; // make object have static physics
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class Player extends PhysicsObject
|
|
12
|
+
{
|
|
13
|
+
constructor(pos)
|
|
14
|
+
{
|
|
15
|
+
super(pos, vec2(2), RED);
|
|
16
|
+
this.mass = 1; // make object have dynamic physics
|
|
17
|
+
this.renderOrder = 1; // render player on top of other objects
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
update()
|
|
21
|
+
{
|
|
22
|
+
// apply movement controls
|
|
23
|
+
const moveInput = keyDirection().clampLength(1).scale(.2); // clamp and scale input
|
|
24
|
+
this.velocity = this.velocity.add(moveInput); // apply movement
|
|
25
|
+
|
|
26
|
+
super.update(); // call parent update function
|
|
27
|
+
cameraPos = this.pos; // move camera with player
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function gameInit()
|
|
32
|
+
{
|
|
33
|
+
// setup level
|
|
34
|
+
objectDefaultDamping = .7;
|
|
35
|
+
new Player();
|
|
36
|
+
|
|
37
|
+
// create background objects
|
|
38
|
+
for (let i = 1; i < 300; ++i)
|
|
39
|
+
new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, rand(), hsl(.4,.5,rand(.2)));
|
|
40
|
+
|
|
41
|
+
// create foreground objects
|
|
42
|
+
for (let i = 1; i < 300; ++i)
|
|
43
|
+
new PhysicsObject(randInCircle(7+i,7), vec2(rand(4,9),rand(4,9)), hsl(0,0,rand(.8,1)));
|
|
44
|
+
}
|
package/examples/starter/game.js
CHANGED
|
@@ -70,9 +70,9 @@ function gameInit()
|
|
|
70
70
|
tile(0, 16), // tileIndex, tileSize
|
|
71
71
|
hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
|
|
72
72
|
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
73
|
-
2, .2, .2, .1, .05,
|
|
74
|
-
.99, 1, 1, PI,
|
|
75
|
-
.05, .
|
|
73
|
+
2, .2, .2, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
74
|
+
.99, 1, 1, PI, // damping, angleDamping, gravityScale, cone
|
|
75
|
+
.05, .5, true, true // fadeRate, randomness, collide, additive
|
|
76
76
|
);
|
|
77
77
|
particleEmitter.elasticity = .3; // bounce when it collides
|
|
78
78
|
particleEmitter.trailScale = 2; // stretch in direction of motion
|
|
@@ -7,18 +7,18 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../src/engineDebug.js?
|
|
11
|
-
<script src=../../src/engineUtilities.js?
|
|
12
|
-
<script src=../../src/engineSettings.js?
|
|
13
|
-
<script src=../../src/engineObject.js?
|
|
14
|
-
<script src=../../src/engineDraw.js?
|
|
15
|
-
<script src=../../src/engineInput.js?
|
|
16
|
-
<script src=../../src/engineAudio.js?
|
|
17
|
-
<script src=../../src/engineTileLayer.js?
|
|
18
|
-
<script src=../../src/engineParticles.js?
|
|
19
|
-
<script src=../../src/engineMedals.js?
|
|
20
|
-
<script src=../../src/engineWebGL.js?
|
|
21
|
-
<script src=../../src/engine.js?
|
|
10
|
+
<script src=../../src/engineDebug.js?1117></script>
|
|
11
|
+
<script src=../../src/engineUtilities.js?1117></script>
|
|
12
|
+
<script src=../../src/engineSettings.js?1117></script>
|
|
13
|
+
<script src=../../src/engineObject.js?1117></script>
|
|
14
|
+
<script src=../../src/engineDraw.js?1117></script>
|
|
15
|
+
<script src=../../src/engineInput.js?1117></script>
|
|
16
|
+
<script src=../../src/engineAudio.js?1117></script>
|
|
17
|
+
<script src=../../src/engineTileLayer.js?1117></script>
|
|
18
|
+
<script src=../../src/engineParticles.js?1117></script>
|
|
19
|
+
<script src=../../src/engineMedals.js?1117></script>
|
|
20
|
+
<script src=../../src/engineWebGL.js?1117></script>
|
|
21
|
+
<script src=../../src/engine.js?1117></script>
|
|
22
22
|
|
|
23
23
|
<!-- Add your game scripts here -->
|
|
24
|
-
<script src=game.js?
|
|
24
|
+
<script src=game.js?1117></script>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.min.js?
|
|
10
|
+
<script src=../../dist/littlejs.min.js?1117></script>
|
|
11
11
|
<script>
|
|
12
12
|
|
|
13
13
|
/*
|
|
@@ -161,6 +161,6 @@ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, [ti
|
|
|
161
161
|
|
|
162
162
|
///////////////////////////////////////////////////////////////////////////////
|
|
163
163
|
// music - Depp Loop
|
|
164
|
-
const music = new Music([[[,0,
|
|
164
|
+
const music = new Music([[[.6,0,76,,,1,1,.5,,,,,.1,,,.06,,.5,.2,,-700],[,0,43,.01,,.2,2,,,,,,,,,,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
|
|
165
165
|
|
|
166
166
|
</script>
|
|
@@ -17,11 +17,15 @@ let uiRoot, uiMenu;
|
|
|
17
17
|
const getMenuVisible =()=> uiMenu.visible;
|
|
18
18
|
const setMenuVisible =(visible)=> uiMenu.visible = visible;
|
|
19
19
|
|
|
20
|
+
// use a fixed size canvas
|
|
21
|
+
canvasFixedSize = vec2(1920, 1080); // 1080p
|
|
22
|
+
canvasPixelated = false;
|
|
23
|
+
|
|
20
24
|
function createUI()
|
|
21
25
|
{
|
|
22
26
|
// setup root to attach all ui elements to
|
|
23
27
|
uiRoot = new UIObject();
|
|
24
|
-
const uiInfo = new UIText(vec2(0,
|
|
28
|
+
const uiInfo = new UIText(vec2(0,90), vec2(1e3, 70),
|
|
25
29
|
'LittleJS UI System Example\nM = Toggle menu');
|
|
26
30
|
uiInfo.textColor = WHITE;
|
|
27
31
|
uiInfo.lineWidth = 8;
|
|
@@ -31,6 +35,7 @@ function createUI()
|
|
|
31
35
|
uiMenu = new UIObject(vec2(0,450));
|
|
32
36
|
uiRoot.addChild(uiMenu);
|
|
33
37
|
const uiBackground = new UIObject(vec2(0,0), vec2(450,580));
|
|
38
|
+
uiBackground.lineWidth = 8;
|
|
34
39
|
uiMenu.addChild(uiBackground);
|
|
35
40
|
|
|
36
41
|
// example large text
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?
|
|
10
|
+
<script src=../../dist/littlejs.js?1117></script>
|
|
11
11
|
|
|
12
12
|
<!-- Add your game scripts here -->
|
|
13
|
-
<script src=../../plugins/uiSystem.js?
|
|
14
|
-
<script src=game.js?
|
|
13
|
+
<script src=../../plugins/uiSystem.js?1117></script>
|
|
14
|
+
<script src=game.js?1117></script>
|
package/package.json
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Copyright (c) 2006-2010 Erin Catto http://www.gphysics.com
|
|
2
|
+
|
|
3
|
+
This software is provided 'as-is', without any express or implied
|
|
4
|
+
warranty. In no event will the authors be held liable for any damages
|
|
5
|
+
arising from the use of this software.
|
|
6
|
+
|
|
7
|
+
Permission is granted to anyone to use this software for any purpose,
|
|
8
|
+
including commercial applications, and to alter it and redistribute it
|
|
9
|
+
freely, subject to the following restrictions:
|
|
10
|
+
|
|
11
|
+
1. The origin of this software must not be misrepresented; you must not
|
|
12
|
+
claim that you wrote the original software. If you use this software
|
|
13
|
+
in a product, an acknowledgment in the product documentation would be
|
|
14
|
+
appreciated but is not required.
|
|
15
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
|
16
|
+
misrepresented as being the original software.
|
|
17
|
+
3. This notice may not be removed or altered from any source distribution.
|
package/plugins/uiSystem.js
CHANGED
|
@@ -246,7 +246,8 @@ class UICheckbox extends UIObject
|
|
|
246
246
|
}
|
|
247
247
|
render()
|
|
248
248
|
{
|
|
249
|
-
|
|
249
|
+
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
250
|
+
drawUIRect(this.pos, this.size, color, this.lineWidth, this.lineColor);
|
|
250
251
|
if (this.checked)
|
|
251
252
|
{
|
|
252
253
|
// draw an X if checked
|
package/reference.md
CHANGED
|
@@ -224,6 +224,7 @@ soundDefaultTaper = .7 // Default range percent to taper off sound (0-1)
|
|
|
224
224
|
keyIsDown(key) // Is key down?
|
|
225
225
|
keyWasPressed(key) // Was key pressed this frame?
|
|
226
226
|
keyWasReleased(key) // Was key released this frame?
|
|
227
|
+
keyDirection() // Get input vector from arrow keys or wasd
|
|
227
228
|
|
|
228
229
|
// Mouse / Touch
|
|
229
230
|
mousePos // World space mouse position
|
|
@@ -406,4 +407,4 @@ showWatermark // True if watermark with FPS should be show
|
|
|
406
407
|
|
|
407
408
|
[LittleJS Engine](https://github.com/KilledByAPixel/LittleJS) Copyright 2021 Frank Force
|
|
408
409
|
|
|
409
|
-

|
|
410
|
+

|
package/src/engine.js
CHANGED
package/src/engineDebug.js
CHANGED
|
@@ -162,6 +162,10 @@ function debugText(text, pos, size=1, color='#fff', time=0, angle=0, font='monos
|
|
|
162
162
|
* @memberof Debug */
|
|
163
163
|
function debugClear() { debugPrimitives = []; }
|
|
164
164
|
|
|
165
|
+
/** Trigger debug system to take a screenshot
|
|
166
|
+
* @memberof Debug */
|
|
167
|
+
function debugScreenshot() { debugTakeScreenshot = 1; }
|
|
168
|
+
|
|
165
169
|
/** Save a canvas to disk
|
|
166
170
|
* @param {HTMLCanvasElement} canvas
|
|
167
171
|
* @param {String} [filename]
|
|
@@ -235,7 +239,7 @@ function debugUpdate()
|
|
|
235
239
|
if (keyWasPressed('Digit4'))
|
|
236
240
|
debugRaycast = !debugRaycast;
|
|
237
241
|
if (keyWasPressed('Digit5'))
|
|
238
|
-
|
|
242
|
+
debugScreenshot();
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
245
|
|
package/src/engineDraw.js
CHANGED
|
@@ -458,7 +458,10 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
|
|
|
458
458
|
context.lineJoin = 'round';
|
|
459
459
|
|
|
460
460
|
pos = pos.copy();
|
|
461
|
-
|
|
461
|
+
|
|
462
|
+
const lines = (text+'').split('\n');
|
|
463
|
+
pos.y -= (lines.length-1) * size/2; // center text vertically
|
|
464
|
+
lines.forEach(line=>
|
|
462
465
|
{
|
|
463
466
|
lineWidth && context.strokeText(line, pos.x, pos.y, maxWidth);
|
|
464
467
|
context.fillText(line, pos.x, pos.y, maxWidth);
|
package/src/engineExport.js
CHANGED
|
@@ -19,6 +19,7 @@ export {
|
|
|
19
19
|
engineInit,
|
|
20
20
|
engineObjectsUpdate,
|
|
21
21
|
engineObjectsDestroy,
|
|
22
|
+
engineObjectsCollect,
|
|
22
23
|
engineObjectsCallback,
|
|
23
24
|
engineObjectsRaycast,
|
|
24
25
|
engineAddPlugin,
|
|
@@ -38,6 +39,7 @@ export {
|
|
|
38
39
|
debugOverlap,
|
|
39
40
|
debugText,
|
|
40
41
|
debugClear,
|
|
42
|
+
debugScreenshot,
|
|
41
43
|
debugSaveCanvas,
|
|
42
44
|
debugSaveText,
|
|
43
45
|
debugSaveDataURL,
|
|
@@ -236,6 +238,7 @@ export {
|
|
|
236
238
|
keyIsDown,
|
|
237
239
|
keyWasPressed,
|
|
238
240
|
keyWasReleased,
|
|
241
|
+
keyDirection,
|
|
239
242
|
clearInput,
|
|
240
243
|
mouseIsDown,
|
|
241
244
|
mouseWasPressed,
|
package/src/engineInput.js
CHANGED
|
@@ -43,6 +43,15 @@ function keyWasReleased(key, device=0)
|
|
|
43
43
|
return inputData[device] && !!(inputData[device][key] & 4);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/** Returns input vector from arrow keys or WASD if enabled
|
|
47
|
+
* @return {Vector2}
|
|
48
|
+
* @memberof Input */
|
|
49
|
+
function keyDirection(up='ArrowUp', down='ArrowDown', left='ArrowLeft', right='ArrowRight')
|
|
50
|
+
{
|
|
51
|
+
const k = (key)=> keyIsDown(key) ? 1 : 0;
|
|
52
|
+
return vec2(k(right) - k(left), k(up) - k(down));
|
|
53
|
+
}
|
|
54
|
+
|
|
46
55
|
/** Clears all input
|
|
47
56
|
* @memberof Input */
|
|
48
57
|
function clearInput() { inputData = [[]]; touchGamepadButtons = []; }
|
|
@@ -126,9 +135,9 @@ function gamepadStick(stick, gamepad=0)
|
|
|
126
135
|
{ return gamepadStickData[gamepad] ? gamepadStickData[gamepad][stick] || vec2() : vec2(); }
|
|
127
136
|
|
|
128
137
|
///////////////////////////////////////////////////////////////////////////////
|
|
129
|
-
// Input
|
|
138
|
+
// Input system functions called automatically by engine
|
|
130
139
|
|
|
131
|
-
//
|
|
140
|
+
// input is stored as a bit field for each key: 1 = isDown, 2 = wasPressed, 4 = wasReleased
|
|
132
141
|
// mouse and keyboard are stored together in device 0, gamepads are in devices > 0
|
|
133
142
|
let inputData = [[]];
|
|
134
143
|
|
|
@@ -158,9 +167,6 @@ function inputUpdatePost()
|
|
|
158
167
|
mouseWheel = 0;
|
|
159
168
|
}
|
|
160
169
|
|
|
161
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
162
|
-
// Input event handlers
|
|
163
|
-
|
|
164
170
|
function inputInit()
|
|
165
171
|
{
|
|
166
172
|
if (headlessMode) return;
|
|
@@ -203,11 +209,11 @@ function inputInit()
|
|
|
203
209
|
|
|
204
210
|
isUsingGamepad = false;
|
|
205
211
|
inputData[0][e.button] = 3;
|
|
206
|
-
mousePosScreen =
|
|
212
|
+
mousePosScreen = mouseEventToScreen(e);
|
|
207
213
|
e.button && e.preventDefault();
|
|
208
214
|
}
|
|
209
215
|
onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
|
|
210
|
-
onmousemove = (e)=> mousePosScreen =
|
|
216
|
+
onmousemove = (e)=> mousePosScreen = mouseEventToScreen(e);
|
|
211
217
|
onwheel = (e)=> mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
|
|
212
218
|
oncontextmenu = (e)=> false; // prevent right click menu
|
|
213
219
|
onblur = (e) => clearInput(); // reset input when focus is lost
|
|
@@ -218,14 +224,12 @@ function inputInit()
|
|
|
218
224
|
}
|
|
219
225
|
|
|
220
226
|
// convert a mouse or touch event position to screen space
|
|
221
|
-
function
|
|
227
|
+
function mouseEventToScreen(mousePos)
|
|
222
228
|
{
|
|
223
|
-
if (!mainCanvas || headlessMode)
|
|
224
|
-
return vec2(); // fix bug that can occur if user clicks before page loads
|
|
225
|
-
|
|
226
229
|
const rect = mainCanvas.getBoundingClientRect();
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
const px = percent(mousePos.x, rect.left, rect.right);
|
|
231
|
+
const py = percent(mousePos.y, rect.top, rect.bottom);
|
|
232
|
+
return vec2(px*mainCanvas.width, py*mainCanvas.height);
|
|
229
233
|
}
|
|
230
234
|
|
|
231
235
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -380,7 +384,7 @@ function touchInputInit()
|
|
|
380
384
|
{
|
|
381
385
|
// set event pos and pass it along
|
|
382
386
|
const p = vec2(e.touches[0].clientX, e.touches[0].clientY);
|
|
383
|
-
mousePosScreen =
|
|
387
|
+
mousePosScreen = mouseEventToScreen(p);
|
|
384
388
|
wasTouching ? isUsingGamepad = touchGamepadEnable : inputData[0][button] = 3;
|
|
385
389
|
}
|
|
386
390
|
else if (wasTouching)
|
|
@@ -428,7 +432,7 @@ function touchInputInit()
|
|
|
428
432
|
// check each touch point
|
|
429
433
|
for (const touch of e.touches)
|
|
430
434
|
{
|
|
431
|
-
const touchPos =
|
|
435
|
+
const touchPos = mouseEventToScreen(vec2(touch.clientX, touch.clientY));
|
|
432
436
|
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
433
437
|
{
|
|
434
438
|
// virtual analog stick
|
package/src/engineObject.js
CHANGED
|
@@ -338,19 +338,19 @@ class EngineObject
|
|
|
338
338
|
|
|
339
339
|
/** Convert from local space to world space
|
|
340
340
|
* @param {Vector2} pos - local space point */
|
|
341
|
-
localToWorld(pos) { return this.pos.add(pos.rotate(
|
|
341
|
+
localToWorld(pos) { return this.pos.add(pos.rotate(this.angle)); }
|
|
342
342
|
|
|
343
343
|
/** Convert from world space to local space
|
|
344
344
|
* @param {Vector2} pos - world space point */
|
|
345
|
-
worldToLocal(pos) { return pos.subtract(this.pos).rotate(this.angle); }
|
|
345
|
+
worldToLocal(pos) { return pos.subtract(this.pos).rotate(-this.angle); }
|
|
346
346
|
|
|
347
347
|
/** Convert from local space to world space for a vector (rotation only)
|
|
348
348
|
* @param {Vector2} vec - local space vector */
|
|
349
|
-
localToWorldVector(vec) { return vec.rotate(this.angle); }
|
|
349
|
+
localToWorldVector(vec) { return vec.rotate(-this.angle); }
|
|
350
350
|
|
|
351
351
|
/** Convert from world space to local space for a vector (rotation only)
|
|
352
352
|
* @param {Vector2} vec - world space vector */
|
|
353
|
-
worldToLocalVector(vec) { return vec.rotate(
|
|
353
|
+
worldToLocalVector(vec) { return vec.rotate(this.angle); }
|
|
354
354
|
|
|
355
355
|
/** Called to check if a tile collision should be resolved
|
|
356
356
|
* @param {Number} tileData - the value of the tile at the position
|