Changelog for v3001
[unreleased]
Fixed
- Fixed compatibility issues when calculating font height with missing TextMetrics props - @imaginarny
[3001.0.19] - 2025-06-15
- Fixed
AreaComp#onClick()attaching events to app, instead of object, so event wasn’t being paused withobj.paused- @lajbel - Fixed all touch events having a bad transform - @lajbel
[3001.0.18] - 2025-05-16
Fixed
- Removed beant - @lajbel
- Fixed TexPacker loading big images - @lajbel, @mflerackers
- Various fixes and improvements - All Contributors
[3001.0.17] - 2025-05-08
Added
- New way to import globals in JS
/dist/types.d.ts
Fixed
- Removed beant - @lajbel
- Various fixes and improvements - All Contributors
[3001.0.16] - 2025-04-18
Fixed
- Removed beant - @lajbel
- Various fixes and improvements - All contributors
[3001.0.15] - 2025-04-18
Fixed
- Various fixes and improvements - All contributors
[3001.0.14] - 2025-04-18
Fixed
- Various fixes and improvements - All contributors
[3001.0.13] - 2025-04-18
Fixed
- Various fixes and improvements - All contributors
[3001.0.12] - 2025-04-12
Fixed
- Blockers - @lajbel
[3001.0.11] - 2025-04-12
Added
-
Added CSS Colors! 🎨 - @lajbel (based on @dragoncoder047 idea)
color("slateblue"); color("red"); color("wheat"); color("tomato"); // yum! -
Added
loadHappy()font to load a default font, happy :D - @lajbelkaplay({ font: "happy" }); loadHappy(); add([text("ohhi")]);
Fixed
[3001.0.10] - 2025-03-22
Added
-
Added new option in
LoadSpriteOptfor loading sprites in an individual spritesheet - @chqs-gitloadSprite("player", "sprites/player.png", { singular: true, }); -
Frame option for load animations with singular frames - @dragoncoder047
loadSpriteAtlas("/examples/sprites/dungeon.png", { wizard: { x: 128, y: 140, width: 144, height: 28, sliceX: 9, anims: { bouncy: { frames: [8, 5, 0, 3, 2, 3, 0, 5], speed: 10, loop: true, }, }, }, }); add([sprite("wizard", { anim: "bouncy" }), pos(100, 100)]);
Fixed
- Args were not being passed to global
trigger()- @lajbel - AreaComp.onClick now returns the correct type, KEventController, instead of void - @lajbel
- Lifespan was using async - @lajbel
- Wrong calculation in Vector.dot() - @andrenanninga
- Fixed pointer lock undefined catch error for non-promise version - @imaginarny
[3001.0.9] - 2025-01-15
Added
- (examples) Added a new
particleexample! - @lajbel
Changed
- Improved
lifespan()explanation - @lajbel - (examples)
particleexample renamed tolifespan- @lajbel
Fixed
- Fixed a bug where
lifespan()was working incorrectly - @lajbel
[3001.0.8] - 2025-01-15
Fixed
- Fixed a bug where alpha channel wasn’t correctly setted - @mflerackers
[3001.0.7] - 2025-01-15
Added
- Added
kaplay({ spriteAtlasPadding })for setting the space between the sprites in the sprite atlas - @marianyp
kaplay({
spriteAtlasPadding: 10, // 10 pixels of space between each sprite
});
Changed
- Now you cannot pass parameters that are not a component or string to
.use(). Otherwise it will throw an error - @lajbel
Fixed
- Fixed a bug where font atlas were working strange - @mflerackers
[3001.0.6] “Santa Events” - 2024-12-27
Added
-
Added
trigger(event, tag, ...args)for global triggering events on a specific tag - @lajbeltrigger("shoot", "target", 140); on("shoot", "target", (obj, score) => { obj.destroy(); debug.log(140); // every bomb was 140 score points! }); -
Added
{ override?: true }inCharTransformfor overridding text styles - @dragoncoder047add([ pos(100, 150), text("With override: Hello [foo]styled[/foo] text", { transform: { color: BLACK, // Default text color for every character }, styles: { foo: { color: RED, // [foo] will be red override: true, // will override the black def color }, }, }), ]); -
Added
TextCompOpt.identAllboolean to indent every new line - @dragoncoder047 -
Added TypeScript definition for all App Events and missing Game Object Events - @lajbel
Fixed
- Fixed an incorrect mention to the component in
TextInputComptype - @dragoncoder047
[3001.0.5] - 2024-12-18
Added
-
Added tags and components separation in
KAPLAYOpt.tagsAsComponents -
Added
GameObjRaw.is(),GameObjRaw.tag()andGameObjRaw.untag()to check, add and remove tags -
Added
GameObjRaw.has()to check if a game object has a component tags -
Added events for listen to comps being removed or added
onUse()andonUnused() -
Added
cancel()to cancel the current eventonKeyPress("space", () => { // do something // cancel the event return cancel(); }); -
Added
getDefaultLayer()to get the default layer -
Added
getLayers()to get the layers list -
Added many JSDoc specifiers on many functions (@require, @deprecated, @since, @group, etc)
Changed
- Added
.use(),.unuse()and.has()toGameObjRaw, to add, remove and check components. This only works withKAPLAYOpt.tagsAsComponentsset totrue
Deprecated
- Deprecated camera methods
camScale(),camPos()andcamRot()in favor ofsetCamScale(),getCamScale(),setCamPos(),getCamPos(),setCamRot()andgetCamRot() - Deprecated
camTransform()in favor ofgetCamTransform() - Deprecated
camFlash()in favor offlash(), for ashake()-like name
Fixed
- Fixed artifacts present in some TrueType fonts
- Fixed
.use()and.unuse()with area components
[3001.0.0] - 2024-10-31
Added
-
Added
getTreeRoot()to get the game’s root object, which is the parent of all other objects// get the root object const root = getTreeRoot(); root.add(); // same as add() root.get(); // same as get() -
Added Buttons API for using Input bindings,
onButtonPress(),onButtonRelease(),onButtonDown(), and it’s corresponding boolean versions,isButtonPressed(),isButtonDown()andisButtonReleased()kaplay({ // bind your buttons buttons: { jump: { keyboard: ["space", "up"], keyboardCode: "Space", // you can also use key codes gamepad: ["south"], }, }, }); onButtonPress("jump", () => { player.jump(); }); -
Added
getButton(btn)andsetButton(btn)to get and set button bindings// ["space", "up"] debug.log(getButton("jump").keyboard); // change the jump button in keyboard to "w" setButton("jump", { keyboard: ["w"], // gamepad binding is not changed }); -
Added
getLastInputDeviceType()to get what was the last pressed deviceonButtonPress(() => { const lastInputDevice = getLastInputDeviceType(); // keyboard, mouse or gamepad // change icons, etc }); -
Added
pressButton(btn)andreleaseButton(btn)to simulate button press and releasepressButton("jump"); // triggers onButtonPress and starts onButtonDown releaseButton("jump"); // triggers onButtonRelease and stops onButtonDown -
Added
GameObjRaw.tagsto get a game object’s tagsconst obj = add([sprite("bean"), "enemy", "dangerous"]); // get the tags debug.log(obj.tags); // ["enemy", "dangerous"] -
Added the
animate()component to animate the properties of an object using keyframes. Check out Animation Example// prop to animate, frames, options rotatingBean.animate("angle", [0, 360], { duration: 2, direction: "forward", }); -
Readded
layers()and thelayer()componentBefore the
z()component, there was alayer()component that allowed you to control the draw order of objects. It was removed in v3000, but now it’s back from the void.// define the layers layers( [ "bg", "game", "ui", // the default layer ], "game", ); // use the layer component add([sprite("bg"), layer("bg")]); -
Added
SpriteComp.hasAnim()to check if an animation existsconst obj = add([sprite("bean", { anim: "walk" })]); // check if an animation exists debug.log(obj.hasAnim("walk")); // true -
Added
SpriteComp.getAnim()for get any animation dataloadSprite("bean", "bean.png", { sliceX: 4, sliceY: 1, anims: { walk: { from: 0, to: 3, }, }, }); const obj = add([sprite("bean")]); // get the animation data debug.log(obj.getAnim("walk")); // { from: 0, to: 3 } -
Added
SpriteComp.getCurAnim()to get the current animation dataconst obj = add([sprite("bean", { anim: "walk" })]); // get the current animation name debug.log(obj.getCurAnim().name); // "walk" -
Added
camFlash()to flash the screencamFlash(0.5, 0.5, 0.5, 0.5); -
Added support for radius in individual corners for
RectComp,radiusadd([ rect(100, 100, { radius: [10, 20, 30, 40], }), ]); -
Added
loadMusic()to load streaming audio (doesn’t block in loading screen)loadMusic("bgm", "bgm.mp3"); // play the music play("bgm"); -
Added
Vec2.fromArray()to convert an array to aVec2const point = Vec2.fromArray([100, 200]); // vec2(100, 200); -
Added
Vec2.toArray()to convert aVec2to an arrayconst point = vec2(100, 200); const arr = point.toArray(); // [100, 200] -
Added
chooseMultiple()to choose a random element from an arrayconst numbers = [1, 2, 3, 4, 5]; const random = chooseMultiple(numbers, 3); // [3, 1, 5] -
Added
shuffle()to shuffle an arrayconst numbers = [1, 2, 3, 4, 5]; shuffle(numbers); // [3, 1, 5, 2, 4] -
Added
KAPLAYOpt.debugKeyfor customizing the key used to toggle debug modekaplay({ debugKey: "l", }); -
Added compatibility with custom properties in debug mode
const obj = add([ sprite("bean"), { health: 100, // on debug.inspect damage: 10, // on debug.inspect hp() { this.health -= this.damage; }, // not on debug.inspect }, ]); // see the custom properties in debug mode debug.inspect = true; -
Added effector components:
areaEffector(),buoyancyEffector(),pointEffector(),surfaceEffector() -
Added
constantForce()component -
Added
pathfinder()component to calculate a list of waypoints on a graph -
Added
patrol()component to move along a list of waypoints -
Added
sentry()component to notify when certain objects are in sight -
Added
NavMeshclass for pathfinding on a mesh -
Added
particles()component to emit and draw particles -
Added
SpriteComp.animFrameto get the frame of the current animation (not on the spritesheet) -
Added
outline(),shader(), andarea()properties todebug.inspect -
Added
getSceneName()to get the current scene name -
Added
Color.toArray()to convert a color to an array -
Added
raycastandLevelComp.raycastmethod to level -
Added support for textured polygons
-
Added support for concave polygon drawing
-
Added support for arrays in uniforms
-
Added support for texture larger than 2048x2048
-
Added support for gravity direction
-
Added line join (bevel, miter, round) and line caps (square, round)
-
Added quadratic bezier and Catmull-Rom evaluation
-
Added evaluation of the first and second derivatives for all splines
-
Added higher order easing functions linear, steps and cubic-bezier
Changed
-
Now collision checks are only done if there’s area objects
-
Now you can use arrays in all input handlers
onKeyPress(["w", "up"], () => { player.jump(); }); -
Now gamepad events return what gamepad triggered the action
onGamepadButtonPress("south", (btn, gp) => { console.log(gp.index); // gamepad number on navigator's gamepad list }); -
Now
ScaleCompandSpriteCompuses setters/getters for it’s stateconst obj = add([sprite("bean"), scale(2)]); // set it with = syntax obj.scale = vec2(3, 4); obj.sprite = "bag"; -
Now you can type
get()with a type parameter and passing component typesconst player = get<BodyComp>("player"); -
Now you can pass an
AudioBuffertoloadSound() -
Now
debug.log()accepts multiple argument of any type, likeconsole.log() -
Now
Keyalso accepts a string as an acceptable value -
Now
text()component doesn’t require to pass a string -
Now
camScale()andcamPos()accept only 1 number as parameter -
Now
shake()can be called without args -
Now
loadShader()andloadShaderURL()accepts null for unused parameters -
Now
RectCompOptaccepts a array of numbers forradius
Deprecated
- Deprecated
kaboom()in favor ofkaplay()(you can still usekaboom*) - Deprecated
SpriteComp.curAnim()in favor ofSpriteComp.getCurAnim.name() - Deprecated
fadeIncomponent in favor ofOpacityComp.fadeIn() - Deprecated
Event,EventHandlerandEventControllerin favor ofKEvent,KEventHandlerandKEventController
Removed
- (!) Removed compatibility to use two KAPLAY frames in the same page
- (!) Many TypeScript definitions were fixed, if you use TypeScript now maybe you see new errors that make your code strict
- Fix error screen not showing with not Error object
- Fix error where debug screen was scaling bad the blue rectangles
- Fix error where error screen was not showing when the error was thrown in a input event
- Fix error where fonts was cropped in the bottom
- Fix an error where
stay()object loose their input events on scene change