littlejsengine 1.12.6 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/littlejs.d.ts +387 -177
  2. package/dist/littlejs.esm.js +5934 -5294
  3. package/dist/littlejs.esm.min.js +4 -1
  4. package/dist/littlejs.js +5887 -5263
  5. package/dist/littlejs.min.js +4 -1
  6. package/dist/littlejs.release.js +5426 -4829
  7. package/examples/box2d/game.js +1 -1
  8. package/examples/box2d/gameObjects.js +7 -6
  9. package/examples/box2d/index.html +1 -1
  10. package/examples/box2d/scenes.js +7 -7
  11. package/examples/breakout/game.js +1 -1
  12. package/examples/breakout/gameObjects.js +2 -2
  13. package/examples/breakout/index.html +1 -1
  14. package/examples/breakoutTutorial/README.md +2 -2
  15. package/examples/breakoutTutorial/game.js +1 -1
  16. package/examples/breakoutTutorial/index.html +1 -1
  17. package/examples/empty/index.html +1 -1
  18. package/examples/htmlMenu/index.html +1 -1
  19. package/examples/index.html +396 -153
  20. package/examples/module/game.js +1 -1
  21. package/examples/module/index.html +1 -1
  22. package/examples/platformer/game.js +4 -4
  23. package/examples/platformer/gameCharacter.js +6 -6
  24. package/examples/platformer/gameEffects.js +74 -57
  25. package/examples/platformer/gameLevel.js +61 -70
  26. package/examples/platformer/gameObjects.js +4 -4
  27. package/examples/platformer/index.html +1 -1
  28. package/examples/puzzle/index.html +1 -1
  29. package/examples/shorts/base.html +23 -3
  30. package/examples/shorts/box2dCar.js +8 -12
  31. package/examples/shorts/flappyGame.js +52 -0
  32. package/examples/shorts/helloWorld.js +6 -3
  33. package/examples/shorts/hillGlideGame.js +56 -0
  34. package/examples/shorts/landerGame.js +32 -0
  35. package/examples/shorts/maze.js +47 -0
  36. package/examples/shorts/medals.js +42 -0
  37. package/examples/shorts/nineSlice.js +21 -0
  38. package/examples/shorts/piano.js +52 -0
  39. package/examples/shorts/platformer.js +24 -20
  40. package/examples/shorts/{pong.js → pongGame.js} +1 -1
  41. package/examples/shorts/raycasting.js +71 -0
  42. package/examples/shorts/slidingPuzzle.js +42 -0
  43. package/examples/shorts/spaceGame.js +56 -0
  44. package/examples/shorts/starfield.js +17 -0
  45. package/examples/shorts/tileLayer.js +3 -5
  46. package/examples/shorts/tiles.png +0 -0
  47. package/examples/shorts/tiltedView.js +8 -7
  48. package/examples/shorts/topDown.js +18 -26
  49. package/examples/shorts/uiSystem.js +4 -7
  50. package/examples/starter/build.bat +6 -1
  51. package/examples/starter/game.js +2 -2
  52. package/examples/starter/index.html +23 -13
  53. package/examples/stress/index.html +2 -3
  54. package/examples/style.css +136 -0
  55. package/examples/typescript/build.js +1 -2
  56. package/examples/typescript/game.js +2 -2
  57. package/examples/typescript/game.ts +1 -1
  58. package/examples/typescript/index.html +1 -1
  59. package/examples/uiSystem/game.js +8 -24
  60. package/examples/uiSystem/index.html +1 -1
  61. package/package.json +1 -1
  62. package/plugins/box2d.js +8 -8
  63. package/plugins/drawUtilities.js +126 -0
  64. package/plugins/newgrounds.js +1 -1
  65. package/plugins/pluginExport.js +7 -1
  66. package/plugins/postProcess.js +2 -2
  67. package/plugins/uiSystem.js +153 -65
  68. package/plugins/zzfxm.js +1 -1
  69. package/reference.md +10 -10
  70. package/src/engine.js +50 -29
  71. package/src/engineAudio.js +14 -5
  72. package/src/engineBuild.bat +6 -1
  73. package/src/engineBuild.js +20 -5
  74. package/src/engineDebug.js +53 -26
  75. package/src/engineDraw.js +108 -57
  76. package/src/engineExport.js +21 -9
  77. package/src/engineInput.js +109 -37
  78. package/src/engineObject.js +68 -67
  79. package/src/engineParticles.js +26 -9
  80. package/src/engineSettings.js +15 -16
  81. package/src/engineTileLayer.js +312 -153
  82. package/src/engineUtilities.js +182 -130
  83. package/src/engineWebGL.js +47 -36
