kaplay 4000.0.0-alpha.21 → 4000.0.0-alpha.23

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- <!-- markdownlint-disable no-duplicate-heading -->
3
+ <!-- markdownlint-disable no-duplicate-heading blanks-around-fences single-h1 -->
4
4
 
5
5
  All notable changes to this project will be documented in this file.
6
6
 
@@ -8,6 +8,9 @@ The format is (mostly) based on
8
8
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
9
9
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
10
10
 
11
+ - Breaking changes are marked with: **(!)**.
12
+ - [Jump to v3001 changelog](#changelog-for-v3001).
13
+
11
14
  <!--
12
15
  Hey, KAPLAY Dev, you must changelog here, in unreleased, so later your
13
16
  best friend, lajbel, can put the correct version name here
@@ -15,15 +18,301 @@ best friend, lajbel, can put the correct version name here
15
18
 
16
19
  ## [unreleased]
17
20
 
18
- ## [unreleased] (v3001)
21
+ ## [4000.0.0-alpha.23] - 2025-11-05
19
22
 
20
- ---
23
+ ### Added
24
+
25
+ - Added `getGamepadAnalogButton()` to read the analog value of buttons like the
26
+ triggers - @dragoncoder047
27
+
28
+ ```js
29
+ isGamepadButtonDown("rtrigger"); // -> true/false, 0/1
30
+ getGamepadAnalogButton("rtrigger"); // -> analog value between 0 (not pressed) and 1 (fully pressed)
31
+ ```
32
+
33
+ - Added chorded button bindings using the Buttons API, so you can bind different
34
+ actions to `tab` and `shift+tab`, and handle them like normal. Also works with
35
+ gamepads and mouse! - @dragoncoder047
36
+
37
+ ```js
38
+ kaplay({
39
+ buttons: {
40
+ forward: {
41
+ keyboard: "tab",
42
+ gamepad: "south",
43
+ },
44
+ backward: {
45
+ keyboard: "shift+tab",
46
+ gamepad: "rshoulder+south",
47
+ },
48
+ },
49
+ });
50
+ ```
51
+
52
+ - Added `skew` to text formatting, so now italics is possible - @dragoncoder047
53
+
54
+ - Added **lifetime scopes**, a way to define the lifetime of an event handler
55
+ using a specific scope, `scene`, `app` or a game object - @lajbel,
56
+ @dragoncoder047
57
+
58
+ ```js
59
+ app.onUpdate(() => {
60
+ // runs until it is cancelled
61
+ });
62
+
63
+ scene("game", () => {
64
+ const obj = add([]);
65
+
66
+ obj.onUpdate(() => {
67
+ // runs until obj is destroyed
68
+ });
69
+
70
+ scene.onUpdate(() => { // or just onUpdate(() => {
71
+ // runs until scene is changed
72
+ });
73
+ });
74
+ ```
75
+
76
+ All the available handlers in the scopes are `GameEventHandlers` ones:
77
+
78
+ - `onKeyDown()`
79
+ - `onKeyPress()`
80
+ - `onKeyPressRepeat()`
81
+ - `onKeyRelease()`
82
+ - `onCharInput()`
83
+ - `onMouseDown()`
84
+ - `onMousePress()`
85
+ - `onMouseRelease()`
86
+ - `onMouseMove()`
87
+ - `onScroll()`
88
+ - `onTouchStart()`
89
+ - `onTouchMove()`
90
+ - `onTouchEnd()`
91
+ - `onGamepadConnect()`
92
+ - `onGamepadDisconnect()`
93
+ - `onGamepadButtonDown()`
94
+ - `onGamepadButtonPress()`
95
+ - `onGamepadButtonRelease()`
96
+ - `onGamepadStick()`
97
+ - `onButtonDown()`
98
+ - `onButtonPress()`
99
+ - `onButtonRelease()`
100
+ - `onTabHide()`
101
+ - `onTabShow()`
102
+
103
+ And this game object handlers may differ when using it with `obj` and
104
+ `scene`/`app`:
105
+
106
+ - `onFixedUpdate()`
107
+ - `onUpdate()`
108
+ - `onDraw()`
109
+
110
+ - Added `app` scope for app event handlers - @lajbel
111
+ ```js
112
+ app.onUpdate(() => {
113
+ // runs until it is cancelled
114
+ });
115
+ ```
116
+
117
+ - Added `KAPLAYOpt.defaultLifetimeScope` for setting the default lifetime scope
118
+ used for event handlers - @lajbel
119
+
120
+ ```js
121
+ kaplay({
122
+ defaultLifetimeScope: "app", // default is "scene"
123
+ });
124
+
125
+ onKeyPress("space", () => {
126
+ // runs until is cancelled
127
+ });
128
+ ```
129
+
130
+ - Added `skew` to text formatting, so now italics is possible - @dragoncoder047
131
+
132
+ ### Changed
133
+
134
+ - (**!**) Renamed `onShow()` to `onTabShow()` and `onHide()` to `onTabHide()` -
135
+ @lajbel
136
+
137
+ - In addition to being the `scene()` function, now `scene` is also a scope for
138
+ scene event handlers - @lajbel
139
+
140
+ ```js
141
+ scene("game", () => {
142
+ scene.onUpdate(() => { // or just onUpdate(() => {
143
+ // runs until scene is changed
144
+ });
145
+ });
146
+ ```
147
+
148
+ ### Fixed
149
+
150
+ - Now `pushScene()` and `popScene()` give the arguments to the scene in the same
151
+ way that `go()` does rather than passing them all to the first argument as an
152
+ array - @dragoncoder047
153
+ - Fixed a flicker due to the fadeIn not setting opacity until the next frame -
154
+ @mflerackers
155
+ - Fixed FPS cap not working correctly - @mflerackers, @dragoncoder047
156
+
157
+ ## [4000.0.0-alpha.22] - 2025-10-9
158
+
159
+ ### Added
160
+
161
+ - Added `KAPLAYOpt.types`, `kaplayTypes()` and `Opt` to config specific
162
+ TypeScript Advanced Features (TAF) - @lajbel
163
+
164
+ ```ts
165
+ kaplay({
166
+ types: kaplayTypes<
167
+ // Opt<> is optional but recommended to get autocomplete
168
+ Opt<{
169
+ scenes: {}; // define scenes and arguments
170
+ strictScenes: true; // you can only use defined scenes
171
+ }>
172
+ >(),
173
+ });
174
+ ```
175
+
176
+ - Added `TypesOpt.scenes` to type scenes and parameters - @lajbel
177
+
178
+ ```ts
179
+ const k = kaplay({
180
+ types: kaplayTypes<
181
+ Opt<{
182
+ scenes: {
183
+ game: [gamemode: "normal" | "hard"];
184
+ gameOver: [score: number, highScore: number];
185
+ };
186
+ }>
187
+ >(),
188
+ });
189
+
190
+ // If you trigger autocomplete it shows "game" or "gameOver"
191
+ k.scene("game", (gamemode) => {
192
+ // gamemode is now type "normal" | "hard"
193
+
194
+ // @ts-expect-error Argument of type 'string' is not assignable
195
+ // to parameter of type 'number'.
196
+ k.go("gameOver", "10", 10); //
197
+ });
198
+ ```
199
+
200
+ The methods that support this are:
201
+
202
+ - `scene`
203
+ - `go`
204
+ - `onSceneLeave`
205
+ - `getSceneName`
206
+
207
+ - Added `TypesOpt.strictScenes` to make usable scenes just the ones defined -
208
+ @lajbel
209
+
210
+ ```ts
211
+ const k = kaplay({
212
+ types: kaplayTypes<
213
+ Opt<{
214
+ scenes: {
215
+ game: [gamemode: "normal" | "hard"];
216
+ gameOver: [score: number, highScore: number];
217
+ };
218
+ strictScenes: true;
219
+ }>
220
+ >(),
221
+ });
222
+
223
+ // @ts-expect-error Argument of type '"hi"' is not assignable to
224
+ // parameter of type '"game" | "gameOver"'.
225
+ k.scene("hi", () => {});
226
+ ```
227
+
228
+ - Added named animations - @mflerackers
229
+
230
+ By giving a name to an animation, you can define more than one animation
231
+
232
+ ```js
233
+ const anim = obj.animation.get("idle");
234
+ anim.animate("pos", [0, 5, 0], { relative: true });
235
+ ```
236
+
237
+ - Added `screenshotToBlob()` to get a screenshot as a `Blob` - @dragoncoder047
238
+ - Added `getButtons()` to get the input binding buttons definition - @lajbel
239
+ - Added `RuleSystem`, `DecisionTree` and `StateMachine` for enemy AI -
240
+ @mflerackers
241
+ - Added constraint components for distance, translation, rotation, scale and
242
+ transform constraints - @mflerackers
243
+ - Added inverse kinematics constraint components using FABRIK and CCD, the
244
+ latter one can use bone constraints to constrain the angle - @mflerackers
245
+ - Added skew to Mat23, transformation stack, RenderProps, GameObjRaw as well as
246
+ a component - @mflerackers
247
+ - Added texture uniforms, in order to access more than one texture at a time in
248
+ shaders - @mflerackers
249
+
250
+ ### Fixed
251
+
252
+ - Now error screen should be instantly shown - @lajbel
253
+
254
+ ### Changed
255
+
256
+ - Now, you can use `color(c)` with a hexadecimal literal number (ex: 0x00ff00) -
257
+ @lajbel
258
+ ```js
259
+ // blue frog
260
+ add([
261
+ sprite("bean"),
262
+ color(0x0000ff),
263
+ ]);
264
+ ```
265
+ - **(!)** `KAPLAYCtx` doesn't use generics anymore. Now, `KAPLAYCtxT` uses
266
+ them - @lajbel
267
+ - Now, `kaplay` will return `KAPLAYCtx` or `KAPLAYCtxT` depending if it's using
268
+ Advanced TypeScript Features or not - @lajbel
269
+ - `loadShader()` now also checks for link errors as well as compile errors and
270
+ reports them rather than just silently trying to use a borked shader -
271
+ @dragoncoder047
272
+ - The debug `record()` function now records with sound enabled like it should -
273
+ @dragoncoder047
274
+ - Now `KAPLAYOpt.spriteAtlasPadding` is set to `2` by default - @lajbel
275
+ - Transformation and drawing is split now, so the transform can be modified
276
+ before drawing - @mflerackers
21
277
 
22
278
  ## [4000.0.0-alpha.21] - 2025-08-07
23
279
 
24
280
  ### Added
25
281
 
26
- - Added Prefabs - @mflerackers, @lajbel, @amyspark-ng and other contributors.
282
+ - Added `GameObjRaw.serialize()` for serializing the game object and its
283
+ components. - @mflerackers, @lajbel
284
+
285
+ ```js
286
+ const bean = add([sprite("prefab")]);
287
+ const beanSerialized = bean.serialize();
288
+ ```
289
+
290
+ - Added `createPrefab()` for serializing an object and register it (or not) as a
291
+ prefab from a Game Object. - @mflerackers, @lajbel
292
+
293
+ ```js
294
+ const beanObj = add([sprite("bean")]);
295
+
296
+ // Serialize game object and register it as a prefab asset
297
+ createPrefab("bean", beanObj);
298
+
299
+ addPrefab("bean");
300
+
301
+ // Just get serialized data
302
+ const serializedBean = createPrefab(beanObj);
303
+
304
+ addPrefab(beanObj);
305
+ ```
306
+
307
+ - Added `addPrefab()` for creating an object previously serialized -
308
+ @mflerackers, @lajbel
309
+
310
+ ```js
311
+ loadPrefab("bean", "/bean.kaprefab");
312
+
313
+ addPrefab("bean");
314
+ ```
315
+
27
316
  - Added new scene methods `pushScene()` and `popScene()`, for stack behaviour in
28
317
  scenes - @itzKiwiSky
29
318
  - Added `throwError()` for throwing custom errors to the blue screen, even
@@ -34,43 +323,49 @@ best friend, lajbel, can put the correct version name here
34
323
 
35
324
  ### Changed
36
325
 
37
- - Renamed `KAPLAYOpt.tagsAsComponents` to `KAPLAYOpt.tagComponentIds` - @lajbel
38
- - Now moving mouse changes the value of `getLastInputDevice()` - @amyspark-ng
39
326
  - Now `GameObjRaw.exists()` work for nested objects
327
+ - Now moving mouse changes the value of `getLastInputDevice()` - @amyspark-ng
328
+ - (**!**) Renamed `KAPLAYOpt.tagsAsComponents` to `KAPLAYOpt.tagComponentIds` -
329
+ @lajbel
40
330
 
41
331
  ### Fixed
42
332
 
43
333
  - Fixed shader error messages - @dragoncoder047
334
+ - Fixed compatibility issues when calculating font height with missing
335
+ TextMetrics props - @imaginarny
44
336
 
45
337
  ## [4000.0.0-alpha.20] - 2025-06-15
46
338
 
47
339
  ### Added
48
340
 
49
- - Now you can use the frames of a sprite in an atlas also as a font -
341
+ - Added `loadSpriteFromFont()` for loading a bitmap font from a loaded sprite. -
50
342
  @dragoncoder047
51
- - Improved various doc entries. - All Contributors.
343
+
344
+ ### Changed
345
+
346
+ - Improved various doc entries. - Many contributors
52
347
 
53
348
  ### Fixed
54
349
 
55
350
  - Fixed `AreaComp#onClick()` attaching events to app, instead of object, so
56
351
  event wasn't being paused with `obj.paused` - @lajbel
57
- - Fixed all touch events having a bad transform - @lajbel
58
- - Fixed sprite scaling not working properly when letterbox - @mflerackers
352
+ - Fixed all touch events having a bad transformation - @lajbel
353
+ - Fixed sprite scaling not working properly with `KAPLAYOpt.letterbox` -
354
+ @mflerackers
59
355
  - Fixed "add" event running twice in `addLevel()` tiles - @lajbel
60
356
  - Fixed blend component having a wrong ID - @lajbel
61
357
 
62
358
  ### Removed
63
359
 
64
- - `loadPedit` was removed - @lajbel
360
+ - **(!)** `loadPedit()` was removed - @lajbel
65
361
 
66
- ## [4000.0.0-alpha.0 to 4000.0.0-alpha.19]
362
+ ## [4000.0.0-alpha.19] - 2025-05-16
363
+
364
+ > This version changelog covers versions 4000.0.0-alpha.0 through
365
+ > 4000.0.0-alpha.19, as we didn't have a concise changelog strategy before.
67
366
 
68
367
  ### Added
69
368
 
70
- - Added `ellipse()` component - @mflerackers
71
- - Added circle and (rotated) ellipse collision shapes - @mflerackers
72
- - Added `clipLineToRect()` - @mflerackers
73
- - Added `obj.setParent()` to change the parent of a game object - @mflerackers
74
369
  - Added `fakeMouse()` to create a fake mouse cursor - @lajbel
75
370
 
76
371
  ```js
@@ -81,8 +376,7 @@ best friend, lajbel, can put the correct version name here
81
376
  myCursor.moveBy(vec2(100, 200)); // move as your wish
82
377
  ```
83
378
 
84
- - Added restitution and friction to physics - @mflerackers
85
- - Added `k.system()` to replace internal events or create new - @mflerackers
379
+ - Added `system()` to replace internal events or create new - @mflerackers
86
380
 
87
381
  ```js
88
382
  system("collision", () => {
@@ -90,14 +384,19 @@ best friend, lajbel, can put the correct version name here
90
384
  }, [SystemPhase.AfterFixedUpdate, SystemPhase.AfterUpdate]),
91
385
  ```
92
386
 
387
+ - Added `ellipse()` component - @mflerackers
388
+ - Added circle and (rotated) ellipse collision shapes - @mflerackers
389
+ - Added `clipLineToRect()` - @mflerackers
390
+ - Added `obj.setParent()` to change the parent of a game object - @mflerackers
391
+ - Added restitution and friction to physics - @mflerackers
93
392
  - All game objects have methods `onTag()` and `onUntag()` for watching tag
94
393
  changes - @mflerackers
95
394
  - Added `SystemPhase` enum to identify different lifecycle events in the game
96
395
  loop that systems can hook into - @mflerackers
97
- - Blend mode is selectable to change how sprites are composited on top of each
98
- other - @mflerackers
99
- - Picture API to cache drawing of selected objects - @mflerackers
100
- - drawCanvas - @mflerackers
396
+ - Added Blend mode is selectable to change how sprites are composited on top of
397
+ each other - @mflerackers
398
+ - Added Picture API to cache drawing of selected objects - @mflerackers
399
+ - Added `drawCanvas()` - @mflerackers
101
400
  - Added `video()` component to embed a video file into the game - @mflerackers
102
401
  - Added `level()` component and parent argument to `addLevel()` - @KeSuave
103
402
  - Allow the `text()` component to change the font and apply shaders
@@ -115,16 +414,15 @@ best friend, lajbel, can put the correct version name here
115
414
  - Now you can use the global option `inspectOnlyActive: false` to prevent paused
116
415
  objects from showing in the debug inspect view, this is useful if you are
117
416
  swapping out objects for different views - @dragoncoder047
118
- - The `offscreen()` component now has an option `offscreenDistance` to change
119
- the distance at which an object is considered off-screen - @dragoncoder047
417
+ - The `OffScreenComp` now has an option `offscreenDistance` to change the
418
+ distance at which an object is considered off-screen - @dragoncoder047
120
419
  - Now you can cherry-pick specific frames of a sprite sheet by using the
121
420
  `frames` list, instead of being limited to consecutive frames `start` and
122
421
  `end` - @dragoncoder047
123
422
  - `wave()` can now go back and forth between any value that is able to be used
124
423
  with `lerp()` - @dragoncoder047, @mflerackers
125
- - The `textInput` component has more events: `focus`, `blur`, `input`, and
126
- `change`, to better interact with the text input state - @dragoncoder047
127
- - Layers now work globally, no longer only between siblings. @mflerackers
424
+ - The `TextInputComp` has more events: `focus`, `blur`, `input`, and `change`,
425
+ to better interact with the text input state - @dragoncoder047
128
426
  - Areas no longer struggle with parents whose transform inst't up-to-date -
129
427
  @mflerackers
130
428
  - Exported step and smoothstep - @mflerackers
@@ -134,41 +432,16 @@ best friend, lajbel, can put the correct version name here
134
432
  - Typed `StateComp` - @amyspark-ng
135
433
  - Added bias to line drawing, which controls the offset from the center of the
136
434
  line - @mflerackers
137
- - Added `sprite.play("anim", {preventRestart: true})` to allow play() to be
138
- called from update() and not reset the animation to frame 0 - @dragoncoder047
139
- - Added `throwError()` for trowing custom errors in the blue screen, even errors
140
- KAPLAY can't handle. - @lajbel
141
- - Added Prefabs - @mflerackers, @lajbel, @amyspark-ng and other contributors.
142
-
143
- ### Fixed
144
-
145
- - `obj.exists()` now correctly returns false if the parent was destroyed but obj
146
- wasn't - @dragoncoder047
147
- - Various typescript type fixes - @amyspark-ng, @lajbel, @KeSuave
148
- - 9slice sprites behave properly when using anchor - @mflerackers
149
- - Rendering glitches with outlines on circles - @mflerackers
150
- - `wait()` now fires the callback and its onEnd events at the same time like was
151
- intended, instead of onEnd being waiting for twice the duration -
435
+ - Added `SpriteAnimPlayOpt.preventRestart` to allow `SpriteComp.play()` to be
436
+ called from an `onUpdate()` and not reset the animation to frame 0 -
152
437
  @dragoncoder047
153
- - `Vec2.dot()` now actually does the Correct Calculation&trade; - @andrenanninga
154
- - `setCursorLocked(true)` doesn't error if the browser is using the old
155
- non-Promise-based API return value - @imaginarny
156
- - changing `debug.timeScale` now actually makes the game change speed by
157
- affecting `dt()` - @lajbel
158
- - CapsLock now affects textInput() - @amyspark-ng
159
- - PatrolComp is not going to last waypoint
160
- ([#734](https://github.com/kaplayjs/kaplay/issues/734)) - @nojaf
161
- - Fixed non-focused textInput component backspace - @KeSuave
162
-
163
- ### Removed
164
-
165
- - `make()` was sent to doom - @lajbel
166
- - `loadPedit` was removed - @lajbel
167
438
 
168
439
  ### Changed
169
440
 
170
- - **BREAKING**: Changed default behavior to
171
- `kaplay({ tagsAsComponents: false })`.
441
+ - **(!)** - Now `z()` is global instead of relative - @mflerackers
442
+ - **(!)** Layers now work globally, no longer only between siblings -
443
+ @mflerackers
444
+ - **(!)**: Changed default behavior to `kaplay({ tagsAsComponents: false })`
172
445
  - The physics engine creates less garbage - @mflerackers
173
446
  - Tag-based events are slightly faster - @dragoncoder047
174
447
  - Moved camera to the shader - @mflerackers
@@ -183,6 +456,38 @@ best friend, lajbel, can put the correct version name here
183
456
  setting it to true (focused) will clear focus from all the other text inputs -
184
457
  @dragoncoder047
185
458
  - Changed the API of `HealthComp` - @amyspark-ng
459
+ - CapsLock now affects `TextInputComp` - @amyspark-ng
460
+
461
+ ### Fixed
462
+
463
+ - `GameObjRaw.exists()` now correctly returns false if the parent was destroyed
464
+ but obj wasn't - @dragoncoder047
465
+ - `Vec2.dot()` now actually does the Correct Calculation&trade; - @andrenanninga
466
+ - Fixed `debug.timeScale` not affecting `dt()` scale - @lajbel
467
+ - Fixed `wait()`'s `TimerComp.onEnd()` being waiting for twice the duration -
468
+ @dragoncoder047
469
+ - Fixed non-focused `TextInputComp` backspace - @KeSuave
470
+ - Fixed 9slice sprites behaving wrong when using `Anchor` - @mflerackers
471
+ - Fixed rendering glitches with outlines on circles - @mflerackers
472
+ - Fixed `setCursorLocked(true)` throwing error if the browser is using the old
473
+ non-Promise-based API return value - @imaginarny
474
+ - Fixed `PatrolComp` not going to last waypoint - @nojaf
475
+ - Fixed various TypeScript types - @amyspark-ng, @lajbel, @KeSuave
476
+
477
+ ### Removed
478
+
479
+ - **(!)** `make()` was sent to doom - @lajbel
480
+
481
+ ---
482
+
483
+ # Changelog for v3001
484
+
485
+ ## [unreleased]
486
+
487
+ ### Fixed
488
+
489
+ - Fixed compatibility issues when calculating font height with missing
490
+ TextMetrics props - @imaginarny
186
491
 
187
492
  ## [3001.0.19] - 2025-06-15
188
493
 
@@ -216,32 +521,24 @@ best friend, lajbel, can put the correct version name here
216
521
  - Removed beant - @lajbel
217
522
  - Various fixes and improvements - All contributors
218
523
 
219
- [Read commit history](https://github.com/kaplayjs/kaplay/compare/3001.0.15...3001.0.16)
220
-
221
524
  ## [3001.0.15] - 2025-04-18
222
525
 
223
526
  ### Fixed
224
527
 
225
528
  - Various fixes and improvements - All contributors
226
529
 
227
- [Read commit history](https://github.com/kaplayjs/kaplay/compare/3001.0.14...3001.0.15)
228
-
229
530
  ## [3001.0.14] - 2025-04-18
230
531
 
231
532
  ### Fixed
232
533
 
233
534
  - Various fixes and improvements - All contributors
234
535
 
235
- [Read commit history](https://github.com/kaplayjs/kaplay/compare/3001.0.13...3001.0.14)
236
-
237
536
  ## [3001.0.13] - 2025-04-18
238
537
 
239
538
  ### Fixed
240
539
 
241
540
  - Various fixes and improvements - All contributors
242
541
 
243
- [Read commit history](https://github.com/kaplayjs/kaplay/compare/3001.0.12...3001.0.13)
244
-
245
542
  ## [3001.0.12] - 2025-04-12
246
543
 
247
544
  ### Fixed
@@ -252,8 +549,7 @@ best friend, lajbel, can put the correct version name here
252
549
 
253
550
  ### Added
254
551
 
255
- - Added **CSS Colors!** 🎨 **(experimental)** - @lajbel (based on
256
- @dragoncoder047 idea) (**experimental**)
552
+ - Added **CSS Colors!** 🎨 - @lajbel (based on @dragoncoder047 idea)
257
553
 
258
554
  ```js
259
555
  color("slateblue");
@@ -289,8 +585,7 @@ best friend, lajbel, can put the correct version name here
289
585
  });
290
586
  ```
291
587
 
292
- - Frame option for load animations with singular frames (**experimental**) -
293
- @dragoncoder047
588
+ - Frame option for load animations with singular frames - @dragoncoder047
294
589
 
295
590
  ```js
296
591
  loadSpriteAtlas("/examples/sprites/dungeon.png", {
@@ -370,7 +665,7 @@ kaplay({
370
665
  ### Added
371
666
 
372
667
  - Added `trigger(event, tag, ...args)` for global triggering events on a
373
- specific tag (**experimental**) - @lajbel
668
+ specific tag - @lajbel
374
669
 
375
670
  ```js
376
671
  trigger("shoot", "target", 140);
@@ -401,7 +696,7 @@ kaplay({
401
696
  ]);
402
697
  ```
403
698
 
404
- - Added `{ indentAll?: boolean }` in `TextCompOpt` to indent every new line -
699
+ - Added `TextCompOpt.identAll` boolean to indent every new line -
405
700
  @dragoncoder047
406
701
 
407
702
  - Added TypeScript definition for all App Events and missing Game Object
@@ -417,23 +712,23 @@ kaplay({
417
712
  ### Added
418
713
 
419
714
  - Added tags and components separation in `KAPLAYOpt.tagsAsComponents`
420
- (**experimental**)
421
- - Added `.is()`, `.tag()` and `.untag()` to `GameObjRaw`, check, add and remove
422
- (**experimental**)
423
- - Added `.has()` to `GameObjRaw`, to check if a game object has a component tags
424
- (**experimental**)
715
+ - Added `GameObjRaw.is()`, `GameObjRaw.tag()` and `GameObjRaw.untag()` to check,
716
+ add and remove tags
717
+ - Added `GameObjRaw.has()` to check if a game object has a component tags
425
718
  - Added events for listen to comps being removed or added `onUse()` and
426
- `onUnused()` (**experimental**)
427
- - Added `k.cancel()` to cancel the current event (**experimental**)
428
- - ```js
719
+ `onUnused()`
720
+ - Added `cancel()` to cancel the current event
721
+
722
+ ```js
429
723
  onKeyPress("space", () => {
430
724
  // do something
431
725
  // cancel the event
432
726
  return cancel();
433
727
  });
434
728
  ```
435
- - Added `getDefaultLayer()` to get the default layer (**experimental**)
436
- - Added `getLayers()` to get the layers list (**experimental**)
729
+
730
+ - Added `getDefaultLayer()` to get the default layer
731
+ - Added `getLayers()` to get the layers list
437
732
  - Added many JSDoc specifiers on many functions (@require, @deprecated, @since,
438
733
  @group, etc)
439
734
 
@@ -441,28 +736,38 @@ kaplay({
441
736
 
442
737
  - Added `.use()`, `.unuse()` and `.has()` to `GameObjRaw`, to add, remove and
443
738
  check components. This only works with `KAPLAYOpt.tagsAsComponents` set to
444
- `true` (**experimental**)
739
+ `true`
445
740
 
446
741
  ### Deprecated
447
742
 
448
743
  - Deprecated camera methods `camScale()`, `camPos()` and `camRot()` in favor of
449
744
  `setCamScale()`, `getCamScale()`, `setCamPos()`, `getCamPos()`, `setCamRot()`
450
- and `getCamRot`.
451
- - Deprecated `camTransform()` in favor of `getCamTransform()`.
452
- - Deprecated `camFlash()` in favor of `flash()`, for a `shake()`-like name.
745
+ and `getCamRot()`
746
+ - Deprecated `camTransform()` in favor of `getCamTransform()`
747
+ - Deprecated `camFlash()` in favor of `flash()`, for a `shake()`-like name
453
748
 
454
749
  ### Fixed
455
750
 
456
- - Fixed artifacts present in some TrueType fonts.
457
- - Fixed `.use()` and `.unuse()` with area components.
751
+ - Fixed artifacts present in some TrueType fonts
752
+ - Fixed `.use()` and `.unuse()` with area components
753
+
754
+ ## [3001.0.0] - 2024-10-31
458
755
 
459
- ## [3001.0.0] "Spooky Beans!" - 2024-10-31
756
+ ### Added
757
+
758
+ - Added `getTreeRoot()` to get the game's root object, which is the parent of
759
+ all other objects
460
760
 
461
- ### Input
761
+ ```js
762
+ // get the root object
763
+ const root = getTreeRoot();
764
+ root.add(); // same as add()
765
+ root.get(); // same as get()
766
+ ```
462
767
 
463
- - Added input bindings, `onButtonPress`, `onButtonRelease`, `onButtonDown`, and
464
- it's corresponding boolean versions, `isButtonPressed`, `isButtonDown` and
465
- `isButtonReleased`.
768
+ - Added Buttons API for using Input bindings, `onButtonPress()`,
769
+ `onButtonRelease()`, `onButtonDown()`, and it's corresponding boolean
770
+ versions, `isButtonPressed()`, `isButtonDown()` and `isButtonReleased()`
466
771
 
467
772
  ```js
468
773
  kaplay({
@@ -481,7 +786,7 @@ kaplay({
481
786
  });
482
787
  ```
483
788
 
484
- - added `getButton(btn)` and `setButton(btn)` to get and set button bindings
789
+ - Added `getButton(btn)` and `setButton(btn)` to get and set button bindings
485
790
 
486
791
  ```js
487
792
  // ["space", "up"]
@@ -494,7 +799,7 @@ kaplay({
494
799
  });
495
800
  ```
496
801
 
497
- - added `getLastInputDeviceType()` to get what was the last pressed device
802
+ - Added `getLastInputDeviceType()` to get what was the last pressed device
498
803
 
499
804
  ```js
500
805
  onButtonPress(() => {
@@ -503,7 +808,7 @@ kaplay({
503
808
  });
504
809
  ```
505
810
 
506
- - added `pressButton(btn)` and `releaseButton(btn)` to simulate button press and
811
+ - Added `pressButton(btn)` and `releaseButton(btn)` to simulate button press and
507
812
  release
508
813
 
509
814
  ```js
@@ -511,46 +816,7 @@ kaplay({
511
816
  releaseButton("jump"); // triggers onButtonRelease and stops onButtonDown
512
817
  ```
513
818
 
514
- - added the possibility of use arrays in all input handlers
515
-
516
- ```js
517
- onKeyPress(["w", "up"], () => {
518
- player.jump();
519
- });
520
- ```
521
-
522
- - now gamepad events return what gamepad triggered the action
523
-
524
- ```js
525
- onGamepadButtonPress("south", (btn, gp) => {
526
- console.log(gp.index); // gamepad number on navigator's gamepad list
527
- });
528
- ```
529
-
530
- ### Physics
531
-
532
- - added effector components: `areaEffector()`, `buoyancyEffector()`,
533
- `pointEffector()`, `surfaceEffector()`.
534
- - added `constantForce()` component.
535
- - added `patrol()` component to move along a list of waypoints.
536
- - added `sentry()` component to notify when certain objects are in sight.
537
- - added `NavMesh` class for pathfinding on a mesh.
538
- - added `pathfinder()` component to calculate a list of waypoints on a graph.
539
- - now collision checks are only done if there's area objects.
540
-
541
- ### Game Object
542
-
543
- - added `getTreeRoot()` to get the game's root object, which is the parent of
544
- all other objects
545
-
546
- ```js
547
- // get the root object
548
- const root = getTreeRoot();
549
- root.add(); // same as add()
550
- root.get(); // same as get()
551
- ```
552
-
553
- - added `GameObjRaw.tags` to get a game object's tags.
819
+ - Added `GameObjRaw.tags` to get a game object's tags
554
820
 
555
821
  ```js
556
822
  const obj = add([sprite("bean"), "enemy", "dangerous"]);
@@ -559,22 +825,7 @@ kaplay({
559
825
  debug.log(obj.tags); // ["enemy", "dangerous"]
560
826
  ```
561
827
 
562
- ### Components
563
-
564
- - added support to setters/getters syntax in `ScaleComp` and `SpriteComp`
565
- components
566
-
567
- ```js
568
- const obj = add([sprite("bean"), scale(2)]);
569
-
570
- // set it with = syntax
571
- obj.scale = vec2(3, 4);
572
- obj.sprite = "bag";
573
- ```
574
-
575
- ### Rendering and Animation
576
-
577
- - added the `animate()` component to _animate_ the properties of an object using
828
+ - Added the `animate()` component to _animate_ the properties of an object using
578
829
  keyframes. Check out
579
830
  [Animation Example](https://play.kaplayjs.com/?example=animation)
580
831
 
@@ -586,9 +837,7 @@ kaplay({
586
837
  });
587
838
  ```
588
839
 
589
- - added `particles()` component to emit and draw particles.
590
-
591
- - readded `layers()` and the `layer()` component.
840
+ - Readded `layers()` and the `layer()` component
592
841
 
593
842
  Before the `z()` component, there was a `layer()` component that allowed you
594
843
  to control the draw order of objects. It was removed in v3000, but now it's
@@ -610,16 +859,16 @@ kaplay({
610
859
  add([sprite("bg"), layer("bg")]);
611
860
  ```
612
861
 
613
- - added `SpriteComp.getCurAnim()` to get the current animation data
862
+ - Added `SpriteComp.hasAnim()` to check if an animation exists
614
863
 
615
864
  ```js
616
865
  const obj = add([sprite("bean", { anim: "walk" })]);
617
866
 
618
- // get the current animation name
619
- debug.log(obj.getCurAnim().name); // "walk"
867
+ // check if an animation exists
868
+ debug.log(obj.hasAnim("walk")); // true
620
869
  ```
621
870
 
622
- - added `SpriteComp.getAnim()` for get any animation data
871
+ - Added `SpriteComp.getAnim()` for get any animation data
623
872
 
624
873
  ```js
625
874
  loadSprite("bean", "bean.png", {
@@ -639,22 +888,22 @@ kaplay({
639
888
  debug.log(obj.getAnim("walk")); // { from: 0, to: 3 }
640
889
  ```
641
890
 
642
- - added `SpriteComp.hasAnim()` to check if an animation exists
891
+ - Added `SpriteComp.getCurAnim()` to get the current animation data
643
892
 
644
893
  ```js
645
894
  const obj = add([sprite("bean", { anim: "walk" })]);
646
895
 
647
- // check if an animation exists
648
- debug.log(obj.hasAnim("walk")); // true
896
+ // get the current animation name
897
+ debug.log(obj.getCurAnim().name); // "walk"
649
898
  ```
650
899
 
651
- - added `camFlash()` to flash the screen.
900
+ - Added `camFlash()` to flash the screen
652
901
 
653
902
  ```js
654
903
  camFlash(0.5, 0.5, 0.5, 0.5);
655
904
  ```
656
905
 
657
- - added support for radius in individual corners for `RectComp` component.
906
+ - Added support for radius in individual corners for `RectComp,radius`
658
907
 
659
908
  ```js
660
909
  add([
@@ -664,18 +913,7 @@ kaplay({
664
913
  ]);
665
914
  ```
666
915
 
667
- - (**! break**) removed compatibility to use two KAPLAY frames in the same page,
668
- due to performance improvements
669
-
670
- - fix error screen not showing with not Error object
671
-
672
- - Added `SpriteComp.animFrame` to get the frame of the current animation (not on
673
- the spritesheet)
674
-
675
- ### Audio
676
-
677
- - now you can pass an `AudioBuffer` to `loadSound()`
678
- - added `loadMusic()` to load streaming audio (doesn't block in loading screen).
916
+ - Added `loadMusic()` to load streaming audio (doesn't block in loading screen)
679
917
 
680
918
  ```js
681
919
  loadMusic("bgm", "bgm.mp3");
@@ -684,39 +922,34 @@ kaplay({
684
922
  play("bgm");
685
923
  ```
686
924
 
687
- ### Math
688
-
689
- - added `Vec2.fromArray()` to convert an array to a `Vec2`.
925
+ - Added `Vec2.fromArray()` to convert an array to a `Vec2`
690
926
 
691
927
  ```js
692
928
  const point = Vec2.fromArray([100, 200]); // vec2(100, 200);
693
929
  ```
694
930
 
695
- - added `Vec2.toArray()` to convert a `Vec2` to an array.
931
+ - Added `Vec2.toArray()` to convert a `Vec2` to an array
696
932
 
697
933
  ```js
698
934
  const point = vec2(100, 200);
699
935
  const arr = point.toArray(); // [100, 200]
700
936
  ```
701
937
 
702
- - added `chooseMultiple()` to choose a random element from an array.
938
+ - Added `chooseMultiple()` to choose a random element from an array
703
939
 
704
940
  ```js
705
941
  const numbers = [1, 2, 3, 4, 5];
706
942
  const random = chooseMultiple(numbers, 3); // [3, 1, 5]
707
943
  ```
708
944
 
709
- - added `shuffle()` to shuffle an array.
945
+ - Added `shuffle()` to shuffle an array
710
946
 
711
947
  ```js
712
948
  const numbers = [1, 2, 3, 4, 5];
713
949
  shuffle(numbers); // [3, 1, 5, 2, 4]
714
950
  ```
715
951
 
716
- ### Debug mode
717
-
718
- - added `outline()`, `shader()`, and `area()` properties to `debug.inspect`.
719
- - added `KAPLAYOpt.debugKey` for customizing the key used to toggle debug mode.
952
+ - Added `KAPLAYOpt.debugKey` for customizing the key used to toggle debug mode
720
953
 
721
954
  ```js
722
955
  kaplay({
@@ -724,7 +957,7 @@ kaplay({
724
957
  });
725
958
  ```
726
959
 
727
- - added compatibility with custom properties in debug mode
960
+ - Added compatibility with custom properties in debug mode
728
961
 
729
962
  ```js
730
963
  const obj = add([
@@ -742,1248 +975,90 @@ kaplay({
742
975
  debug.inspect = true;
743
976
  ```
744
977
 
745
- - Now `debug.log()` accepts multiple argument of any type, like `console.log()`.
978
+ - Added effector components: `areaEffector()`, `buoyancyEffector()`,
979
+ `pointEffector()`, `surfaceEffector()`
980
+ - Added `constantForce()` component
981
+ - Added `pathfinder()` component to calculate a list of waypoints on a graph
982
+ - Added `patrol()` component to move along a list of waypoints
983
+ - Added `sentry()` component to notify when certain objects are in sight
984
+ - Added `NavMesh` class for pathfinding on a mesh
985
+ - Added `particles()` component to emit and draw particles
986
+ - Added `SpriteComp.animFrame` to get the frame of the current animation (not on
987
+ the spritesheet)
988
+ - Added `outline()`, `shader()`, and `area()` properties to `debug.inspect`
989
+ - Added `getSceneName()` to get the current scene name
990
+ - Added `Color.toArray()` to convert a color to an array
991
+ - Added `raycast` and `LevelComp.raycast` method to level
992
+ - Added support for textured polygons
993
+ - Added support for concave polygon drawing
994
+ - Added support for arrays in uniforms
995
+ - Added support for texture larger than 2048x2048
996
+ - Added support for gravity direction
997
+ - Added line join (bevel, miter, round) and line caps (square, round)
998
+ - Added quadratic bezier and Catmull-Rom evaluation
999
+ - Added evaluation of the first and second derivatives for all splines
1000
+ - Added higher order easing functions linear, steps and cubic-bezier
746
1001
 
747
- ### Helpers
1002
+ ### Changed
748
1003
 
749
- - added `getSceneName()` to get the current scene name
750
- - added `Color.toArray()` to convert a color to an array
751
- - added global raycast function and raycast method to level
752
- - added support for textured polygons
753
- - added support for concave polygon drawing
754
- - added support for arrays in uniforms
755
- - added support for texture larger than 2048x2048
756
- - added support for gravity direction
757
- - added line join (bevel, miter, round) and line caps (square, round)
758
- - added quadratic bezier and Catmull-Rom evaluation
759
- - added evaluation of the first and second derivatives for all splines
760
- - added higher order easing functions linear, steps and cubic-bezier
1004
+ - Now collision checks are only done if there's area objects
1005
+ - Now you can use arrays in all input handlers
761
1006
 
762
- ### TypeScript
1007
+ ```js
1008
+ onKeyPress(["w", "up"], () => {
1009
+ player.jump();
1010
+ });
1011
+ ```
763
1012
 
764
- - Now you can type `get()` with a type parameter and passing component types.
765
- (**v4000**)
1013
+ - Now gamepad events return what gamepad triggered the action
766
1014
 
767
- ```ts
768
- const player = get<BodyComp>("player");
1015
+ ```js
1016
+ onGamepadButtonPress("south", (btn, gp) => {
1017
+ console.log(gp.index); // gamepad number on navigator's gamepad list
1018
+ });
769
1019
  ```
770
1020
 
771
- - Now `Key` also accepts a string as an acceptable value.
772
- - Now `text()` component doesn't require to pass a string.
773
- - Now `camScale()` and `camPos()` accept only 1 number as parameter.
774
- - Now `shake()` can be called without args.
775
- - Now `loadShader()` and `loadShaderURL()` accepts null for unused parameters.
776
- - Now `RectCompOpt` accepts a array of numbers for `radius`.
777
-
778
- ### Deprecations
779
-
780
- > All changes applies for both v3001 and v4000
781
-
782
- - deprecated `kaboom()` in favor of `kaplay()` (you can still use `kaboom*`)
783
- - deprecated `SpriteComp.curAnim()` in favor of `SpriteComp.getCurAnim().name`
784
- - deprecated `fadeIn` component in favor of `OpacityComp.fadeIn()`
785
- - deprecated `Event`, `EventHandler` and `EventController` in favor of `KEvent`,
786
- `KEventHandler` and `KEventController`
787
-
788
- ### Bug fixes
789
-
790
- > All changes applies for both v3001 and v4000
791
-
792
- - **(break)** much typescript definitions was fixed, if you use typescript now
793
- maybe you see new errors that make your code strict
794
- - fix error screen not showing with not Error object
795
- - fix error where debug screen was scaling bad the blue rectangles
796
- - fix error where error screen was not showing when the error was thrown in a
797
- input event
798
- - fix error where fonts was cropped in the bottom
799
- - fix an error where `stay()` object loose their input events on scene change
800
-
801
- ### v3000.1.17
802
-
803
- - exposed `vel` property on `BodyComp`
804
-
805
- ### v3000.1.16
806
-
807
- - fixed error not being logged
808
- - fixed error screen scaling error in letterbox mode
809
-
810
- ### v3000.1.15
811
-
812
- - fixed `loadRoot()` not working sometimes
813
- - fixed audio being resumed when the tab is switched on but `debug.paused` is
814
- true
815
-
816
- ### v3000.1.12
817
-
818
- - fixed `color()` and `rgb()` not working
819
-
820
- ### v3000.1.11
821
-
822
- - added option `kaboom({ focus: false })` to disable focus on start
823
- - fixed `rand()` typing for numbers
824
- - fixed mouse position in fullscreen
825
- - added `Color#toHSL()`
826
-
827
- ### v3000.1.10
828
-
829
- - fixed test code accidentally getting shipped (where a screenshot will be
830
- downloaded every time you press space)
831
-
832
- ### v3000.1.9
833
-
834
- - added `fill` option to `rect()`, `circle()` and `sprite()`
835
- - fixed view getting cut off in letterbox mode
836
-
837
- ### v3000.1.8
838
-
839
- - fixed `scale` option acting weird when width and height are defined (by
840
- @hirnsalat)
841
-
842
- ### v3000.1.7
843
-
844
- - fixed `debug.paused` not pausing audio
845
- - added `mask()` component
846
- - added support for colored font outline
847
-
848
- ```js
849
- loadFont("apl386", "/examples/fonts/apl386.ttf", {
850
- outline: {
851
- width: 8,
852
- color: rgb(0, 0, 255),
853
- },
854
- });
855
- ```
856
-
857
- - fixed `wave()` not starting at `0` when time is `0`
858
- - kaboom now only displays error screen for kaboom's own error, instead of
859
- catching all errors in current window
860
- - added `KaboomError` class for errors related to current kaboom instance
861
- - setting `obj.text` with `text()` component now immediately updates `width` and
862
- `height` property
863
-
864
- ```js
865
- const obj = add([text("oh hi"), pos(100, 200)]);
866
-
867
- // before
868
- obj.text = "bye";
869
- console.log(obj.width); // still the width of "oh hi" until next render
870
-
871
- // before
872
- obj.text = "bye";
873
- console.log(obj.width); // will be updated to the width of "bye"
874
- ```
875
-
876
- ### v3000.1.6
877
-
878
- - fixed `loadSound` typing to accept `ArrayBuffer`
879
-
880
- ### v3000.1.5
881
-
882
- - added `Event#clear()` method
883
- - fixed `add()` without argument
884
-
885
- ### v3000.1.4
886
-
887
- - added `audio.stop()` method
888
-
889
- ```js
890
- const music = play("music");
891
- music.stop();
892
- ```
893
-
894
- ### v3000.1.3
895
-
896
- - fixed `onCollideUpdate()` still runs when object is paused
897
- - allow `add()` and `make()` without arguments
898
- - added `debug.numObjects()`
899
- - added `width` and `height` properties to `SpriteData`
900
-
901
- ```js
902
- // get sprite size
903
- getSprite("bean").then((spr) => {
904
- console.log(spr.width, spr.height);
905
- });
906
- ```
907
-
908
- ### v3000.1.2
909
-
910
- - fixed audio not pausing when tab hidden and `backgroundAudio` not set
911
- - fixed `debug.timeScale` not working
912
- - fixed `debug.paused` not able to resume
913
- - fixed `quad` option not working in `sprite()` component
914
- - added `onHide()` and `onShow()` for tab visibility event
915
-
916
- ### v3000.1.1
917
-
918
- - fixed some indirect `fixed` related issues
919
-
920
- ## [3000.1.0] - 2023-08-18 (kaboom.js)
921
-
922
- - added game object level input handling
923
-
924
- ```js
925
- // add a scene game object
926
- const scene = add([]);
927
-
928
- const bean = scene.add([sprite("bean"), pos(100, 200), area(), body()]);
929
-
930
- scene.onKeyPress("space", () => {
931
- bean.jump();
932
- });
933
-
934
- scene.onMousePress(() => {
935
- bean.jump();
936
- });
937
-
938
- // setting scene.paused will pause all the input events
939
- scene.paused = true;
940
-
941
- // destroying scene will cancel all its input events
942
- scene.destroy();
943
-
944
- const ui = add([]);
945
-
946
- ui.add(makeButton());
947
-
948
- // these will only work if ui game object is active
949
- ui.onMousePress(() => {
950
- // ...
951
- });
952
-
953
- // before you'll have to manually clean up events on obj.onDestroy()
954
- const scene = add([]);
955
- const evs = [];
956
- scene.onDestroy(() => {
957
- evs.forEach((ev) => ev.cancel());
958
- });
959
- evs.push(
960
- k.onKeyPress("space", () => {
961
- doSomeSceneSpecificStuff();
962
- }),
963
- );
964
- ```
965
-
966
- - added `make()` to create game object without adding to the scene
967
-
968
- ```js
969
- const obj = make([sprite("bean"), pos(120, 60)]);
970
-
971
- add(obj);
972
- ```
973
-
974
- - fixed children not inheriting `fixed()` from parent
975
-
976
- ```js
977
- // before
978
- const ui = add([fixed()]);
979
-
980
- ui.add([
981
- rect(),
982
- // have to also give all children game objects fixed()
983
- fixed(),
984
- ]);
985
-
986
- // now
987
- const ui = add([fixed()]);
988
-
989
- // you don't have to add fixed() to children
990
- ui.add([rect(100, 100)]);
991
- ```
992
-
993
- - fixed `AreaComp#onClick()` event not getting cleaned up when game object is
994
- destroyed
995
- - fixed typo `isTouchScreen()` -> `isTouchscreen()`
996
- - fixed inspect mode doesn't show the properties box of indirect children game
997
- objects
998
- - fixed some problem causing kaboom to not work with vite
999
- - fixed "destroy" event not run on children game objects
1000
- - calling `shake()` when another shake is happening adds to the shake instead of
1001
- reset it?
1002
- - fixed incorrect touch position when canvas is not at top left of page
1003
-
1004
- ## [3000.0.0] - 2023-05-25 (kaboom.js)
1005
-
1006
- ### Game Objects
1007
-
1008
- - added scene graph, game objects are now stored in a tree-like structure and
1009
- can have children with `obj.add()`
1010
-
1011
- ```js
1012
- const bean = add([sprite("bean"), pos(160, 120)]);
1013
-
1014
- const sword = bean.add([
1015
- sprite("sword"),
1016
- // transforms will be relative to parent bean object
1017
- pos(20, 20),
1018
- rotate(20),
1019
- ]);
1020
-
1021
- const hat = bean.add([
1022
- sprite("hat"),
1023
- // transforms will be relative to parent bean object
1024
- pos(0, -10),
1025
- ]);
1026
-
1027
- // children will be moved alongside the parent
1028
- bean.moveBy(100, 200);
1029
-
1030
- // children will be destroyed alongside the parent
1031
- bean.destroy();
1032
- ```
1033
-
1034
- - added `recursive` and `liveUpdate` options to `get()`
1035
-
1036
- ```js
1037
- const enemies = get("enemy", {
1038
- // get from all children and descendants, instead of only direct children
1039
- recursive: true,
1040
- // live update the returned list to listen to onAdd and onDestroy events
1041
- liveUpdate: true,
1042
- });
1043
-
1044
- console.log(enemies.length); // 3
1045
-
1046
- add([sprite("bigbird"), "enemy"]);
1047
-
1048
- console.log(enemies.length); // 4
1049
- ```
1050
-
1051
- - changed object update order from reversed to not reversed
1052
- - (**BREAK**) removed `GameObj#every()` and `GameObj#revery()` in favor of
1053
- `obj.get("*").forEach()`
1054
- - (**BREAK**) renamed `GameObj#_id` to `GameObj#id`
1055
- - `addLevel()` now returns a `GameObj` which has all individual grid objects as
1056
- its children game objects, with `LevelComp` containing its previous methods
1057
- - added `onAdd()` and `onDestroy()` events to listen to added / destroyed game
1058
- objects
1059
-
1060
- ### Components
1061
-
1062
- - added support for getter and setters in component properties
1063
-
1064
- #### Area
1065
-
1066
- - added collision support for rotate shapes and polygons
1067
- - added option `collisionIgnore` to `area()` component, which accepts a list of
1068
- tags to ignore when checking collision
1069
-
1070
- ```js
1071
- const bean = add([
1072
- sprite("bean"),
1073
- pos(100, 80),
1074
- area({
1075
- collisionIgnore: ["cloud", "particle"],
1076
- }),
1077
- ]);
1078
- ```
1079
-
1080
- - added `Area#getCollisions` to get a list of all current collisions happening
1081
-
1082
- ```js
1083
- for (const col of player.getCollisions()) {
1084
- const c = col.target;
1085
- if (c.is("chest")) {
1086
- c.open();
1087
- }
1088
- }
1089
- ```
1090
-
1091
- - added `Area#onCollideUpdate()` and `onCollideUpdate()` to register an event
1092
- that runs every frame when 2 objects are colliding
1093
- - added `Area#onCollideEnd()` and `onCollideEnd()` to register an event that
1094
- runs once when 2 objects stop colliding
1095
- - added `Area#onHover()` and `onHover()` to register an event that runs once
1096
- when an object(s) is hovered over
1097
- - added `Area#onHoverEnd()` and `onHoverEnd()` to register an event that runs
1098
- once when an object(s) stops being hovered over
1099
- - (**BREAK**) renamed `onHover()` to `onHoverUpdate()` (it registers an event
1100
- that runs every frame when an object is hovered over)
1101
- - (**BREAK**) renamed `pushOut()` to `resolveCollision()`
1102
-
1103
- #### Body
1104
-
1105
- - added `Body#onFall()` which fires when object starts falling
1106
- - added `Body#onPhysicsResolve()` and `Body#onBeforePhysicsResolve()` to
1107
- register events relating to collision resolution
1108
-
1109
- ```js
1110
- // make semi-solid platforms that doesn't block player when player is jumping over it
1111
- player.onBeforePhysicsResolve((collision) => {
1112
- if (collision.target.is(["platform", "soft"]) && player.isJumping()) {
1113
- collision.preventResolution();
1114
- }
1115
- });
1116
- ```
1117
-
1118
- - (**BREAK**) removed `solid()` in favor of `body({ isStatic: true })`
1119
- - added option `body({ mass: 3 })` to define how hard a non-static body is to be
1120
- pushed by another non-static body
1121
- - added option `body({ stickToPlatform: false })` to turn off object moving with
1122
- platform
1123
- - (**BREAK**) removed `Body#doubleJump()` in favor of `doubleJump()` component
1124
- - (**BREAK**) renamed `Body#weight` to `Body#gravityScale`
1125
- - (**BREAK**) renamed `Body#onFall()` to `Body#onFallOff()` which triggers when
1126
- object fall off a platform
1127
- - (**BREAK**) defining `setGravity()` is now required for enabling gravity,
1128
- `body()` by default will only prevent objects from going through each other
1129
-
1130
- #### Others
1131
-
1132
- - (**BREAK**) renamed `origin()` to `anchor()`, so it won't mess up typescript
1133
- in global mode
1134
- - (**BREAK**) `anchor` (previously `origin`) no longer controls text alignment,
1135
- use `text({ align: "left" })` option instead
1136
- - added `doubleJump()` component to enable double jump (or any number of jumps)
1137
- - (**BREAK**) renamed `outview()` to `offscreen()`, and uses a much faster check
1138
- (but less accurate) for if object is offscreen
1139
- - removed `offset` option in favor of a simpler `distance` option
1140
- - renamed `onExitView()` and `onEnterView()` to `onExitScreen()` and
1141
- `onEnterScreen()`
1142
- - (**BREAK**) removed `cleanup()` component in favor of
1143
- `offscreen({ destroy: true })`
1144
- - added `OpacityComp#fadeOut()`
1145
- - added `fadeIn()` component
1146
- - `stay()` now accepts a list of scenes to stay for, like
1147
- `stay(["gameover", "menu"])`
1148
- - (**BREAK**) changed `SpriteComp#flipX` and `SpriteComp#flipY` to properties
1149
- instead of functions
1150
- - (**BREAK**) `sprite.onAnimStart()` and `sprite.onAnimEnd()` now triggers on
1151
- any animation
1152
-
1153
- ```js
1154
- // before
1155
- obj.onAnimEnd("walk", () => {
1156
- // do something
1157
- });
1158
-
1159
- // v3000
1160
- obj.onAnimEnd((anim) => {
1161
- if (anim === "walk") {
1162
- // do something
1163
- }
1164
- });
1165
- ```
1166
-
1167
- - (**BREAK**) `ScaleComp#scale` will always be a `Vec2` not `number`
1168
- - `shader()` comp `uniform` parameter now supports a callback that returns the
1169
- uniform every frame
1170
-
1171
- ```js
1172
- const player = add([
1173
- sprite("bean"),
1174
- // will calculate and send u_time every frame
1175
- shader("flashy", () => ({
1176
- u_time: time(),
1177
- })),
1178
- ]);
1179
- ```
1180
-
1181
- ### Assets
1182
-
1183
- - added `loadProgress()` that returns a `0.0 - 1.0` that indicates current asset
1184
- loading progress
1185
- - added option `loadingScreen` to `kaboom()` where you can turn off the default
1186
- loading screen
1187
- - added `onLoadUpdate()` to register a custom loading screen (see "loader"
1188
- example)
1189
-
1190
- ```js
1191
- // custom loading screen
1192
- onLoadUpdate((progress) => {
1193
- drawCircle({
1194
- pos: center(),
1195
- radius: 32,
1196
- end: map(progress, 0, 1, 0, 360),
1197
- });
1198
- });
1199
- ```
1200
-
1201
- - added support for multiple sprite sources as frames in `loadSprite()`
1202
-
1203
- ```js
1204
- loadSprite("player", [
1205
- "sprites/player_idle.png",
1206
- "sprites/player_run.png",
1207
- "sprites/player_jump.png",
1208
- ]);
1209
- ```
1210
-
1211
- - (**BREAK**) added `loadShaderURL()`, `loadShader()` now only load shader code
1212
- not files
1213
-
1214
- ### Text
1215
-
1216
- - added `loadFont()` to load `.ttf`, `.otf`, `.woff2` or any font supported by
1217
- browser `FontFace`
1218
-
1219
- ```js
1220
- // Load a custom font from a .ttf file
1221
- loadFont("FlowerSketches", "/examples/fonts/FlowerSketches.ttf");
1222
-
1223
- // Load a custom font with options
1224
- loadFont("apl386", "/examples/fonts/apl386.ttf", {
1225
- outline: 4,
1226
- filter: "linear",
1227
- });
1228
- ```
1229
-
1230
- - (**BREAK**) renamed previous `loadFont()` to `loadBitmapFont()`
1231
- - (**BREAK**) removed built-in `apl386`, `apl386o`, `sink`, `sinko` (still
1232
- available under `examples/fonts`)
1233
- - changed default font size to `36`
1234
- - (**BREAK**) changed to bbcode syntax for styled text
1235
-
1236
- ```js
1237
- // before
1238
- "[oh hi].green here's some [styled].wavy text";
1239
- // v3000
1240
- "[green]oh hi[/green] here's some [wavy]styled[/wavy] text";
1241
- ```
1242
-
1243
- ### Graphics
1244
-
1245
- - fixed visual artifacts on text rendering
1246
- - added `colors` option to `drawPolygon()` that controls the color of each
1247
- corner
1248
- - added `gradient` option to `drawRect()` that specifies the start and end color
1249
- - added `drawMasked()` and `drawSubtracted()`
1250
- - added `pushRotateX()`, `pushRotateY()` and `pushRotateZ()`
1251
- - added `pixelDensity` option to `kaboom()`
1252
- - (**BREAK**) changed position vertex format from `vec3` to `vec2` (which is
1253
- passed in as the first argument of custom `frag` and `vert` shader functions)
1254
- - added `usePostEffect()` to add post process shader
1021
+ - Now `ScaleComp` and `SpriteComp` uses setters/getters for it's state
1255
1022
 
1256
- ```js
1257
- loadShader(
1258
- "invert",
1259
- null,
1260
- `
1261
- vec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {
1262
- vec4 c = def_frag();
1263
- return vec4(1.0 - c.r, 1.0 - c.g, 1.0 - c.b, c.a);
1264
- }
1265
- `,
1266
- );
1267
-
1268
- usePostEffect("invert");
1269
- ```
1270
-
1271
- - shader error logs now yields the correct line number
1272
- - added `slice9` option to `loadSprite()` to enable
1273
- [9 slice scaling](https://en.wikipedia.org/wiki/9-slice_scaling)
1274
-
1275
- ```js
1276
- loadSprite("grass", "/sprites/grass.png", {
1277
- slice9: {
1278
- left: 8,
1279
- right: 8,
1280
- top: 8,
1281
- bottom: 8,
1282
- },
1283
- });
1284
-
1285
- const g = add([sprite("grass")]);
1286
-
1287
- onMouseMove(() => {
1288
- const mpos = mousePos();
1289
- // updating width / height will scale the image but not the sliced frame
1290
- g.width = mpos.x;
1291
- g.height = mpos.y;
1292
- });
1293
- ```
1294
-
1295
- ### Audio
1296
-
1297
- - added option `kaboom({ backgroundAudio: false })` to not pause audio when tab
1298
- not active
1299
- - changed `speed`, `detune`, `volume`, `loop` in `AudioPlay` from functions to
1300
- properties
1301
- - added `onEnd()` event for `const pb = play("sound")`
1302
-
1303
- ```js
1304
- // before
1305
- const music = play("song");
1306
- music.speed(2);
1307
- music.volume(0.5);
1308
- music.loop(true);
1309
-
1310
- // v3000
1311
- const music = play("song");
1312
- music.speed = 2;
1313
- music.volume = 0.5;
1314
- music.loop = true;
1315
- ```
1316
-
1317
- ### Input
1318
-
1319
- - added `onScroll(action: (delta: Vec2) => void)` to listen mouse wheel scroll
1320
- - fixed touches not treated as mouse
1321
- - (**BREAK**) changed `onTouchStart()`, `onTouchMove()` and `onTouchEnd()`
1322
- callback signature to `(pos: Vec2, touch: Touch) => void` (exposes the native
1323
- `Touch` object)
1324
- - added `onGamepadButtonPress()`, `onGamepadButtonDown()`,
1325
- `onGamepadButtonRelease()`
1326
- - added `isGamepadButtonPressed()`, `isGamepadButtonDown()`,
1327
- `isGamepadButtonReleased()`
1328
- - added `onGamepadStick()` to handle gamepad axes info for left and right sticks
1329
- - added `getConnectedGamepads()`
1330
- - added `onGamepadConnect()` and `onGamepadDisconnect()`
1331
- - added `gamepads` option to `kaboom()` to define custom gamepads
1332
-
1333
- ### Level
1334
-
1335
- - (**BREAK**) changed `addLevel()` options API
1336
- - renamed `width` and `height` to `tileWidth` and `tileHeight`
1337
- - renamed `any` to `wildcardTile`
1338
- - now all tile symbols are defined in the `tiles` object
1339
-
1340
- ```js
1341
- // before
1342
- addLevel(["@ ^ $$", "======="], {
1343
- width: 32,
1344
- height: 32,
1345
- "=": () => [sprite("grass"), area(), body({ isStatic: true })],
1346
- $: () => [sprite("coin"), area(), "coin"],
1347
- any: (symbol) => {
1348
- if (symbol === "@") {
1349
- return [
1350
- /* ... */
1351
- ];
1352
- }
1353
- },
1354
- });
1355
-
1356
- // v3000
1357
- addLevel(["@ ^ $$", "======="], {
1358
- tileWidth: 32,
1359
- tileHeight: 32,
1360
- tiles: {
1361
- "=": () => [sprite("grass"), area(), body({ isStatic: true })],
1362
- $: () => [sprite("coin"), area(), "coin"],
1363
- },
1364
- wildcardTile: (symbol) => {
1365
- if (symbol === "@") {
1366
- return [
1367
- /* ... */
1368
- ];
1369
- }
1370
- },
1371
- });
1372
- ```
1373
-
1374
- ### Misc
1375
-
1376
- - sprites are now automatically packed, improving performance
1377
- - (**BREAK**) renamed `gravity()` into `getGravity()` and `setGravity()`
1378
- - (**BREAK**) removed all deprecated functions in v2000.2
1379
- - (**BREAK**) raised esbuild target to `esnext`
1380
- - added `setBackground()` and `getBackground()` in addition to `background`
1381
- option in `kaboom()`
1382
- - moved type defs for global functions to `import "kaboom/global"`
1383
-
1384
- ```js
1385
- // if use global functions
1386
- import "kaboom";
1387
- import "kaboom/global"; // required to load global types
1388
-
1389
- kaboom();
1390
-
1391
- // will have definition
1392
- add();
1393
- ```
1394
-
1395
- ```js
1396
- // if don't use global function
1397
- import "kaboom";
1398
-
1399
- kaboom({ global: false });
1400
-
1401
- // type error, won't pollute global namespace if not manually import "kaboom/global"
1402
- add();
1403
- ```
1404
-
1405
- - added `tween()` for tweening, and a set of built-in easing functions in
1406
- `easings`
1407
-
1408
- ```js
1409
- onMousePress(() => {
1410
- tween(
1411
- bean.pos.x,
1412
- mousePos().x,
1413
- 1,
1414
- (val) => (bean.pos.x = val),
1415
- easings.easeOutBounce,
1416
- );
1417
- tween(
1418
- bean.pos.y,
1419
- mousePos().y,
1420
- 1,
1421
- (val) => (bean.pos.y = val),
1422
- easings.easeOutBounce,
1423
- );
1424
- });
1425
- ```
1426
-
1427
- - (**BREAK**) changed all event handlers to return a `EventController` object
1428
- instead of a function to cancel event
1429
-
1430
- ```js
1431
- // before
1432
- const cancel = onUpdate(() => {
1433
- /* ... */
1434
- });
1435
- cancel();
1436
-
1437
- // v3000
1438
- const ev = onUpdate(() => {
1439
- /* ... */
1440
- });
1441
- ev.paused = true;
1442
- ev.cancel();
1443
- ```
1444
-
1445
- - timers can now be paused
1446
-
1447
- ```js
1448
- const timer = wait(4, () => {
1449
- /* ... */
1450
- });
1451
- timer.paused = true;
1452
- timer.resume();
1453
-
1454
- const timer = loop(1, () => {
1455
- /* ... */
1456
- });
1457
- timer.paused = true;
1458
- timer.resume();
1459
- ```
1460
-
1461
- - `kaboom()` now automatically focuses the canvas
1462
- - added `quit()` to end everything
1463
- - added `download()`, `downloadText()`, `downloadJSON()`, `downloadBlob()`
1464
- - added `Recording#stop()` to stop the recording and returns the video data as
1465
- mp4 Blob
1466
- - added `debug.numFrames()` to get the total number of frames elapsed
1467
- - added `onError()` to handle error or even custom error screen
1468
- - added `onResize()` to register an event that runs when canvas resizes
1469
- - added `setCursorLocked()` and `isCursorLocked()`
1470
- - (**BREAK**) renamed `cursor()` to `setCursor()`
1471
- - (**BREAK**) renamed `fullscreen()` to `setFullscreen()`
1472
- - (**BREAK**) renamed `isTouch()` to `isTouchscreen()`
1473
- - (**BREAK**) removed `layers()` in favor of parent game objects (see "layers"
1474
- example)
1475
- - (**BREAK**) removed `load()` event for components, use `onLoad()` in `add()`
1476
- event
1477
- - (**BREAK**) removed `debug.objCount()` in favor of `getAll().length`
1478
- - added `debug.numFrames()` to get the current frame count
1479
-
1480
- ## [2000.2.6] - 2022-01-27 (kaboom.js)
1481
-
1482
- - fixed text always being wrapped if updated
1483
- - fixed text comp properties `letterSpacing`, `charSpacing`, `transform`,
1484
- `styles` not being exposed
1485
-
1486
- ### v2000.2.5
1487
-
1488
- - fixed updating `font` property on gameobj not updating the text font
1489
-
1490
- ### v2000.2.4
1491
-
1492
- - fixed `focus()` not properly exported
1493
- - deprecated `focus()` in favor of `canvas.focus()` due to name collision
1494
-
1495
- ### v2000.2.3
1496
-
1497
- - fixed `kaboom.d.ts` completely messed up
1498
-
1499
- ### v2000.2.2
1500
-
1501
- - fixed doc for `TextCompOpt#styles` and `DrawTextOpt#styles`
1502
-
1503
- ### v2000.2.1
1504
-
1505
- - fixed updates not running at all when `kaboom({ debug: false })`
1506
-
1507
- ## [2000.2.0] "Fancy Text Mode" 2022-01-23 (kaboom.js)
1508
-
1509
- - added `formatText()` and `drawFormattedText()`
1510
- - added `charSpacing` and `lineSpacing` in `TextCompOpt` and `DrawTextOpt`
1511
- - added optional `transitions` argument in `state()` to define allowed
1512
- transitions
1513
- - added `StateComp#onStateTransition` to register event for specific transitions
1514
- - added syntax to style a piece of text `"this is a [styled].wavy text"` and
1515
- `style` option in `TextCompOpt` and `DrawTextOpt` to define the styles with
1516
- `CharTransformFunc`
1517
- - deprecated `dir()` in favor of `Vec2.fromAngle()`
1518
- - fixed `onTouchEnd()` fired on `touchmove`
1519
- - added `outview()` component to control behavior when object leaves visible
1520
- area
1521
- - deprecated `cleanup(delay?: number)` in favor of `cleanup(opt?: CleanupOpt)`
1522
- - deprecated `mouseWorldPos()` in favor of `toWorld(mousePos())`
1523
- - deprecated `rng()` in favor of `new RNG()`
1524
- - added classes `Vec2`, `Color`, `Mat4`, `Timer`, `Quad`, `RNG`, `Line`, `Rect`,
1525
- `Circle`
1526
- - added deprecation warning
1527
- - fixed letterbox view mode
1528
- - allow non-stretch letterbox
1529
- - fixed mouse position malfunction in fullscreen, stretch and letterbox mode
1530
-
1531
- ### [2000.1.8]
1532
-
1533
- - fixed `Color#eq()` not giving correct result
1534
-
1535
- ### v2000.1.7
1536
-
1537
- - fixed not having export if installed from github repo with npm
1538
- - fixed event canceller returned by raw `onUpdate()` and `onDraw()` crashing
1539
-
1540
- ### v2000.1.6
1541
-
1542
- - fixed debug widget scale
1543
-
1544
- ### v2000.1.5
1545
-
1546
- - fixed `enterState()` not passing args to `onStateEnter()` callback
1547
-
1548
- ### v2000.1.4
1549
-
1550
- - fixed `state()` to not require registering `onStateUpdate()` before using any
1551
- state
1552
-
1553
- ### v2000.1.2
1554
-
1555
- - fixed `onKeyRelease()` wrongfully check for key press instead of release
1556
-
1557
- ### v2000.1.1
1558
-
1559
- - fixed `StateComp#enterState()` not accepting any state
1560
-
1561
- ## [2000.1.0] "Record Mode" - 2021-11-04 (kaboom.js)
1562
-
1563
- - added `hsl2rgb()` for converting HSL color to kaboom RGB
1564
- - added `record()` to start a screen recording
1565
- - added F5 to screenshot and F6 to toggle record mode in debug mode
1566
- - added `DrawTextOpt#transform()` and `TextCompOpt#transform()` for defining
1567
- style and transformation for each character
1568
- - added `state()` component for finite state machine
1569
- - added support for multiple tags in `get()` and `every()`
1570
- - added UI indicator for `debug.paused` and `debug.timeScale`
1571
- - changed inspect mode UI style
1572
- - added color constants `WHITE`, `BLACK`, `BLUE`, `GREEN`, `RED`, `MAGENTA`,
1573
- `CYAN`, `YELLOW`
1574
- - added new API style (`on` prefix for all event handler function, `is` prefix
1575
- for all boolean state getters)
1576
- - `onLoad()`
1577
- - `onUpdate()`
1578
- - `onDraw()`
1579
- - `onKeyPress()`
1580
- - `onKeyPressRepeat()`
1581
- - `onKeyDown()`
1582
- - `onKeyRelease()`
1583
- - `onMousePress()`
1584
- - `onMouseDown()`
1585
- - `onMouseRelease()`
1586
- - `onMoueMove()`
1587
- - `onTouchStart()`
1588
- - `onTouchMove()`
1589
- - `onTouchEnd()`
1590
- - `onCollide()`
1591
- - `onClick()`
1592
- - `onHover()`
1593
- - `isFocused()`
1594
- - `isKeyDown()`
1595
- - `isKeyPressed()`
1596
- - `isKeyPressedRepeat()`
1597
- - `isKeyDown()`
1598
- - `isMouseDown()`
1599
- - `isMousePressed()`
1600
- - `isMouseReleased()`
1601
- - `isMouseMoved()`
1602
- - `isMouseMoved()`
1603
- - `GameObj#onUpdate()`
1604
- - `GameObj#onDraw()`
1605
- - `AreaComp#onCollide()`
1606
- - `AreaComp#onHover()`
1607
- - `AreaComp#onClick()`
1608
- - `BodyComp#onGround()`
1609
- - `BodyComp#onFall()`
1610
- - `BodyComp#onHeadbutt()`
1611
- - `BodyComp#onDoubleJump()`
1612
- - `BodyComp#isGrounded()`
1613
- - `BodyComp#isFalling()`
1614
- - `SpriteComp#onAnimEnd()`
1615
- - `SpriteComp#onAnimStart()`
1616
- - `HealthComp#onDeath()`
1617
- - `HealthComp#onHurt()`
1618
- - `HealthComp#onHeal()`
1619
- - `AudioPlay#isStopped()`
1620
- - `AudioPlay#isPaused()`
1621
-
1622
- ## [2000.0.0] "Burp Mode" - 2021-10-20 (kaboom.js)
1623
-
1624
- - version jumped to v2000.0.0 (still semver, just big)
1625
- - added `burp()` for easy burping
1626
- - added decent typescript / autocomplete support and jsdocs
1627
- - introducing new character "bean" ![bean](assets/sprites/bean.png)
1628
- - added `loadBean()` to load `"bean"` as a default sprite
1629
- - changed default font to [APL386](https://abrudz.github.io/APL386/), as
1630
- `"apl386o"` (default outlined version) and `"apl386"`
1631
- - included font
1632
- [kitchen sink](https://polyducks.itch.io/kitchen-sink-textmode-font) as
1633
- `"sinko"` (outlined version) and `"sink"` (standard version with extended
1634
- characters for text-mode games)
1635
- - added `font` field in `KaboomOpt` to set the default font
1636
- - added `loadSpriteAtlas(src, entries)` to load sprite atlas
1637
- - inspect mode now displays every comp's state
1638
- - **BREAK** added continuous collision resolution which checks collision in
1639
- `move()` if 2 objects are both "solid" (objects now won't pass through other
1640
- solid object at high speed or low framerate)
1641
-
1642
- ```js
1643
- // before
1644
- add([sprite("player"), area()]);
1645
-
1646
- add([sprite("rock"), solid()]);
1647
-
1648
- keyDown("left", () => {
1649
- player.move(-120, 0);
1650
- });
1651
-
1652
- player.action(() => {
1653
- player.resolve(); // or pushOutAll() in beta versions
1654
- });
1655
-
1656
- // after
1657
- const player = add([sprite("player"), area(), solid()]);
1658
-
1659
- // both should be solid
1660
- add([sprite("rock"), area(), solid()]);
1661
-
1662
- keyDown("left", () => {
1663
- // this will handle collision resolution for you, if the other obj is also "solid"
1664
- player.move(-120, 0);
1665
- });
1666
- ```
1667
-
1668
- - added comp `opacity()` to set opacity
1669
- - added comp `health()` to manage health related logic
1670
- - added comp `move()` to manage projectile-like behavior
1671
- - added comp `cleanup()` to auto destroy obj when it leaves screen
1672
- - added comp `outline()` to draw a lil outline
1673
- - added comp `timer()` to attach timers to a game obj
1674
- - added comp `fixed()` to make a game obj unaffected by camera
1675
- - added comp `stay()` to make a game obj stay after scene switch
1676
- - added comp `lifespan()` to destroy game obj after certain amount of time
1677
- - added comp `z()` to define draw order for objs on the same layer
1678
- - added `weight` to `BodyComp` and `BodyCompOpt` to control the gravity
1679
- multiplier
1680
- - added `djump()` to `BodyComp` for double jump
1681
- - added `dir()` to calculate directional vector from angle
1682
- - added constants `LEFT`, `RIGHT`, `UP`, `DOWN` for unit directional vector
1683
- - added `fullscreen()` to enable real fullscreen mode
1684
- - **BREAK** separated color and opacity, removed `rgba()` in favor of `rgb`, use
1685
- component `opacity()` to define opacity
1686
- - **BREAK** changed color from 0-1 range to 0-255, angles from radians to
1687
- degrees
1688
-
1689
- ```js
1690
- // before
1691
- add([rotate(Math.PI / 2), color(0, 0.5, 1.0, 0.5)]);
1692
-
1693
- // after
1694
- add([rotate(90), color(0, 127, 255), opacity(0.5)]);
1695
- ```
1696
-
1697
- - `global` and `debug` flag now are enabled by default, need to turn off
1698
- manually if you don't want
1699
- - added input events `touchStart(id, pos)`, `touchMove(id, pos)`,
1700
- `touchEnd(id, pos)`, `mouseMove(pos)`
1701
- - added `mouseDeltaPos()`
1702
- - added `touchToMouse` to control if touch events should be translated to mouse
1703
- events
1704
- - added `mousePos()` now gets the screen mouse pos, use `mouseWorldPos()` to get
1705
- the mouse position affected by camera
1706
- - added `anim` field in `SpriteCompOpt` to play an anim on start
1707
- - better type support for components
1708
- - `scene()` and `start()` (also removed in favor of `go()`) are optional now, if
1709
- you don't need multiple scenes yet you can just go directly
1710
-
1711
- ```js
1712
- kaboom();
1713
- // no mandatory scene() to start kabooming
1714
- add(...);
1715
- keyPress(...);
1716
- ```
1717
-
1718
- - **BREAK** `area()` is now explicit and not automatically added by `sprite()`,
1719
- `rect()`, and `text()`, removed each `noArea` or `area` config field
1720
- - **BREAK** `area()` now takes an `AreaCompOpt`, where you can define the area
1721
- size, scale, and hover cursor
1722
-
1723
- ```js
1724
- add([
1725
- sprite("bean"),
1726
- area(), // empty area will derive from sprite size
1727
- area({ scale: 0.5 }), // 0.5x the sprite size
1728
- area({ offset: vec2(0, 12), width: 4, height: 12 }), // more control over the collider region
1729
- ]);
1730
- ```
1731
-
1732
- - **BREAK** renamed `isCollided()` to `isColliding()`, `isHovered()` to
1733
- `isHovering()`
1734
- - **BREAK** removed `overlaps()` and `isOverlapped()` and replaced with
1735
- `isColliding()` and `collides()` only checks doesn't return true when 2
1736
- objects are just touching each other, use `isTouching()` to check if they're
1737
- not colliding but just touching each other
1738
- - added `isTouching()` to check if 2 objects are collided or just touching other
1739
- - audio is now paused when you leave the tab
1740
- - audio is now paused on `debug.paused = true`
1741
- - added local storage helper `getData(key, default?)` and `setData(key, data)`
1742
- - added `loadShader(id, vert, frag, isUrl)`
1743
- - added `shader()` comp for attaching custom shader to an obj
1744
- - different layers do not prevent collisions now
1745
- - **BREAK** changed last argument of `loadFont()` to `FontLoadOpt`
1746
- - all event handlers like `keyPress()`, `mouseClick()`, `action()`, `collides()`
1747
- now returns a function to cancel that listener
1748
- - added `require` on component definitions, making it possible to declare
1749
- dependencies for components, e.g.
1750
-
1751
- ```js
1752
- function alwaysRight() {
1753
- return {
1754
- // the id of this component
1755
- id: "alwaysRight",
1756
- // list of component ids that this requires
1757
- require: ["pos"],
1758
- update() {
1759
- // so you can use `move()` from pos() component with no worry
1760
- this.move(100, 0);
1761
- },
1762
- };
1763
- }
1764
- ```
1765
-
1766
- - **BREAK** overlapping component fields are not allowed, e.g. you can't have a
1767
- custom comp that has a `collides` field if it already have a `area` component,
1768
- since it already has that
1769
- - **BREAK** changed `text(txt, size, conf)` to `text(txt, conf)` with `size` as
1770
- a field
1771
- - added `obj.c(id)` for getting a specific comp's state (by default all comps'
1772
- states are mounted to the obj by `Object.defineProperty`)
1773
-
1774
- ```js
1775
- // both works
1776
- obj.play("anim");
1777
- obj.c("sprite").play("anim");
1778
- ```
1779
-
1780
- - pedit, aseprite plugins are now included by default
1781
- - added `addKaboom()` for quick kaboom explosion
1782
- - `load*()` now accepts `null` as name and not load into assets manager, instead
1783
- just return the resource data handle
1784
- - **BREAK** renamed event `headbump` to `headbutt`
1785
- - **BREAK** renamed event `grounded` to `ground`
1786
- - added `width`, `height`, and `tiled` attrib to `SpriteCompOpt`, for better
1787
- control over sprite size and tiled sprite support
1788
- - **BREAK** renamed `resolve()` to `pushOutAll()` on `area` comp
1789
- - added `pushOut()` for pushing a single object out from another with `area`
1790
- comp
1791
- - fixed `"add"` event getting called twice for tagged objs
1792
- - added `moveTo(dest: Vec2, speed?: number)` to `pos()` comp
1793
- - added `keyPress()` (and all other key events) with no arg to check for any key
1794
- - **BREAK** renamed `camShake()` to `shake()`
1795
- - added `flipX` and `flipY` on `sprite()` comp configuration, and `flipX()`
1796
- `flipY()` methods
1797
- - **BREAK** remove `flipX()` and `flipY()` on `scale()` comp
1798
- - **BREAK** removed `start()` in favor of `go()`
1799
- - **BREAK** removed `changeSprite()` in favor of `use(sprite("newsprite"))`
1800
- - tags and components are converged, tags are just empty components now
1801
- - added `unuse()` to remove a component or tag
1802
- - **BREAK** removed `rmTag()` in favor of `unuse()`
1803
- - **BREAK** removed `camIgnore()` in favor of `fixed()`
1804
- - **BREAK** renamed `makeRng()` to `rng()`
1805
- - sprite animation now supports defining properties like loop and speed in load
1806
- step and play step
1807
-
1808
- ```js
1809
- loadSprite("hero", "hero.png", {
1810
- sliceX: 9,
1811
- anims: {
1812
- idle: { from: 0, to: 3, speed: 3, loop: true },
1813
- run: { from: 4, to: 7, speed: 10, loop: true },
1814
- hit: 8,
1815
- },
1816
- });
1817
- ```
1818
-
1819
- - **BREAK** changed `.play(anim, ifLoop)` under `sprite()` to accept a dict of
1820
- properties `.play(anim, { loop: true, speed: 60, pingpong: true })`
1821
- - **BREAK** now every symbol definition in `addLevel()` should be a function
1822
- returning the component list, to ensure there's no weird shared states
1023
+ ```js
1024
+ const obj = add([sprite("bean"), scale(2)]);
1823
1025
 
1824
- ```js
1825
- addLevel(["* *", "* *", "======"], {
1826
- "*": () => [sprite("wall"), area(), solid()],
1827
- "=": () => [sprite("floor"), area(), solid()],
1828
- });
1829
- ```
1026
+ // set it with = syntax
1027
+ obj.scale = vec2(3, 4);
1028
+ obj.sprite = "bag";
1029
+ ```
1830
1030
 
1831
- - **BREAK** renamed `clearColor` to `background`
1832
- - added collision detection functions `testLineLine()`, `testRectRect()`,
1833
- `testRectLine()` etc.
1834
- - added drawing functions `drawSprite()`, `drawRect()`, `drawCircle()`,
1835
- `drawPolygon()`, `drawEllipse()`, `drawLine()`, `drawLines()`
1836
- - added transformation functions `pushTransform()`, `popTransform()`,
1837
- `pushTranslate()`, `pushRotate()`, `pushScale()`
1838
- - **BREAK** removed `areaWidth()` and `areaHeight()` since they won't make sense
1839
- if the area shape is not rectangle, use `worldArea()` if you need area data
1031
+ - Now you can type `get()` with a type parameter and passing component types
1840
1032
 
1841
- ```js
1842
- const area = player.worldArea();
1843
- if (area.shape === "rect") {
1844
- const width = area.p2.x - area.p1.x;
1845
- const height = area.p2.y - area.p1.y;
1846
- }
1847
- ```
1033
+ ```ts
1034
+ const player = get<BodyComp>("player");
1035
+ ```
1848
1036
 
1849
- ### v0.5.1
1850
-
1851
- - added plugins npm package support e.g.
1852
- `import asepritePlugin from "kaboom/plugins/aseprite"`
1853
-
1854
- ## [0.5.0] "Sticky Type" - 2021-05-11 (kaboom.js)
1855
-
1856
- - platforms are now sticky
1857
- - moved to TypeScript
1858
- - improved graphics performance
1859
- - improved inspect drawing performance
1860
- - added on-screen log that catches all kinds of errors
1861
- - added `cursor()`
1862
- - added `curPlatform()` by `body()`
1863
- - added `falling()` by `body()`
1864
- - added `changeSprite()` by `sprite()`
1865
- - added `duration()` and `time()` for the handle returned by `play()`
1866
- - added optional `seek` field to the audio play conf `play([conf])`
1867
- - added `LoopHandle` returned by `loop()` that has a `stop()`
1868
- - added a default background (can be dismissed by setting `clearColor`)
1869
- - fixed `sound.pause()` to work on firefox
1870
- - fixed collisions not treating explicit default layer the same as implicit
1871
- default layer
1872
- - fixed unable to play another anim in `onAnimEnd()`
1873
- - fixed scene switches happen in the middle of a frame
1874
- - fixed `scale(0)` not working
1875
- - fixed `mousePos()` not returning the camera affected pos with no layers
1876
- - **BREAK** changed `dbg()` to plain `debug` object
1877
- - **BREAK** moved `fps()`, `objCount()`, `stepFrame()`, `log()`, `error()` under
1878
- `debug`
1879
- - **BREAK** removed `debug.logTime`
1880
- - **BREAK** changed component `debugInfo()` hook to `inspect()`
1881
- - **BREAK** removed `timer()` component
1882
- - **BREAK** renamed `removeTag()` to `rmTag()`
1883
- - **BREAK** changed `SpriteAnim` from `[ from, to ]` to
1884
- `{ from: number, to: number }`
1885
- - **BREAK** removed `onAnimPlay()` and `onAnimEnd()` in favor of generic event
1886
- `on("animEnd", (anim: string) => {})`
1887
- - **BREAK** removed `obj.addTag()` in favor of `obj.use()`
1888
- - **BREAK** merged `debug.hoverInfo` and `debug.showArea` into `debug.inspect`
1889
- - **BREAK** removed `sound.resume()` in favor of `sound.play()`
1890
-
1891
- ### v0.4.1
1892
-
1893
- - fixed `on("destroy")` handler getting called twice
1894
- - fixed sprite `play()` not playing
1895
-
1896
- ## [0.4.0] "Multiboom" - UNKNOWN (kaboom.js)
1897
-
1898
- - **BREAK** removed `init()` and `kaboom.global()`, in favor of `kaboom()`, also
1899
- allows multiple kaboom games on one page
1037
+ - Now you can pass an `AudioBuffer` to `loadSound()`
1038
+ - Now `debug.log()` accepts multiple argument of any type, like `console.log()`
1039
+ - Now `Key` also accepts a string as an acceptable value
1040
+ - Now `text()` component doesn't require to pass a string
1041
+ - Now `camScale()` and `camPos()` accept only 1 number as parameter
1042
+ - Now `shake()` can be called without args
1043
+ - Now `loadShader()` and `loadShaderURL()` accepts null for unused parameters
1044
+ - Now `RectCompOpt` accepts a array of numbers for `radius`
1900
1045
 
1901
- ```js
1902
- // replaces init(), and added a 'global' flag for previous kaboom.global()
1903
- kaboom({
1904
- global: true,
1905
- width: 480,
1906
- height: 480,
1907
- });
1908
- ```
1046
+ ### Deprecated
1909
1047
 
1910
- or not global
1048
+ - Deprecated `kaboom()` in favor of `kaplay()` (you can still use `kaboom*`)
1049
+ - Deprecated `SpriteComp.curAnim()` in favor of `SpriteComp.getCurAnim().name`
1050
+ - Deprecated `fadeIn` component in favor of `OpacityComp.fadeIn()`
1051
+ - Deprecated `Event`, `EventHandler` and `EventController` in favor of `KEvent`,
1052
+ `KEventHandler` and `KEventController`
1911
1053
 
1912
- ```js
1913
- const k = kaboom();
1914
- k.scene();
1915
- k.start();
1916
- k.vec2();
1917
- ```
1054
+ ### Removed
1918
1055
 
1919
- - **BREAK** changed `clearColor` on `kaboom(conf)` to accept a 4 number array
1920
- instead of `rgba()`
1921
- - added a plugin system, see the `multiboom` example and `src/plugins`
1922
- - **BREAK** removed support for `.kbmsprite`, supports newer version of `.pedit`
1923
- through pedit plugin
1924
- - **BREAK** `loadAseprite()` and made it an external plugin under
1925
- `plugins/aseprite.js`
1926
- - added `sceneData()` for custom scene data kv store
1927
- - fixed `mouseClick` doesn't work on mobile
1928
- - disabled context menu on canvas
1929
- - prevented default behavior for 'tab' and function keys
1930
- - added `numFrames()` by `sprite()`
1931
- - added `screenshot()` that returns of a png base64 data url for a screenshot
1932
-
1933
- ## [0.3.0] "King Dedede...Bug!" - UNKNOWN
1934
-
1935
- - **BREAK** removed `pause()` and `paused()` in favor to `kaboom.debug.paused`
1936
- - **BREAK** removed `velY`, `curPlatform` and `maxVel` fields by `body()`
1937
- - **BREAK** changed `curAnim` by `sprite()` to method `curAnim()`
1938
- - fixed `dt()` surge on page visibility change (#20)
1939
- - pause audio when page is not visible
1940
- - added built in debug control with `init({ debug: true, })`
1941
- - `` ` ``: toggle `showLog` (default on with `debug: true`)
1942
- - `f1`: toggle `showArea`
1943
- - `f2`: toggle `hoverInfo`
1944
- - `f8`: toggle `paused`
1945
- - `f7`: decrease `timeScale`
1946
- - `f9`: increase `timeScale`
1947
- - `f10`: `stepFrame()`
1948
- - added on screen logging with `log()` and `error()`
1949
- - fixed `loadRoot()` sometimes doesn't work in async tasks
1950
-
1951
- ## [0.2.0] "Hear the Tremble" - UNKNOWN
1952
-
1953
- - **BREAK** removed `aseSpriteSheet` conf field from
1954
- `loadSprite(name, src, conf)`
1955
- - added `pause()`, `resume()`, `stop()`, `loop()`, `unloop()`, `volume()`,
1956
- `detune()`, `speed()` methods to the handle returned by `play()`
1957
- - added `camShake()` for built in camera shake
1958
- - added `loadAseprite(name, imgSrc, jsonSrc)`
1959
- - added area component generation for `text()`
1960
- - added `noArea` to conf field of `sprite()`, `rect()` and `text()`, allowing to
1961
- disable auto area component generation
1962
- - added a `quad` field to sprite comp creation config
1963
- `sprite(id, { quad: quad(0, 0, 0.5, 0.5) })`
1964
- - fixed `resolve()` not working if the obj also has `solid`, so it does not
1965
- check for itself (#8)
1966
- - `mousePos()` accepts a layer argument, which returns the mouse position
1967
- affected by camera transform if that layer is not `camIgnore()`-ed
1968
- - fixed camera position getting calculated before completing every object's
1969
- update (#14)
1970
- - fixed some cases `on("grounded", f)` called multiple times when moving on a
1971
- smooth platform
1972
- - added `revery()` to iterate objects in reverse order
1973
- - added `readd()` to re-add an object to the scene without triggering events
1974
- - added `level.spawn()`
1975
-
1976
- ## [0.1.0] "Oh Hi Mark" -
1977
-
1978
- - **BREAK** changed default origin point to `"topleft"`, so if you want object
1979
- origin point to be at center you'll need to manual `origin("center")`
1980
- - **BREAK** integrated `kit/physics` and `kit/level` to main lib
1981
- - **BREAK** makes `collides()` only run on first collision, not run every frame
1982
- during the same collision
1983
- - **BREAK** `camPos()` by default focuses to center, so `camPos(player.pos)`
1984
- puts player in the center of the screen
1985
- - **BREAK** renamed `kaboom.import()` to `kaboom.global()`
1986
- - added an arg field to `start(scene, ...)` to forward args to start scene
1987
- - added `camScale()`, `camRot()` and `camIgnore()`
1988
- - added `obj.overlaps()` by `area()`, and `overlaps()`
1989
- - added 3 ext fonts under `ext/fonts`
1056
+ - **(!)** Removed compatibility to use two KAPLAY frames in the same page
1057
+ - **(!)** Many TypeScript definitions were fixed, if you use TypeScript now
1058
+ maybe you see new errors that make your code strict
1059
+ - Fix error screen not showing with not Error object
1060
+ - Fix error where debug screen was scaling bad the blue rectangles
1061
+ - Fix error where error screen was not showing when the error was thrown in a
1062
+ input event
1063
+ - Fix error where fonts was cropped in the bottom
1064
+ - Fix an error where `stay()` object loose their input events on scene change