diff --git a/CHANGELOG.md b/CHANGELOG.md index ca01a90d..10d102df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,32 @@ The format is (mostly) based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3001.0.9] - 2025-01-15 + +### Added + +- Added new option in `LoadSpriteOpt` for loading sprites in an individual + spritesheet - @chqs-git + ```js + loadSprite( + "player", + "sprites/player.png", + { + singular: true, + }, + ); + ``` +- **(examples)** Added a new `particle` example! - @lajbel + +### Changed + +- Improved `lifespan()` explanation - @lajbel +- **(examples)** `particle` example renamed to `lifespan` - @lajbel + +### Fixed + +- Fixed a bug where `lifespan()` was working incorrectly - @lajbel + ## [3001.0.8] - 2025-01-15 ### Fixed @@ -19,11 +45,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Added `kaplay({ spriteAtlasPadding })` for setting the space between the sprites in the sprite atlas - @marianyp - ```js - kaplay({ - spriteAtlasPadding: 10, // 10 pixels of space between each sprite - }); - ``` +```js +kaplay({ + spriteAtlasPadding: 10, // 10 pixels of space between each sprite +}); +``` ### Changed diff --git a/examples/lifespan.js b/examples/lifespan.js new file mode 100644 index 00000000..891fa63d --- /dev/null +++ b/examples/lifespan.js @@ -0,0 +1,41 @@ +// @ts-check + + +kaplay(); + +const sprites = [ + "apple", + "heart", + "coin", + "meat", + "lightening", +]; + +sprites.forEach((spr) => { + loadSprite(spr, `/sprites/${spr}.png`); +}); + +setGravity(800); + +// Spawn one object every 0.1 second +loop(0.1, () => { + // Compose object properties with components + const item = add([ + pos(center()), + sprite(choose(sprites)), + anchor("center"), + scale(rand(0.5, 1)), + area({ collisionIgnore: ["fruit"] }), + body(), + // lifespan() comp destroys the object after desired seconds + lifespan(1, { + // it will fade after 0.5 seconds + fade: 0.5 + }), + opacity(1), + move(choose([LEFT, RIGHT]), rand(60, 240)), + "fruit", + ]); + + item.jump(rand(320, 640)); +}); diff --git a/examples/particle.js b/examples/particle.js index 238dd457..e21a2e1e 100644 --- a/examples/particle.js +++ b/examples/particle.js @@ -1,43 +1,49 @@ -// @ts-check - -// Particle spawning +// Creating particles using Particle Component kaplay(); -const sprites = [ - "apple", - "heart", - "coin", - "meat", - "lightening", -]; +loadSprite("star", "./examples/sprites/particle_star_filled.png"); -sprites.forEach((spr) => { - loadSprite(spr, `/sprites/${spr}.png`); +onLoad(() => { + go("game") }); -setGravity(800); - -// Spawn one particle every 0.1 second -loop(0.1, () => { - // TODO: they are resolving collision with each other for some reason - // Compose particle properties with components - const item = add([ - pos(mousePos()), - sprite(choose(sprites)), - anchor("center"), - scale(rand(0.5, 1)), - area({ collisionIgnore: ["particle"] }), - body(), - lifespan(1, { fade: 0.5 }), - opacity(1), - move(choose([LEFT, RIGHT]), rand(60, 240)), - "particle", +function woah() { + const parts = add([ + pos(center()), + particles({ + max: 20, + speed: [50, 100], + angle: [0, 360], + angularVelocity: [45, 90], + lifeTime: [1.0, 1.5], + colors: [rgb(128, 128, 255), WHITE], + opacities: [0.1, 1.0, 0.0], + scales: [1, 2, 1], + texture: getSprite("star").data.tex, + quads: [getSprite("star").data.frames[0]], + }, { + lifetime: 1.5, + rate: 0, + direction: -90, + spread: 40, + }), ]); - item.onCollide("particle", (p) => { - console.log("dea"); + parts.emit(20); +} + +scene("game", () => { + onKeyPress("space", () => { + woah(); + }); + + onMousePress(() => { + woah(); }); - item.jump(rand(320, 640)); + add([ + text("press space for particles"), + ]); }); + diff --git a/package.json b/package.json index 490d4c58..016f3d6b 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "kaplay", "description": "KAPLAY is a JavaScript & TypeScript game library that helps you make games fast and fun!", - "version": "3001.0.8", + "version": "3001.0.9", "license": "MIT", "homepage": "https://kaplayjs.com/", + "funding": "https://opencollective.com/kaplay", "repository": { "type": "git", "url": "git+https://github.com/kaplayjs/kaplay.git" diff --git a/src/components/misc/lifespan.ts b/src/components/misc/lifespan.ts index e3a43731..169d2934 100644 --- a/src/components/misc/lifespan.ts +++ b/src/components/misc/lifespan.ts @@ -23,19 +23,25 @@ export function lifespan(time: number, opt: LifespanCompOpt = {}): EmptyComp { return { id: "lifespan", require: ["opacity"], - async add(this: GameObj) { - await _k.game.root.wait(time); - this.opacity = this.opacity ?? 1; - if (fade > 0) { - await _k.game.root.tween( - this.opacity, - 0, - fade, - (a) => this.opacity = a, - easings.linear, - ); - } - this.destroy(); + add(this: GameObj) { + _k.game.root.wait(time, () => { + this.opacity = this.opacity ?? 1; + + if (fade > 0) { + _k.game.root.tween( + this.opacity, + 0, + fade, + (a) => this.opacity = a, + easings.linear, + ).onEnd(() => { + this.destroy(); + }); + } + else { + this.destroy(); + } + }); }, }; } diff --git a/src/types.ts b/src/types.ts index d81ee2a6..9885d7da 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1178,11 +1178,13 @@ export interface KAPLAYCtx< * * @example * ```js - * // spawn an explosion, destroy after 1 seconds, start fading away after 0.5 second + * // spawn an explosion, destroy after 1.5 seconds (time + fade) * add([ * sprite("explosion", { anim: "burst", }), - * lifespan(1, { fade: 0.5 }), - * ]) + * lifespan(1, { + * fade: 0.5 // it start fading 0.5 second after time + * }), + * ]); * ``` * * @returns The lifespan comp.