@@ -1,8 +1,11 @@
1
1
  function gameRender()
2
2
  {
3
- // draw text
4
- drawText('Hello World', vec2(0,2), 3);
3
+ // draw background rect
4
+ drawRect(cameraPos, vec2(30), hsl(0,0,.2));
5
+
6
+ // draw text to the overlay canvas
7
+ drawTextOverlay('Hello World', vec2(0,3), 3);
5
8
 
6
9
  // draw a tile
7
- drawTile(vec2(0,-2), vec2(7), tile(3,128));
10
+ drawTile(vec2(Math.sin(time)*3,-2), vec2(7), tile(3,128));
8
11
  }
@@ -0,0 +1,56 @@
1
+ class Player extends EngineObject
2
+ {
3
+ constructor(pos)
4
+ {
5
+ super(pos, vec2(2), tile(9), 0, CYAN);
6
+ this.damping = 1; // disable damping
7
+ this.clampSpeed = false; // disable speed clamping
8
+ }
9
+
10
+ update()
11
+ {
12
+ super.update();
13
+
14
+ const h = getGroundHeight(this.pos.x);
15
+ if (this.pos.y < h + this.size.y/2)
16
+ {
17
+ // clamp to ground and reflect velocity
18
+ this.pos.y = h + this.size.y/2;
19
+ const n = vec2((h-getGroundHeight(this.pos.x+.1))/.1, 1).normalize();
20
+ this.velocity = this.velocity.reflect(n,0);
21
+ }
22
+
23
+ // apply movement controls
24
+ if (mouseIsDown(0) || keyIsDown('Space'))
25
+ this.applyAcceleration(vec2(0,-.05));
26
+ this.velocity.x = max(this.velocity.x,.4);
27
+ this.angle = this.velocity.angle() - PI/2;
28
+
29
+ // move camera with player
30
+ cameraPos = vec2(this.pos.x+9,5);
31
+ }
32
+ }
33
+
34
+ function getGroundHeight(x)
35
+ {
36
+ return Math.sin(x/4)*2 + Math.sin(x/17);
37
+ }
38
+
39
+ function gameInit()
40
+ {
41
+ gravity.y = -.01;
42
+ new Player(vec2(0,5));
43
+ }
44
+
45
+ function gameRender()
46
+ {
47
+ const h = 100, w = 20;
48
+ const pos = vec2(), size = vec2(.2,h), color = WHITE;
49
+ for (let x=cameraPos.x-w; x<cameraPos.x+w; x+=.1)
50
+ {
51
+ pos.x = x;
52
+ pos.y = getGroundHeight(x)-h/2;
53
+ color.setHSLA(.2+.2*wave(.2,1,x), .5, .5);
54
+ drawRect(pos, size, color);
55
+ }
56
+ }
@@ -0,0 +1,32 @@
1
+ class Player extends EngineObject
2
+ {
3
+ constructor(pos)
4
+ {
5
+ super(pos, vec2(1,2), tile(8), 0, RED);
6
+ this.setCollision(); // make object collide
7
+ }
8
+
9
+ update()
10
+ {
11
+ super.update();
12
+
13
+ // apply movement controls
14
+ this.applyAcceleration(keyDirection().scale(.002));
15
+ }
16
+ }
17
+
18
+ function gameInit()
19
+ {
20
+ // setup level
21
+ gravity.y = -.001;
22
+ new Player(vec2(0,4));
23
+
24
+ // create ground
25
+ for (let i=0, y=0; i<20; ++i)
26
+ {
27
+ y = (y + rand(1,-1)*4) * .5;
28
+ const o = new EngineObject(vec2(i*2-20, y-54), vec2(2, 99), 0, 0, hsl(0,0,.5+i%.29));
29
+ o.setCollision(); // make object collide
30
+ o.mass = 0; // make object have static physics
31
+ }
32
+ }
@@ -0,0 +1,47 @@
1
+ function generateMaze(size)
2
+ {
3
+ const maze = [], w = size.x, h = size.y;
4
+ maze[1 + w] = 1; // start point
5
+ for(let k=w*h*9|0; k--;)
6
+ {
7
+ // get a random position on odd coordinates
8
+ const jx = randInt(w/2-(w%2?0:2)|0)*2 + 1;
9
+ const jy = randInt(h/2-(h%2?1:2)|0)*2 + 1;
10
+ const j = jx + jy*w;
11
+
12
+ // get a random direction
13
+ const d = randSign() * (randBool() ? 1 : w);
14
+
15
+ // check if we are not the same line or column
16
+ if (j%w != (j+d*2)%w && (j/w|0) != ((j+d*2)/w|0))
17
+ continue;
18
+
19
+ // check if pos is open and the next 2 cells are closed
20
+ if (maze[j] && !maze[j+d] && !maze[j+d*2])
21
+ maze[j+d] = maze[j+d*2] = 1;
22
+ }
23
+ return maze;
24
+ }
25
+
26
+ function gameInit()
27
+ {
28
+ // generate maze data
29
+ const mazeSize = vec2(27,15);
30
+ const maze = generateMaze(mazeSize);
31
+
32
+ // create tile layer
33
+ const pos = vec2();
34
+ const tileLayer = new TileCollisionLayer(pos, mazeSize);
35
+ for (pos.x = tileLayer.size.x; pos.x--;)
36
+ for (pos.y = tileLayer.size.y; pos.y--;)
37
+ {
38
+ // check if tile should be solid
39
+ if (maze[pos.x + pos.y*mazeSize.x])
40
+ continue;
41
+
42
+ // set tile data
43
+ tileLayer.setData(pos, new TileLayerData(1));
44
+ }
45
+ tileLayer.redraw(); // redraw tile layer with new data
46
+ cameraPos = mazeSize.scale(.5); // center camera
47
+ }
@@ -0,0 +1,42 @@
1
+ // create example medals
2
+ const medal_openedExample = new Medal(0, 'Opened Example', 'You opened this example!');
3
+ const medal_leftClick = new Medal(1, 'Left Clicked', 'You left clicked!', '🐁');
4
+ const medal_rightClick = new Medal(2, 'Right Clicked', 'You right clicked!', '🐭');
5
+ const medal_spacePressed = new Medal(3, 'Pressed Spacebar', 'You pressed spacebar!', '🚀');
6
+
7
+ // setup medals
8
+ const saveName = 'Medals Example';
9
+ medalsInit(saveName);
10
+
11
+ // clear medals for testing
12
+ medalsForEach(medal=> medal.unlocked = false);
13
+ medal_openedExample.unlock();
14
+
15
+ function gameUpdate()
16
+ {
17
+ if (mouseWasPressed(0))
18
+ medal_leftClick.unlock();
19
+ if (mouseWasPressed(2))
20
+ medal_rightClick.unlock();
21
+ if (keyWasPressed('Space'))
22
+ medal_spacePressed.unlock();
23
+ }
24
+
25
+ function gameRender()
26
+ {
27
+ const size = 80;
28
+ let pos = mainCanvasSize.scale(.5).subtract(vec2(0,40));
29
+ drawTextScreen('Unlocked Medals', pos, size);
30
+
31
+ // show unlocked medals
32
+ let medalsCount = 0;
33
+ medalsForEach(medal=> medal.unlocked && medalsCount++);
34
+ pos = pos.add(vec2((1-medalsCount)*size/2, 100));
35
+ medalsForEach(medal=>
36
+ {
37
+ if (!medal.unlocked)
38
+ return;
39
+ medal.renderIcon(pos, size);
40
+ pos.x += size + 8;
41
+ });
42
+ }
@@ -0,0 +1,21 @@
1
+ function gameRender()
2
+ {
3
+ const nineSliceTile = tile(16);
4
+ const threeSliceTile = tile(19);
5
+
6
+ // draw nine slice with thin border and color
7
+ drawNineSlice(vec2(-7,4), vec2(13, 6), nineSliceTile, hsl(.1,.5,.9), .5);
8
+ drawTextOverlay('Nine Slice\nThin Border', vec2(-7,4), 1, BLACK);
9
+
10
+ // draw nine slice in screen space with thick border
11
+ drawNineSliceScreen(vec2(700,150), vec2(250), nineSliceTile);
12
+ drawTextScreen('Nine Slice\nScreen Space', vec2(700,150), 30, BLACK);
13
+
14
+ // draw three slice with thick border and additive color
15
+ drawThreeSlice(vec2(-7,-4), vec2(9, 7), threeSliceTile, WHITE, 2, hsl(.6,1,.5));
16
+ drawTextOverlay('Three Slice\nThick Border', vec2(-7,-4), 1, BLACK);
17
+
18
+ // draw three slice in screen space with thick border
19
+ drawThreeSliceScreen(vec2(700,400), vec2(400,150), threeSliceTile);
20
+ drawTextScreen('Three Slice\nScreen Space', vec2(700,400), 30, BLACK);
21
+ }
@@ -0,0 +1,52 @@
1
+ const pianoSound = new Sound([,0,220,,9]), keys = [];
2
+
3
+ class PianoKey extends EngineObject
4
+ {
5
+ constructor(pos, size, semitone, isWhite)
6
+ {
7
+ const keySize = 2;
8
+ size = size.scale(keySize);
9
+ pos = pos.scale(keySize).add(vec2(0,4-size.y/2));
10
+ super(pos, size, 0, 0, hsl(0,0,isWhite ? 1 : .3));
11
+ this.drawSize = size.subtract(vec2(.1,0));
12
+ this.semitone = semitone;
13
+ }
14
+ press()
15
+ {
16
+ if (!this.isDown)
17
+ pianoSound.playNote(this.semitone);
18
+ this.isDown = true;
19
+ }
20
+ release()
21
+ {
22
+ if (this.isDown)
23
+ pianoSound.stop(.2);
24
+ this.isDown = false;
25
+ }
26
+ render()
27
+ {
28
+ const color = this.isDown ? RED : this.color;
29
+ drawRect(this.pos, this.drawSize, color);
30
+ }
31
+ }
32
+
33
+ function gameInit()
34
+ {
35
+ // create piano keyboard
36
+ for(let i=15; i--;)
37
+ keys.unshift(new PianoKey(vec2(i-7,0), vec2(1,4), [0,2,4,5,7,9,11][i%7]+(i/7|0)*12, 1));
38
+ for(let i=10; i--;)
39
+ keys.unshift(new PianoKey(vec2([1,2,4,5,6][i%5]+(i/5|0)*7-7.5,0), vec2(1,2), [1,3,6,8,10][i%5]+(i/5|0)*12));
40
+ }
41
+
42
+ function gameUpdate()
43
+ {
44
+ // update state of piano keys
45
+ const pressedKey = keys.find(k=>k.isDown);
46
+ const newPressedKey = mouseIsDown(0) && keys.find(k=>isOverlapping(k.pos, k.size, mousePos));
47
+ if (newPressedKey != pressedKey)
48
+ {
49
+ pressedKey && pressedKey.release();
50
+ newPressedKey && newPressedKey.press();
51
+ }
52
+ }
@@ -1,31 +1,23 @@
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
1
+ class Player extends EngineObject
12
2
  {
13
3
  constructor(pos)
14
4
  {
15
- super(pos, vec2(2,4), RED);
16
- this.mass = 1; // make object have dynamic physics
5
+ super(pos, vec2(2,4), 0, 0, RED);
6
+ this.setCollision(); // make object collide
17
7
  }
18
8
 
19
9
  update()
20
10
  {
11
+ super.update();
12
+
21
13
  // apply movement controls
22
14
  const moveInput = keyDirection();
23
15
  this.velocity.x += moveInput.x * (this.groundObject ? .1: .01);
24
16
  if (this.groundObject && moveInput.y > 0)
25
17
  this.velocity.y = .9; // jump
26
18
 
27
- super.update(); // call parent update function
28
- cameraPos = vec2(this.pos.x, 9); // move camera with player
19
+ // move camera with player
20
+ cameraPos = vec2(this.pos.x, 9);
29
21
  }
30
22
  }
