Skip to content

Commit

Permalink
feat: layers and layer component (#121)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Báez <lajbelms@gmail.com>
  • Loading branch information
mflerackers and lajbel authored Jun 8, 2024
1 parent ec86a8f commit a81d952
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 121 deletions.
167 changes: 51 additions & 116 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- 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
- added layers and the layer component

### Deprecated

Expand Down Expand Up @@ -80,10 +81,7 @@ loadFont("apl386", "/examples/fonts/apl386.ttf", {
- setting `obj.text` with `text()` component now immediately updates `width` and `height` property

```js
const obj = add([
text("oh hi"),
pos(100, 200),
]);
const obj = add([text("oh hi"), pos(100, 200)]);

// before
obj.text = "bye";
Expand Down Expand Up @@ -146,12 +144,7 @@ getSprite("bean").then((spr) => {
// add a scene game object
const scene = add([]);

const bean = scene.add([
sprite("bean"),
pos(100, 200),
area(),
body(),
]);
const bean = scene.add([sprite("bean"), pos(100, 200), area(), body()]);

scene.onKeyPress("space", () => {
bean.jump();
Expand Down Expand Up @@ -182,18 +175,17 @@ const evs = [];
scene.onDestroy(() => {
evs.forEach((ev) => ev.cancel());
});
evs.push(k.onKeyPress("space", () => {
doSomeSceneSpecificStuff();
}));
evs.push(
k.onKeyPress("space", () => {
doSomeSceneSpecificStuff();
}),
);
```

- added `make()` to create game object without adding to the scene

```js
const obj = make([
sprite("bean"),
pos(120, 60),
]);
const obj = make([sprite("bean"), pos(120, 60)]);

add(obj);
```
Expand All @@ -202,9 +194,7 @@ add(obj);

```js
// before
const ui = add([
fixed(),
]);
const ui = add([fixed()]);

ui.add([
rect(),
Expand All @@ -213,14 +203,10 @@ ui.add([
]);

// now
const ui = add([
fixed(),
]);
const ui = add([fixed()]);

// you don't have to add fixed() to children
ui.add([
rect(100, 100),
]);
ui.add([rect(100, 100)]);
```

- fixed `AreaComp#onClick()` event not getting cleaned up when game object is destroyed
Expand All @@ -238,10 +224,7 @@ ui.add([
- added scene graph, game objects are now stored in a tree-like structure and can have children with `obj.add()`

```js
const bean = add([
sprite("bean"),
pos(160, 120),
]);
const bean = add([sprite("bean"), pos(160, 120)]);

const sword = bean.add([
sprite("sword"),
Expand Down Expand Up @@ -275,10 +258,7 @@ const enemies = get("enemy", {

console.log(enemies.length); // 3

add([
sprite("bigbird"),
"enemy",
]);
add([sprite("bigbird"), "enemy"]);

console.log(enemies.length); // 4
```
Expand Down Expand Up @@ -385,7 +365,7 @@ const player = add([
sprite("bean"),
// will calculate and send u_time every frame
shader("flashy", () => ({
"u_time": time(),
u_time: time(),
})),
]);
```
Expand Down Expand Up @@ -485,9 +465,7 @@ loadSprite("grass", "/sprites/grass.png", {
},
});

const g = add([
sprite("grass"),
]);
const g = add([sprite("grass")]);

onMouseMove(() => {
const mpos = mousePos();
Expand Down Expand Up @@ -538,51 +516,33 @@ music.loop = true;

```js
// before
addLevel([
"@ ^ $$",
"=======",
], {
addLevel(["@ ^ $$", "======="], {
width: 32,
height: 32,
"=": () => [
sprite("grass"),
area(),
body({ isStatic: true }),
],
"$": () => [
sprite("coin"),
area(),
"coin",
],
"=": () => [sprite("grass"), area(), body({ isStatic: true })],
$: () => [sprite("coin"), area(), "coin"],
any: (symbol) => {
if (symbol === "@") {
return [/* ... */];
return [
/* ... */
];
}
},
});

// v3000
addLevel([
"@ ^ $$",
"=======",
], {
addLevel(["@ ^ $$", "======="], {
tileWidth: 32,
tileHeight: 32,
tiles: {
"=": () => [
sprite("grass"),
area(),
body({ isStatic: true }),
],
"$": () => [
sprite("coin"),
area(),
"coin",
],
"=": () => [sprite("grass"), area(), body({ isStatic: true })],
$: () => [sprite("coin"), area(), "coin"],
},
wildcardTile: (symbol) => {
if (symbol === "@") {
return [/* ... */];
return [
/* ... */
];
}
},
});
Expand Down Expand Up @@ -626,14 +586,14 @@ onMousePress(() => {
bean.pos.x,
mousePos().x,
1,
(val) => bean.pos.x = val,
(val) => (bean.pos.x = val),
easings.easeOutBounce,
);
tween(
bean.pos.y,
mousePos().y,
1,
(val) => bean.pos.y = val,
(val) => (bean.pos.y = val),
easings.easeOutBounce,
);
});
Expand All @@ -643,23 +603,31 @@ onMousePress(() => {

```js
// before
const cancel = onUpdate(() => {/* ... */});
const cancel = onUpdate(() => {
/* ... */
});
cancel();

// v3000
const ev = onUpdate(() => {/* ... */});
const ev = onUpdate(() => {
/* ... */
});
ev.paused = true;
ev.cancel();
```

- timers can now be paused

```js
const timer = wait(4, () => {/* ... */});
const timer = wait(4, () => {
/* ... */
});
timer.paused = true;
timer.resume();

const timer = loop(1, () => {/* ... */});
const timer = loop(1, () => {
/* ... */
});
timer.paused = true;
timer.resume();
```
Expand Down Expand Up @@ -829,15 +797,9 @@ timer.resume();

```js
// before
add([
sprite("player"),
area(),
]);
add([sprite("player"), area()]);

add([
sprite("rock"),
solid(),
]);
add([sprite("rock"), solid()]);

keyDown("left", () => {
player.move(-120, 0);
Expand All @@ -848,18 +810,10 @@ player.action(() => {
});

// after
const player = add([
sprite("player"),
area(),
solid(),
]);
const player = add([sprite("player"), area(), solid()]);

// both should be solid
add([
sprite("rock"),
area(),
solid(),
]);
add([sprite("rock"), area(), solid()]);

keyDown("left", () => {
// this will handle collision resolution for you, if the other obj is also "solid"
Expand Down Expand Up @@ -887,17 +841,10 @@ keyDown("left", () => {

```js
// before
add([
rotate(Math.PI / 2),
color(0, 0.5, 1.0, 0.5),
]);
add([rotate(Math.PI / 2), color(0, 0.5, 1.0, 0.5)]);

// after
add([
rotate(90),
color(0, 127, 255),
opacity(0.5),
]);
add([rotate(90), color(0, 127, 255), opacity(0.5)]);
```

- `global` and `debug` flag now are enabled by default, need to turn off manually if you don't want
Expand Down Expand Up @@ -1004,21 +951,9 @@ loadSprite("hero", "hero.png", {
- **BREAK** now every symbol definition in `addLevel()` should be a function returning the component list, to ensure there's no weird shared states

```js
addLevel([
"* *",
"* *",
"======",
], {
"*": () => [
sprite("wall"),
area(),
solid(),
],
"=": () => [
sprite("floor"),
area(),
solid(),
],
addLevel(["* *", "* *", "======"], {
"*": () => [sprite("wall"), area(), solid()],
"=": () => [sprite("floor"), area(), solid()],
});
```

Expand Down
34 changes: 34 additions & 0 deletions examples/layers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
kaplay();

layers(["bg", "game", "ui"], "game");

// bg layer
add([
rect(width(), height()),
layer("bg"),
color(rgb(64, 128, 255)),
// opacity(0.5)
]).add([text("BG")]);

// game layer explicit
add([
pos(width() / 5, height() / 5),
rect(width() / 3, height() / 3),
layer("game"),
color(rgb(255, 128, 64)),
]).add([text("GAME")]);

// game layer implicit
add([
pos(3 * width() / 5, 3 * height() / 5),
rect(width() / 3, height() / 3),
color(rgb(255, 128, 64)),
]).add([pos(width() / 3, height() / 3), text("GAME"), anchor("botright")]);

// ui layer
add([
pos(center()),
rect(width() / 2, height() / 2),
anchor("center"),
color(rgb(64, 255, 128)),
]).add([text("UI"), anchor("center")]);
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export * from "./physics/doubleJump";
export * from "./transform/anchor";
export * from "./transform/fixed";
export * from "./transform/follow";
export * from "./transform/layer";
export * from "./transform/move";
export * from "./transform/offscreen";
export * from "./transform/pos";
Expand Down
24 changes: 24 additions & 0 deletions src/components/transform/layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { getInternalContext, getKaboomContext } from "@/kaboom";
import type { LayerComp } from "@/types";

export function layer(layer: string): LayerComp {
const k = getKaboomContext(this);
const internal = getInternalContext(k);
let _layerIndex = internal.game.layers.indexOf(layer);
return {
id: "layer",
get layerIndex() {
return _layerIndex;
},
get layer(): string {
return k.layers[_layerIndex];
},
set layer(value: string) {
_layerIndex = internal.game.layers.indexOf(value);
if (_layerIndex == -1) throw Error("Invalid layer name");
},
inspect() {
return `${this.layer}`;
},
};
}
Loading

0 comments on commit a81d952

Please sign in to comment.