littlejsengine 1.18.4 → 1.18.8

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 (176) hide show
  1. package/COPYRIGHT.txt +38 -0
  2. package/FAQ.md +633 -0
  3. package/README.md +19 -1
  4. package/dist/littlejs.d.ts +354 -55
  5. package/dist/littlejs.esm.js +1531 -489
  6. package/dist/littlejs.esm.min.js +1 -1
  7. package/dist/littlejs.js +1499 -476
  8. package/dist/littlejs.min.js +1 -1
  9. package/dist/littlejs.release.js +1493 -470
  10. package/package.json +8 -1
  11. package/plugins/box2d.js +32 -7
  12. package/{src/engineMedals.js → plugins/medalSystem.js} +248 -196
  13. package/plugins/pathFinder.js +758 -0
  14. package/plugins/pluginExport.js +19 -0
  15. package/plugins/{tween.js → tweenSystem.js} +7 -7
  16. package/plugins/uiSystem.js +186 -25
  17. package/src/engine.js +2 -141
  18. package/src/engineAudio.js +3 -3
  19. package/src/engineBuild.mjs +4 -2
  20. package/src/engineDebug.js +7 -7
  21. package/src/engineDraw.js +26 -8
  22. package/src/engineExport.js +13 -13
  23. package/src/engineInput.js +8 -8
  24. package/src/engineLogo.js +146 -0
  25. package/src/engineMath.js +15 -6
  26. package/src/engineObject.js +11 -5
  27. package/src/engineParticles.js +6 -3
  28. package/src/engineRelease.js +1 -1
  29. package/src/engineSettings.js +0 -47
  30. package/src/engineUtilities.js +13 -8
  31. package/src/engineWebGL.js +34 -7
  32. package/src/jsconfig.json +3 -1
  33. package/.github/workflows/test.yml +0 -17
  34. package/AI.md +0 -173
  35. package/CLAUDE.md +0 -1
  36. package/examples/box2d/game.js +0 -192
  37. package/examples/box2d/gameObjects.js +0 -564
  38. package/examples/box2d/index.html +0 -9
  39. package/examples/box2d/scenes.js +0 -194
  40. package/examples/box2d/tiles.png +0 -0
  41. package/examples/breakout/game.js +0 -175
  42. package/examples/breakout/gameObjects.js +0 -147
  43. package/examples/breakout/index.html +0 -8
  44. package/examples/breakout/tiles.png +0 -0
  45. package/examples/breakoutTutorial/README.md +0 -521
  46. package/examples/breakoutTutorial/game.js +0 -191
  47. package/examples/breakoutTutorial/images/1.png +0 -0
  48. package/examples/breakoutTutorial/images/10.png +0 -0
  49. package/examples/breakoutTutorial/images/11.png +0 -0
  50. package/examples/breakoutTutorial/images/2.png +0 -0
  51. package/examples/breakoutTutorial/images/3.png +0 -0
  52. package/examples/breakoutTutorial/images/4.png +0 -0
  53. package/examples/breakoutTutorial/images/5.png +0 -0
  54. package/examples/breakoutTutorial/images/6.png +0 -0
  55. package/examples/breakoutTutorial/images/7.png +0 -0
  56. package/examples/breakoutTutorial/images/8.png +0 -0
  57. package/examples/breakoutTutorial/images/9.png +0 -0
  58. package/examples/breakoutTutorial/index.html +0 -8
  59. package/examples/electron/build.mjs +0 -127
  60. package/examples/electron/electron.js +0 -35
  61. package/examples/electron/game.js +0 -54
  62. package/examples/electron/index.html +0 -13
  63. package/examples/electron/package.json +0 -5
  64. package/examples/electron/tiles.png +0 -0
  65. package/examples/empty/game.js +0 -51
  66. package/examples/empty/index.html +0 -5
  67. package/examples/empty/tiles.png +0 -0
  68. package/examples/favicon.png +0 -0
  69. package/examples/games.jpg +0 -0
  70. package/examples/htmlMenu/game.js +0 -82
  71. package/examples/htmlMenu/index.html +0 -45
  72. package/examples/htmlMenu/tiles.png +0 -0
  73. package/examples/index.html +0 -62
  74. package/examples/logo.png +0 -0
  75. package/examples/logo2.png +0 -0
  76. package/examples/module/build.mjs +0 -124
  77. package/examples/module/game.js +0 -132
  78. package/examples/module/index.html +0 -10
  79. package/examples/module/tiles.png +0 -0
  80. package/examples/particles/index.html +0 -426
  81. package/examples/particles/tiles.png +0 -0
  82. package/examples/platformer/data/gameLevelData.tmx +0 -143
  83. package/examples/platformer/data/gameLevelData.tsx +0 -4
  84. package/examples/platformer/game.js +0 -147
  85. package/examples/platformer/gameCharacter.js +0 -309
  86. package/examples/platformer/gameEffects.js +0 -278
  87. package/examples/platformer/gameLevel.js +0 -205
  88. package/examples/platformer/gameLevelData.json +0 -171
  89. package/examples/platformer/gameObjects.js +0 -378
  90. package/examples/platformer/gamePlayer.js +0 -35
  91. package/examples/platformer/index.html +0 -9
  92. package/examples/platformer/tiles.png +0 -0
  93. package/examples/platformer/tilesLevel.png +0 -0
  94. package/examples/puzzle/game.js +0 -331
  95. package/examples/puzzle/index.html +0 -8
  96. package/examples/puzzle/tiles.png +0 -0
  97. package/examples/screenshot.jpg +0 -0
  98. package/examples/shorts/animation.js +0 -18
  99. package/examples/shorts/base.html +0 -54
  100. package/examples/shorts/blending.js +0 -14
  101. package/examples/shorts/box2d.js +0 -51
  102. package/examples/shorts/box2dCar.js +0 -59
  103. package/examples/shorts/box2dPool.js +0 -107
  104. package/examples/shorts/box2dTileLayer.js +0 -48
  105. package/examples/shorts/cameraDrag.js +0 -22
  106. package/examples/shorts/clock.js +0 -21
  107. package/examples/shorts/colors.js +0 -25
  108. package/examples/shorts/debugDraw.js +0 -37
  109. package/examples/shorts/empty.js +0 -30
  110. package/examples/shorts/flappyGame.js +0 -55
  111. package/examples/shorts/fontImage.js +0 -17
  112. package/examples/shorts/fps.js +0 -90
  113. package/examples/shorts/helloWorld.js +0 -11
  114. package/examples/shorts/hillGlideGame.js +0 -63
  115. package/examples/shorts/input.js +0 -64
  116. package/examples/shorts/landerGame.js +0 -57
  117. package/examples/shorts/maze.js +0 -48
  118. package/examples/shorts/medals.js +0 -51
  119. package/examples/shorts/music.js +0 -78
  120. package/examples/shorts/musicPlayer.js +0 -137
  121. package/examples/shorts/nineSlice.js +0 -40
  122. package/examples/shorts/parallax.js +0 -72
  123. package/examples/shorts/particles.js +0 -28
  124. package/examples/shorts/piano.js +0 -44
  125. package/examples/shorts/platformer.js +0 -45
  126. package/examples/shorts/pongGame.js +0 -41
  127. package/examples/shorts/postProcess.js +0 -62
  128. package/examples/shorts/sequencer.js +0 -124
  129. package/examples/shorts/shader.js +0 -29
  130. package/examples/shorts/shapes.js +0 -21
  131. package/examples/shorts/slidingPuzzle.js +0 -52
  132. package/examples/shorts/song.mp3 +0 -0
  133. package/examples/shorts/sound.js +0 -36
  134. package/examples/shorts/spaceGame.js +0 -58
  135. package/examples/shorts/spriteAtlas.js +0 -31
  136. package/examples/shorts/starfield.js +0 -15
  137. package/examples/shorts/texture.js +0 -16
  138. package/examples/shorts/textureWrapped.js +0 -12
  139. package/examples/shorts/tileLayer.js +0 -48
  140. package/examples/shorts/tileRaycast.js +0 -39
  141. package/examples/shorts/tiles.png +0 -0
  142. package/examples/shorts/tiltedView.js +0 -63
  143. package/examples/shorts/timers.js +0 -53
  144. package/examples/shorts/topDown.js +0 -38
  145. package/examples/shorts/tween.js +0 -24
  146. package/examples/shorts/uiSystem.js +0 -61
  147. package/examples/shorts/video.webm +0 -0
  148. package/examples/shorts/videoPlayer.js +0 -34
  149. package/examples/shorts.js +0 -743
  150. package/examples/starter/build.bat +0 -7
  151. package/examples/starter/build.mjs +0 -126
  152. package/examples/starter/game.js +0 -137
  153. package/examples/starter/index.html +0 -35
  154. package/examples/starter/tiles.png +0 -0
  155. package/examples/stress/index.html +0 -173
  156. package/examples/style.css +0 -150
  157. package/examples/tweenSystem/game.js +0 -171
  158. package/examples/tweenSystem/index.html +0 -10
  159. package/examples/tweenSystem/tiles.png +0 -0
  160. package/examples/typescript/build.mjs +0 -60
  161. package/examples/typescript/game.js +0 -100
  162. package/examples/typescript/game.ts +0 -132
  163. package/examples/typescript/index.html +0 -10
  164. package/examples/typescript/tiles.png +0 -0
  165. package/examples/typescript/tsconfig.json +0 -17
  166. package/examples/uiSystem/game.js +0 -139
  167. package/examples/uiSystem/index.html +0 -10
  168. package/examples/uiSystem/tiles.png +0 -0
  169. package/jsconfig.json +0 -12
  170. package/plugins/desktop.ini +0 -2
  171. package/reference.md +0 -448
  172. package/test/math.test.mjs +0 -774
  173. package/test/setup.mjs +0 -22
  174. package/test/smoke.test.mjs +0 -274
  175. package/test/tween.test.mjs +0 -576
  176. package/test/util.test.mjs +0 -80