31
23
 
@@ -33,10 +25,22 @@ function gameInit()
33
25
  {
34
26
  // setup level
35
27
  gravity.y = -.05;
36
- new Player(vec2(0,4));
28
+ new Player(vec2(5,6));
37
29
 
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);
30
+ // create tile layer
31
+ const pos = vec2();
32
+ const tileLayer = new TileCollisionLayer(pos, vec2(256));
33
+ for (pos.x = tileLayer.size.x; pos.x--;)
34
+ for (pos.y = tileLayer.size.y; pos.y--;)
35
+ {
36
+ // check if tile should be solid
37
+ const levelHeight = pos.x<9 ? 2 : (pos.x/4|0)**3.1%7;
38
+ if (pos.y > levelHeight)
39
+ continue;
40
+
41
+ // set tile data
42
+ tileLayer.setData(pos, new TileLayerData(1));
43
+ tileLayer.setCollisionData(pos);
44
+ }
45
+ tileLayer.redraw(); // redraw tile layer with new data
42
46
  }
@@ -32,7 +32,7 @@ function gameUpdate()
32
32
  ball && ball.destroy(); // destroy old ball
33
33
  ball = new PhysicsObject(cameraPos); // create a ball
34
34
  ball.velocity = vec2(.2); // give ball some movement
35
- ball.elasticity = 1; // make ball bounce
35
+ ball.restitution = 1; // make ball bounce
36
36
  ball.mass = 1; // make ball have dynamic physics
37
37
  }
38
38
 
@@ -0,0 +1,71 @@
1
+ let playerPos = vec2(), playerAngle = 0;
2
+
3
+ // a simple function to generate a level
4
+ const levelTest = (X,Y)=> ((X|0)**3&(Y|0)**2)%30>5;
5
+
6
+ // cast a ray and return the distance to the first wall hit (0-1)
7
+ function raycast(pos, angle)
8
+ {
9
+ const maxDistance = 40, delta = .05;
10
+ const rayX = delta*Math.sin(angle);
11
+ const rayY = delta*Math.cos(angle);
12
+ let posX = pos.x, posY = pos.y;
13
+ for (let distance = 0; distance < maxDistance; distance += delta)
14
+ {
15
+ if (levelTest(posX, posY))
16
+ return distance/maxDistance;
17
+ posX += rayX;
18
+ posY += rayY;
19
+ }
20
+ return 1;
21
+ }
22
+
23
+ function gameUpdate()
24
+ {
25
+ // update camera angle with mouse pointer lock
26
+ if (mouseWasPressed(0))
27
+ pointerLockRequest();
28
+ if (keyWasPressed('Escape'))
29
+ pointerLockExit()
30
+ if (pointerLockIsActive() || isTouchDevice)
31
+ playerAngle += mouseDelta.x * .003;
32
+
33
+ // update player movement, prevent walking through walls
34
+ const velocity = keyDirection().scale(.1).rotate(playerAngle);
35
+ const newPos = playerPos.add(velocity);
36
+ if (!levelTest(newPos.x, newPos.y))
37
+ playerPos = newPos;
38
+ }
39
+
40
+ function gameRender()
41
+ {
42
+ {
43
+ // draw horizontal slizes to create floor and ceiling
44
+ const h = 9;
45
+ let pos = vec2(), size = vec2(39, .11), color = WHITE;
46
+ for (let y=-h; y<h; y+=.1)
47
+ {
48
+ const p = 1.01-abs(y/h)
49
+ pos.y = y;
50
+ color.setHSLA(.1, y>0?0:.5, .7-p*.7);
51
+ drawRect(pos, size, color);
52
+ }
53
+ }
54
+ {
55
+ // draw vertical slices to create the walls
56
+ const w = 20;
57
+ const pos = vec2(), size = vec2(.11), color = WHITE;
58
+ for (let x=-w; x<w; x+=.1)
59
+ {
60
+ const p = raycast(playerPos, playerAngle + x/w);
61
+ pos.x = x;
62
+ size.y = .4/p;
63
+ color.setHSLA(.6, .5, .7-p*.7);
64
+ drawRect(pos, size, color);
65
+ }
66
+ }
67
+ // draw instructions and pointer lock status
68
+ const instructions = pointerLockIsActive() ? 'Mouse Control Active - ESC To Exit' : 'Click To Enable Mouse Control';
69
+ if (!isTouchDevice)
70
+ drawTextScreen(instructions, vec2(mainCanvasSize.x/2, 50), 24, pointerLockIsActive() ? GREEN : WHITE);
71
+ }
@@ -0,0 +1,42 @@
1
+ const gridSize = vec2(4,3);
2
+ const pieceSize = vec2(5,4);
3
+ let emptyGridPos = vec2();
4
+
5
+ class PuzzlePiece extends EngineObject
6
+ {
7
+ constructor(gridPos, size)
8
+ {
9
+ const color = rgb(gridPos.x/(gridSize.x-1), gridPos.y/(gridSize.y-1), 1);
10
+ super(gridPos.multiply(size), size, 0, 0, color);
11
+ this.gridPos = gridPos;
12
+ this.text = gridPos.x + gridPos.y*gridSize.x;
13
+ }
14
+
15
+ update()
16
+ {
17
+ if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
18
+ if (abs(this.gridPos.x-emptyGridPos.x) + abs(this.gridPos.y-emptyGridPos.y) == 1)
19
+ {
20
+ // swap with empty space when clicked on
21
+ this.pos = emptyGridPos.multiply(this.size);
22
+ [emptyGridPos, this.gridPos] = [this.gridPos, emptyGridPos];
23
+ }
24
+ }
25
+
26
+ render()
27
+ {
28
+ super.render();
29
+ drawTextOverlay(this.text, this.pos, 2.5, BLACK);
30
+ }
31
+ }
32
+
33
+ function gameInit()
34
+ {
35
+ // create puzzle pieces
36
+ for(let x=gridSize.x; x--;)
37
+ for(let y=gridSize.y; y--;)
38
+ (x||y) && new PuzzlePiece(vec2(x,y), pieceSize);
39
+
40
+ // center camera on grid
41
+ cameraPos = gridSize.subtract(vec2(1)).multiply(pieceSize).scale(.5);
42
+ }
@@ -0,0 +1,56 @@
1
+ class Player extends EngineObject
2
+ {
3
+ constructor(pos)
4
+ {
5
+ super(pos, vec2(1,2), tile(8), 0, CYAN);
6
+ this.damping = .97;
7
+ this.angleDamping = .95;
8
+ this.shootTimer = new Timer;
9
+ }
10
+
11
+ update()
12
+ {
13
+ super.update();
14
+
15
+ // space ship controls
16
+ const moveInput = keyDirection();
17
+ this.applyAngularAcceleration(moveInput.x * .005);
18
+ this.applyAcceleration(vec2().setAngle(this.angle, moveInput.y*.02));
19
+ if (!this.shootTimer.active() && (keyIsDown('Space') || mouseIsDown(0)))
20
+ {
21
+ // shoot bullet
22
+ const pos = this.pos.add(vec2(0,1).rotate(cameraAngle));
23
+ const bullet = new EngineObject(pos, vec2(.2,.5), 0, this.angle, YELLOW);
24
+ bullet.velocity = this.velocity.add(vec2(0,.5).rotate(this.angle));
25
+ this.shootTimer.set(.1);
26
+ }
27
+
28
+ // move camera with player
29
+ cameraPos = this.pos;
30
+ cameraAngle = this.angle;
31
+ }
32
+ }
33
+
34
+ function gameInit()
35
+ {
36
+ new Player(vec2(0,4));
37
+ }
38
+
39
+ function gameRender()
40
+ {
41
+ // draw wrapped starfield with parallax
42
+ const range = 32, halfRange = range/2;
43
+
44
+ // precreate variables to avoid overhead
45
+ const pos = vec2(), size = vec2(), color = WHITE;
46
+ for (let i=1e3; i--;)
47
+ {
48
+ // use math to generate random star positions
49
+ const parallax = i%.13-1;
50
+ pos.x = mod(i**2.1 + cameraPos.x*parallax, range) + cameraPos.x - halfRange;
51
+ pos.y = mod(i**3.1 + cameraPos.y*parallax, range) + cameraPos.y - halfRange;
52
+ size.x = size.y = i%.07+.03;
53
+ color.a = .1+i%.9;
54
+ drawRect(pos, size, color);
55
+ }
56
+ }
@@ -0,0 +1,17 @@
1
+ function gameRender()
2
+ {
3
+ setBlendMode(1);
4
+ // precreate variables to avoid overhead
5
+ const pos = vec2(), size = vec2(), color = WHITE;
6
+ for(let i=2e3; i--;)
7
+ {
8
+ // use math to generate random star positions
9
+ const offset = time*(9+i**2.1%15) + i**2.3;
10
+ pos.x = offset%70-35;
11
+ pos.y = i/120-8;
12
+ size.x = size.y = i%.11+.07;
13
+ color.setHSLA(0, 0, Math.sin(i)**4);
14
+ drawRect(pos, size, color);
15
+ }
16
+ setBlendMode(0);
17
+ }
@@ -3,11 +3,9 @@ function gameInit()
3
3
  cameraPos = vec2(16); // setup camera