@@ -1,331 +0,0 @@
1
- /*
2
- Little Puzzle Game
3
- - A simple match 3 style puzzle game
4
- - Uses a high resolution texture
5
- - Tracks high score in local storage
6
- - Control with mouse or touch
7
- */
8
-
9
- 'use strict';
10
-
11
- // import LittleJS module
12
- import * as LJS from '../../dist/littlejs.esm.js';
13
- const {vec2, rgb, hsl, tile} = LJS;
14
-
15
- ///////////////////////////////////////////////////////////////////////////////
16
- // do not use pixelated rendering
17
- LJS.setCanvasPixelated(false);
18
- LJS.setTilesPixelated(false);
19
-
20
- const fallTime = .2;
21
- const cameraOffset = vec2(0,-.5);
22
- const backgroundColor = hsl(0,0,.2);
23
- const minMatchCount = 3;
24
- const highScoreKey = 'puzzleBestScore';
25
-
26
- // sound effects
27
- const sound_goodMove = new LJS.Sound([.4,.2,250,.04,,.04,,,1,,,,,3]);
28
- const sound_badMove = new LJS.Sound([,,700,,,.07,,,,3.7,,,,3,,,.1]);
29
- const sound_fall = new LJS.Sound([.2,,1900,,,.01,,1.4,,91,,,,,,,,,,.7]);
30
-
31
- let level, levelSize, levelFall, fallTimer, dragStartPos, comboCount, score, bestScore;
32
-
33
- ///////////////////////////////////////////////////////////////////////////////
34
- // tiles
35
- const tileColors =
36
- [
37
- rgb(1,0,0),
38
- rgb(1,1,1),
39
- rgb(1,1,0),
40
- rgb(0,1,0),
41
- rgb(0,.6,1),
42
- rgb(.8,0,1),
43
- rgb(.5,.5,.5),
44
- ];
45
- const tileTypeCount = tileColors.length;
46
-
47
- const getTile = (pos)=> level[pos.x + pos.y * levelSize.x];
48
- const setTile = (pos, data)=> level[pos.x + pos.y * levelSize.x] = data;
49
-
50
- ///////////////////////////////////////////////////////////////////////////////
51
- function gameReset()
52
- {
53
- // reset game objects
54
- LJS.engineObjectsDestroy();
55
-
56
- // randomize level
57
- level = [];
58
- const pos = vec2();
59
- for (pos.x = levelSize.x; pos.x--;)
60
- for (pos.y = levelSize.y; pos.y--;)
61
- setTile(pos, LJS.randInt(tileTypeCount));
62
-
63
- comboCount = score = 0;
64
- fallTimer = new LJS.Timer;
65
- }
66
-
67
- ///////////////////////////////////////////////////////////////////////////////
68
- function gameInit()
69
- {
70
- // setup canvas
71
- LJS.setCanvasFixedSize(vec2(1920, 1080)); // 1080p
72
- LJS.setCanvasClearColor(backgroundColor);
73
- // load high score
74
- bestScore = localStorage[highScoreKey] || 0;
75
-
76
- // setup game
77
- levelSize = vec2(12,6);
78
- LJS.setCameraPos(levelSize.scale(.5).add(cameraOffset));
79
- LJS.setCameraScale(900/levelSize.y);
80
- LJS.setGravity(vec2(0,-.004));
81
-
82
- // start a new game
83
- gameReset();
84
- }
85
-
86
- ///////////////////////////////////////////////////////////////////////////////
87
- function gameUpdate()
88
- {
89
- if (fallTimer.isSet())
90
- {
91
- // update falling tiles
92
- if (fallTimer.elapsed())
93
- {
94
- // add more blocks in the top
95
- for (let x = 0; x < levelSize.x; ++x)
96
- setTile(vec2(x,levelSize.y), LJS.randInt(tileTypeCount));
97
- }
98
-
99
- // allow blocks to fall
100
- if (!fallTimer.active())
101
- {
102
- // check if there is more to fall
103
- levelFall = [];
104
- let keepFalling = 0;
105
- const pos = vec2();
106
- for (pos.x = levelSize.x; pos.x--;)
107
- for (pos.y = 0; pos.y<levelSize.y; pos.y++)
108
- {
109
- const data = getTile(pos);
110
- const abovePos = pos.add(vec2(0,1));
111
- const aboveData = getTile(abovePos);
112
- if (data == -1 && aboveData >= 0)
113
- {
114
- setTile(pos, aboveData);
115
- setTile(abovePos, -1);
116
- levelFall[pos.x+pos.y*levelSize.x] = keepFalling = 1;
117
- }
118
- }
119
-
120
- if (keepFalling)
121
- {
122
- const p = LJS.percent(comboCount, 9, 0);
123
- fallTimer.set(fallTime*p);
124
- sound_fall.play();
125
- }
126
- else
127
- fallTimer.unset();
128
- }
129
- }
130
- else
131
- {
132
- // try to clear matches
133
- clearMatches();
134
- if (!fallTimer.isSet())
135
- {
136
- // mouse/touch control
137
- const mouseTilePos = LJS.mousePos.floor();
138
- if (!LJS.mousePos.arrayCheck(levelSize))
139
- {
140
- // cancel drag if mouse is not in the level bounds
141
- dragStartPos = 0;
142
- }
143
- else if (LJS.mouseWasPressed(0) && !dragStartPos)
144
- {
145
- // start drag
146
- dragStartPos = mouseTilePos.copy();
147
- }
148
- else if (LJS.mouseIsDown(0) && dragStartPos)
149
- {
150
- // if dragging to a neighbor tile
151
- const dx = LJS.abs(dragStartPos.x - mouseTilePos.x);
152
- const dy = LJS.abs(dragStartPos.y - mouseTilePos.y);
153
- if (dx == 1 && dy == 0 || dx == 0 && dy == 1)
154
- {
155
- const startTile = getTile(dragStartPos);
156
- const endTile = getTile(mouseTilePos);
157
- if (startTile >= 0 && endTile >= 0)
158
- {
159
- // swap tiles
160
- setTile(mouseTilePos, startTile);
161
- setTile(dragStartPos, endTile);
162
-
163
- // try to clear matches
164
- clearMatches();
165
-
166
- // undo if no matches
167
- if (!fallTimer.isSet())
168
- {
169
- sound_badMove.play();
170
- setTile(mouseTilePos, endTile);
171
- setTile(dragStartPos, startTile);
172
- }
173
- else
174
- sound_goodMove.play();
175
- dragStartPos = 0;
176
- }
177
- }
178
- }
179
- else
180
- dragStartPos = 0;
181
- }
182
- }
183
-
184
- if (score > bestScore)
185
- {
186
- // update high score
187
- bestScore = score;
188
- localStorage[highScoreKey] = bestScore;
189
- }
190
-
191
- if (LJS.keyWasPressed('KeyR'))
192
- gameReset();
193
- }
194
-
195
- ///////////////////////////////////////////////////////////////////////////////
196
- function gameUpdatePost()
197
- {
198
-
199
- }
200
-
201
- ///////////////////////////////////////////////////////////////////////////////
202
- function gameRender()
203
- {
204
- // draw a black square for the background
205
- LJS.drawRect(LJS.cameraPos.subtract(cameraOffset), levelSize, hsl(0,0,0));
206
-
207
- // draw the blocks
208
- const pos = vec2();
209
- for (pos.x = levelSize.x; pos.x--;)
210
- for (pos.y = levelSize.y; pos.y--;)
211
- {
212
- const data = getTile(pos);
213
- if (data == -1)
214
- continue;
215
-
216
- // highlight drag start
217
- const drawPos = pos.add(vec2(.5));
218
- if (dragStartPos && pos.x == dragStartPos.x && pos.y == dragStartPos.y)
219
- LJS.drawRect(drawPos, vec2(1.05));
220
-
221
- // make pieces fall gradually
222
- if (fallTimer.active() && levelFall[pos.x + pos.y*levelSize.x])
223
- drawPos.y += 1-fallTimer.getPercent();
224
-
225
- // draw background
226
- const color = tileColors[data];
227
- LJS.drawRect(drawPos, vec2(.95), color);
228
-
229
- // use darker color for icon
230
- const color2 = color.scale(.8, 1);
231
- LJS.drawTile(drawPos, vec2(.5), tile(data, 64), color2);
232
- }
233
-
234
- // draw a grey square at top to cover up incoming tiles
235
- LJS.drawRect(LJS.cameraPos.subtract(cameraOffset).add(vec2(0,levelSize.y)), levelSize, backgroundColor);
236
- }
237
-
238
- ///////////////////////////////////////////////////////////////////////////////
239
- function gameRenderPost()
240
- {
241
- // draw text on top of everything
242
- LJS.drawText('Score: ' + score, LJS.cameraPos.add(vec2(-3,-3.1)), .9, hsl(), .1);
243
- LJS.drawText('Best: ' + bestScore, LJS.cameraPos.add(vec2( 3,-3.1)), .9, hsl(), .1);
244
- }
245
-
246
- ///////////////////////////////////////////////////////////////////////////////
247
- // Startup LittleJS Engine
248
- LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
249
-
250
- ///////////////////////////////////////////////////////////////////////////////
251
- // find and remove all runs of 3 or higher
252
- function clearMatches()
253
- {
254
- // horizontal match check
255
- const removeTiles = [], pos = vec2();
256
- for (pos.y = levelSize.y; pos.y--;)
257
- {
258
- let runCount, runData;
259
- for (pos.x = levelSize.x; pos.x--;)
260
- {
261
- const data = getTile(pos);
262
- if (data >= 0 && data == runData)
263
- {
264
- for (let i=++runCount; runCount >= minMatchCount && i--;)
265
- removeTiles[pos.x + i + pos.y * levelSize.x] = 1;
266
- }
267
- else
268
- {
269
- runData = data;
270
- runCount = 1;
271
- }
272
- }
273
- }
274
-
275
- // vertical match check
276
- for (pos.x = levelSize.x; pos.x--;)
277
- {
278
- let runCount, runData;
279
- for (pos.y = levelSize.y; pos.y--;)
280
- {
281
- const data = getTile(pos);
282
- if (data >= 0 && data == runData)
283
- {
284
- for (let i=++runCount; runCount >= minMatchCount && i--;)
285
- removeTiles[pos.x + (pos.y + i) * levelSize.x] = 1;
286
- }
287
- else
288
- {
289
- runData = data;
290
- runCount = 1;
291
- }
292
- }
293
- }
294
-
295
- // remove tiles all at once like this to handle shapes like L or T
296
- let removedCount = 0;
297
- for (pos.x = levelSize.x; pos.x--;)
298
- for (pos.y = levelSize.y; pos.y--;)
299
- {
300
- if (removeTiles[pos.x + pos.y * levelSize.x])
301
- {
302
- // remove tile
303
- ++removedCount;
304
- const data = getTile(pos);
305
- setTile(pos, -1);
306
-
307
- // spawn particles
308
- const color1 = tileColors[data];
309
- const color2 = color1.lerp(hsl(), .5);
310
- new LJS.ParticleEmitter(
311
- pos.add(vec2(.5)), 0, // pos, angle
312
- .5, .1, 200, 3.14, // emitSize, emitTime, rate, cone
313
- 0, // tileInfo
314
- color1, color2, // colorStartA, colorStartB
315
- color1.scale(1,0), color2.scale(1,0),// colorEndA, colorEndB
316
- .5, .3, .2, .05, .05, // particleTime, sizeStart, sizeEnd, speed, angleSpeed
317
- .99, 1, 1, 3.14, .05, // damp, angleDamp, gravityScale, particleCone, fadeRate
318
- .5, 0, 1 // randomness, collide, additive, colorLinear, renderOrder
319
- );
320
- }
321
- }
322
-
323
- if (removedCount)
324
- {
325
- score += ++comboCount*removedCount;
326
- fallTimer.set();
327
- levelFall = [];
328
- }
329
- else
330
- comboCount = 0;
331
- }
@@ -1,8 +0,0 @@
1
- <!DOCTYPE html><head>
2
- <title>LittleJS Puzzle Game</title>
3
- <meta charset=utf-8>
4
- <meta name=apple-mobile-web-app-capable content=yes>
5
- <meta name=mobile-web-app-capable content=yes>
6
- <link rel=icon type=image/png href=../favicon.png>
7
- </head><body>
8
- <script src=game.js type=module></script>
Binary file
Binary file
@@ -1,18 +0,0 @@
1
- canvasClearColor = GRAY;
2
-
3
- function gameRender()
4
- {
5
- {
6
- // animate by changing frames
7
- const pos = vec2(-5, 2*abs(sin(time*2*PI)));
8
- const frame = (time*4)%2|0;
9
- drawTile(pos, vec2(7), tile(3).frame(frame), RED);
10
- }
11
- {
12
- // animate with stretch and squash
13
- const s = sin(time*9)*.5;
14
- const size = vec2(7-s,7+s);
15
- const pos = vec2(5,size.y-7);
16
- drawTile(pos, size, tile(5), GREEN);
17
- }
18
- }
@@ -1,54 +0,0 @@
1
- <!DOCTYPE html><meta charset=utf-8><body>
2
- <script src=../../dist/littlejs.js?1.18.4></script>
3
- <script src=../../dist/box2d.wasm.js></script>
4
-
5
- <!-- LittleJS Engine Source
6
- <script src=../../src/engine.js></script>
7
- <script src=../../src/engineDebug.js></script>
8
- <script src=../../src/engineMath.js></script>
9
- <script src=../../src/engineUtilities.js></script>
10
- <script src=../../src/engineSettings.js></script>
11
- <script src=../../src/engineObject.js></script>
12
- <script src=../../src/engineDraw.js></script>
13
- <script src=../../src/engineInput.js></script>
14
- <script src=../../src/engineAudio.js></script>
15
- <script src=../../src/engineTileLayer.js></script>
16
- <script src=../../src/engineParticles.js></script>
17
- <script src=../../src/engineMedals.js></script>
18
- <script src=../../src/engineWebGL.js></script>
19
- <script src=../../plugins/box2d.js></script>
20
- <script src=../../plugins/box2d.wasm.js></script>
21
- <script src=../../plugins/drawUtilities.js></script>
22
- <script src=../../plugins/postProcess.js></script>
23
- <script src=../../plugins/uiSystem.js></script>
24
- <script src=../../plugins/zzfxm.js></script>
25
- -->
26
- <script>
27
- 'use strict';
28
-
29
- // use fixed size canvas for examples
30
- canvasFixedSize = vec2(960, 540);
31
-
32
- // fix bleeding from neighboring pixels
33
- tileDefaultBleed = .5;
34
-
35
- // allow improved canvas scaling for smoother graphics
36
- canvasPixelated = false;
37
-
38
- // disable watermark
39
- debugWatermark = false;
40
-
41
- // disable showing the engine version in console
42
- showEngineVersion = false;
43
-
44
- // these functions can be overridden for each example
45
- function gameInit() {}
46
- function gameUpdate() {}
47
- function gameUpdatePost() {}
48
- function gameRender() {}
49
- function gameRenderPost() {}
50
-
51
- // check if WebGL can be enabled
52
- function glCanEnable() { return glCanBeEnabled; }
53
-
54
- </script>
@@ -1,14 +0,0 @@
1
- function gameRender()
2
- {
3
- // additive blending
4
- setBlendMode(1);
5
- drawCircle(vec2(-8,-2), 7, rgb(0,0,.5));
6
- drawCircle(vec2(-6, 2), 7, rgb(0,1,0));
7
- drawCircle(vec2(-4,-2), 7, rgb(1,0,0));
8
-
9
- // alpha blending
10
- setBlendMode(0);
11
- drawCircle(vec2(4,-2), 7, hsl(time/9 ,1,.5));
12
- drawCircle(vec2(8,-2), 7, hsl(time/9+1/3,1,.5,.5));
13
- drawCircle(vec2(6, 2), 7, hsl(time/9+2/3,1,.5,.5));
14
- }
@@ -1,51 +0,0 @@
1
- async function gameInit()
2
- {
3
- // setup box2d
4
- await box2dInit();
5
- mouseJoint = 0;
6
- gravity.y = -50;
7
- canvasClearColor = hsl(0,0,.9);
8
-
9
- // create ground object
10
- groundObject = new Box2dStaticObject(vec2(-8));
11
- groundObject.color = GRAY;
12
- groundObject.addBox(vec2(100,2));
13
-
14
- // add some random objects
15
- for (let i=50; i--;)
16
- {
17
- const pos = randInCircle(5);
18
- const color = randColor();
19
- const o = new Box2dObject(pos, vec2(), 0, 0, color);
20
- randInt(2) ? o.addCircle(rand(1,2)) : o.addRandomPoly(rand(1,2));
21
- }
22
- }
23
-
24
- function gameUpdate()
25
- {
26
- // mouse controls
27
- if (mouseJoint)
28
- {
29
- // update mouse joint
30
- mouseJoint.setTarget(mousePos);
31
- if (mouseWasReleased(0))
32
- {
33
- // release object
34
- mouseJoint = mouseJoint.destroy();
35
- }
36
- }
37
- else if (mouseWasPressed(0))
38
- {
39
- // grab object
40
- const object = box2d.pointCast(mousePos);
41
- if (object)
42
- mouseJoint = new Box2dTargetJoint(object,
43
- groundObject, mousePos);
44
- }
45
- }
46
-
47
- function gameRenderPost()
48
- {
49
- // draw mouse joint
50
- mouseJoint && drawLine(mousePos, mouseJoint.getAnchorB(), .2, RED);
51
- }
@@ -1,59 +0,0 @@
1
- async function gameInit()
2
- {
3
- // setup box2d and create the objects
4
- await box2dInit();
5
- gravity.y = -20;
6
-
7
- // create edge list for ground
8
- const edgePoints = [];
9
- for (let i=0, y=0, s=0; i<1e3; ++i)
10
- {
11
- y = clamp(y+rand(-1,1),0,5);
12
- edgePoints.push(vec2(i*5-15, y-8));
13
- }
14
- const ground = new Box2dStaticObject;
15
- ground.lineWidth = 1;
16
- ground.addEdgeList(edgePoints);
17
-
18
- // make a car
19
- new CarObject(vec2(0,-2));
20
- canvasClearColor = hsl(0,0,.9);
21
- }
22
-
23
- class CarObject extends Box2dObject
24
- {
25
- constructor(pos)
26
- {
27
- super(pos);
28
-
29
- // create car with wheels
30
- this.color = RED;
31
- this.addBox(vec2(7,2));
32
- const frequency = 4, maxTorque = 250;
33
- this.wheels = [];
34
- for (let i=2; i--;)
35
- {
36
- const wheelPos = pos.add(vec2(i?2:-2, -1));
37
- const wheel = new Box2dObject(wheelPos, vec2(2), tile(7));
38
- const joint = new Box2dWheelJoint(this, wheel);
39
- joint.setSpringFrequencyHz(frequency);
40
- joint.setMaxMotorTorque(maxTorque);
41
- joint.enableMotor(!i);
42
- const friction = 20;
43
- wheel.addCircle(2, vec2(), 1, friction);
44
- wheel.motorJoint = joint;
45
- this.wheels[i] = wheel;
46
- }
47
- }
48
- update()
49
- {
50
- // car controls - use mouse, arrow keys, or A/D to drive
51
- const maxSpeed = 40;
52
- const input = mouseIsDown(0) ? 1 :
53
- mouseIsDown(2) ? -1 : keyDirection().x ;
54
- let s = this.wheels[0].motorJoint.getMotorSpeed();
55
- s = input ? clamp(s - input, -maxSpeed, maxSpeed) : 0;
56
- this.wheels[0].motorJoint.setMotorSpeed(s);
57
- cameraPos.x = this.pos.x;
58
- }
59
- }
@@ -1,107 +0,0 @@
1
- const hitSound = new Sound([,.1,2e3,,,.01,,,,,,,,1]);
2
- const maxHitDistance = 6;
3
-
4
- class Ball extends Box2dObject
5
- {
6
- constructor(pos, number=0)
7
- {
8
- const color = hsl(number/9, 1, number? .5 : 1);
9
- super(pos, vec2(), 0, 0, color);
10
- this.number = number;
11
-
12
- // setup pool ball physics
13
- const friction = 0, restitution = .95;
14
- this.addCircle(1, vec2(), 1, friction, restitution);
15
- this.setLinearDamping(.4);
16
- this.setBullet(true);
17
- this.setFixedRotation(true);
18
- }
19
- beginContact()
20
- { hitSound.play(this.pos, clamp(this.getSpeed()/20)); }
21
- canHit()
22
- { return this == cueBall && this.getSpeed() < 1; }
23
- getHitStrength()
24
- { return this.getHitOffset().length()/maxHitDistance; }
25
- getHitOffset()
26
- {
27
- // hit from cue ball to mouse position
28
- const deltaPos = mousePos.subtract(this.pos);
29
- const length = min(deltaPos.length(), maxHitDistance);
30
- return deltaPos.normalize(length);
31
- }
32
- update()
33
- {
34
- if (this.canHit() && mouseWasPressed(0))
35
- {
36
- // hit the cue ball
37
- const accel = this.getHitOffset().scale(8);
38
- this.applyAcceleration(accel);
39
- hitSound.play(cueBall.pos, this.getHitStrength(), .5);
40
- }
41
- if (this.pocketed)
42
- this.destroy();
43
- }
44
- render()
45
- {
46
- super.render();
47
-
48
- // draw white circle and ball number
49
- drawCircle(this.pos, .6, WHITE);
50
- const textPos = this.pos.add(vec2(0,-.06));
51
- if (this.number)
52
- drawText(this.number, textPos, .5, BLACK);
53
- if (this.canHit())
54
- {
55
- // draw the aim line
56
- const endPos = this.pos.add(this.getHitOffset());
57
- const width = this.getHitStrength();
58
- drawLine(this.pos, endPos, width, hsl(0,1,.5,.5),
59
- vec2(), 0, false);
60
- }
61
- }
62
- }
63
-
64
- class Pocket extends Box2dStaticObject
65
- {
66
- constructor(pos, size)
67
- {
68
- super(pos, size, 0, 0, BLACK);
69
-
70
- // create a sensor circle for pocket
71
- this.addCircle(size.x);
72
- this.setSensor(true);
73
- }
74
- render()
75
- {
76
- // add ball size to pocket size for drawing
77
- drawCircle(this.pos, this.size.x + 1, BLACK);
78
- }
79
- beginContact(other) { other.pocketed = 1; }
80
- }
81
-
82
- async function gameInit()
83
- {
84
- // setup box2d
85
- await box2dInit();
86
- canvasClearColor = hsl(.4,.5,.5);
87
-
88
- // create table walls
89
- const groundObject = new Box2dStaticObject;
90
- groundObject.color = hsl(.1,1,.2);
91
- groundObject.addBox(vec2(100,3), vec2( 0, 8.5));
92
- groundObject.addBox(vec2(100,3), vec2( 0,-8.5));
93
- groundObject.addBox(vec2(3,100), vec2( 15,0));
94
- groundObject.addBox(vec2(3,100), vec2(-15,0));
95
-
96
- // create pockets
97
- for (let j=0; j<2; ++j)
98
- for (let i=0; i<3; ++i)
99
- new Pocket(vec2(i-1, j-.5).scale(13), vec2(.5));
100
-
101
- // create balls
102
- let number = 1;
103
- for (let i=5; i--;)
104
- for (let j=i+1; j--;)
105
- new Ball(vec2(6+i*.9, j-i/2), number++);
106
- cueBall = new Ball(vec2(-6, 0));
107
- }