4
4
  gravity.y = -.01; // enable gravity
5
5
 
6
- // create tile collision and visible tile layer
6
+ // create tile layer
7
7
  const pos = vec2();
8
8
  const tileLayer = new TileCollisionLayer(pos, vec2(32));
9
-
10
- // init the tile layer
11
9
  for (pos.x = tileLayer.size.x; pos.x--;)
12
10
  for (pos.y = tileLayer.size.y; pos.y--;)
13
11
  {
@@ -18,7 +16,7 @@ function gameInit()
18
16
  // set tile data
19
17
  const tileIndex = 1;
20
18
  const direction = randInt(4)
21
- const mirror = !randInt(2);
19
+ const mirror = randBool();
22
20
  const color = randColor(WHITE, hsl(0,0,.2));
23
21
  const data = new TileLayerData(tileIndex, direction, mirror, color);
24
22
  tileLayer.setData(pos, data);
@@ -43,7 +41,7 @@ function gameUpdate()
43
41
  .99, 1, 1, PI, // damping, angleDamping, gravityScale, cone
44
42
  .05, .8, true, false // fadeRate, randomness, collide, additive
45
43
  );
46
- particleEmitter.elasticity = .5; // bounce when it collides
44
+ particleEmitter.restitution = .5; // bounce when it collides
47
45
  particleEmitter.trailScale = 2; // stretch in direction of motion
48
46
  }
49
47
  }
Binary file
@@ -18,16 +18,17 @@ class Player extends GameObject
18
18
  {
19
19
  update()
20
20
  {
21
+ super.update();
22
+
21
23
  // 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
+ const moveInput = keyDirection().clampLength(1).scale(.2);
25
+ this.velocity = this.velocity.add(moveInput);
24
26
 
25
- super.update(); // call parent update function
26
- cameraPos = this.pos.add(vec2(0,2)); // move camera with player
27
+ // move camera with player
28
+ cameraPos = this.pos.add(vec2(0,2));
27
29
  }
28
30
  }
29
31
 
30
-
31
32
  function gameInit()
32
33
  {
33
34
  // setup level
@@ -35,10 +36,10 @@ function gameInit()
35
36
  new Player(vec2(), vec2(3), tile(5), 0, RED);
36
37
 
37
38
  // create background objects
38
- for (let i = 1; i < 300; ++i)
39
+ for (let i=1; i<300; ++i)
39
40
  new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, 0, hsl(.4,.3,rand(.1,.2),.8), -1e5);
40
41
 
41
42
  // create world objects
42
- for (let i = 1; i < 1e3; ++i)
43
+ for (let i=1; i<1e3; ++i)
43
44
  new GameObject(randInCircle(7+i,7), vec2(rand(1,2),rand(4,9)), 0, 0, hsl(.1,.5,rand(.2,.3)));
44
45
  }
@@ -1,30 +1,22 @@
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
1
+ class Player extends EngineObject
12
2
  {
13
3
  constructor(pos)
14
4
  {
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
5
+ super(pos, vec2(2), tile(5), 0, RED);
6
+ this.setCollision(); // make object collide
7
+ this.renderOrder = 1; // render player on top
18
8
  }
19
9
 
20
10
  update()
21
11
  {
12
+ super.update();
13
+
22
14
  // apply movement controls
23
- const moveInput = keyDirection().clampLength(1).scale(.2); // clamp and scale input
24
- this.velocity = this.velocity.add(moveInput); // apply movement
15
+ const moveInput = keyDirection().clampLength(1).scale(.2);
16
+ this.velocity = this.velocity.add(moveInput);
25
17
 
26
- super.update(); // call parent update function
27
- cameraPos = this.pos; // move camera with player
18
+ // move camera with player
19
+ cameraPos = this.pos;
28
20
  }
29
21
  }
30
22
 
@@ -32,13 +24,13 @@ function gameInit()
32
24
  {
33
25
  // setup level
34
26
  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)));
27
+ new Player;
40
28
 
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)));
29
+ // create collision objects
30
+ for (let i=300; i--;)
31
+ {
32
+ const o = new EngineObject(randInCircle(15+i,7), vec2(rand(4,9),rand(4,9)), 0, 0, hsl(0,0,rand(.8,1)));
33
+ o.setCollision(); // make object collide
34
+ o.mass = 0; // make object have static physics
35
+ }
44
36
  }