Skip to content

Commit

Permalink
VisualComp#alignTo
Browse files Browse the repository at this point in the history
  • Loading branch information
lajbel committed Jul 8, 2023
1 parent a837eaa commit 40f3d72
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 75 deletions.
2 changes: 1 addition & 1 deletion example/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ m.chapter("start", () => [
// Show a background.
m.showBackground(m.k.rgb(255, 255, 255)),
// Show our character.
m.show("t", "normal").appearFrom("right"),
m.show("t", "normal").fadeIn(),
// Say something.
m.say("t", "Hi human, object, or whatever you are!"),
m.say("t", "Welcome to this Mandarina test!"),
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"type": "module",
"scripts": {
"dev": "nodemon --watch ./src --watch ./example --exec \"npm run build && npm run example\" --ext \"ts\"",
"build": "node scripts/build.js && npm run dts",
"build": "node scripts/build.js",
"watch": "nodemon --watch ./src --exec \"npm run build\" --ext \"ts\"",
"build:example": "esbuild example/main.ts --bundle --sourcemap --outfile=example/game.js",
"dev:example": "esbuild example/main.ts --bundle --outfile=example/game.js --servedir=./example/",
Expand Down
74 changes: 20 additions & 54 deletions src/actions/character.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type * as KA from "kaboom";
import type { VisualAction, VisualAlign } from "../types";
import type { VisuaLEffectsOpt } from "../components/visual";
import type { VisualAction, VisualAlign, VisualComp } from "../types";
import { visual, type VisuaLEffectsOpt } from "../components/visual";
import { createAction, getGameData } from "../game";
import { getSpriteDimensions } from "../util";

Expand All @@ -10,7 +10,7 @@ export function showCharacter(
align: VisualAlign = "center",
) {
const { m, k, characters, loadedImages } = getGameData();
let ch: KA.GameObj;
let ch: KA.GameObj<VisualComp>;
let effects: Partial<VisuaLEffectsOpt> = {};

return createAction({
Expand All @@ -20,11 +20,6 @@ export function showCharacter(
fade: false,
start(this: VisualAction) {
const textbox = m._textbox;
const comps: KA.Comp[] = [];

if (this.fade) {
comps.push(k.opacity(0), k.fadeIn(1));
}

const character = characters.get(characterId);
if (!character)
Expand All @@ -37,67 +32,38 @@ export function showCharacter(
throw Error(`Expression "${expression}" does not exist.`);

const spriteScale = loadedImages.get(expressionSprite)?.scale ?? 1;
const spriteDimensions =
getSpriteDimensions(expressionSprite).scale(spriteScale);
const sprW = spriteDimensions.x;
const sprH = spriteDimensions.y;

const alignments: Record<VisualAlign, KA.Vec2> = {
left: k.vec2(sprW / 2, k.height() - sprH / 2),
center: k.vec2(k.center().x, k.height() - sprH / 2),
right: k.vec2(k.width() - sprW / 2, k.height() - sprH / 2),
truecenter: k.vec2(k.center().x, k.center().y),
trueleft: k.vec2(sprW / 2, k.center().y),
trueright: k.vec2(k.width() - sprW / 2, k.center().y),
};

if (this.side) {
const moveTweenComp = () => {
return {
add(this: KA.GameObj<any>) {
k.tween(
this.pos.x,
alignments[align].x,
1,
(v) => {
this.pos.x = v;
},
k.easings.easeInOutQuad,
);
},
};
};

comps.push(
k.pos(
this.side === "left" ? -sprW / 2 : k.width() + sprW / 2,
alignments[align].y,
),
moveTweenComp(),
);
} else {
comps.push(k.pos(alignments[align]));
}
ch = k.make([
`character_${characterId}`,
k.layer("characters"),
k.opacity(1),
k.anchor("center"),
k.pos(0),
visual({
visualObj: "character_sprite",
startEffects: [ ...Object.keys(effects) ],
...effects,
}),
]);

ch = k.add([
ch.add([
"character_sprite",
k.scale(spriteScale),
k.layer("characters"),
k.sprite(expressionSprite),
k.opacity(1),
k.anchor("center"),
...comps,
"character_" + characterId,
]);

if (textbox && character.opt?.voice) {
textbox.on("writeCharacter", () => {
k.play(character.opt?.voice ?? "");
});
}

k.add(ch);
ch.alignTo(expressionSprite, align);
},
back() {
if (!ch) return;

ch.destroy();
},
skip() {
Expand Down
30 changes: 22 additions & 8 deletions src/components/visual.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import type * as KA from "kaboom";
import type { UnionToIntersection } from "types";
import { getGameData } from "game";
import { onAddObj } from "../util";
import { onAddObj, getAlignment, getSpriteDimensions } from "../util";

export type VisualAlign =
| "left"
| "right"
| "center"
| "truecenter"
| "trueleft"
| "trueright";

export type VisualEffect = "fade" | "appearFrom";

Expand Down Expand Up @@ -34,6 +42,7 @@ export interface VisualComp extends KA.Comp {
visualObj: string;
fade(opt: FadeEffectOpt): void;
appearFrom(opt: AppearFromEffectOpt): void;
alignTo(sprite: string, align: VisualAlign): void;
}

export interface VisualCompOpt<TEffect extends VisualEffect[] = any> {
Expand All @@ -48,7 +57,7 @@ export interface VisualCompOpt<TEffect extends VisualEffect[] = any> {
export function visual<T extends VisualEffect[] | undefined = undefined>(
opt: T extends VisualEffect[]
? VisualCompOpt<T> & OptByEffects<T>
: VisualComp,
: VisualCompOpt,
): VisualComp {
let visualObj: KA.GameObj;

Expand All @@ -64,15 +73,11 @@ export function visual<T extends VisualEffect[] | undefined = undefined>(
visualObj: opt.visualObj,

add(this: KA.GameObj) {
const { k } = getGameData();
visualObj = this.get(opt.visualObj, { recursive: true })[0];

if (optHasEffect(opt, "appearFrom")) {
onAddObj(visualObj, () => {
this.fade(opt);
});
if (optHasEffect(opt, "fade")) {
this.fade(opt);
}

if (optHasEffect(opt, "appearFrom")) {
onAddObj(visualObj, () => {
this.appearFrom(opt);
Expand All @@ -92,5 +97,14 @@ export function visual<T extends VisualEffect[] | undefined = undefined>(
visualObj.pos.x = v;
});
},

alignTo(sprite, align) {
const { loadedImages } = getGameData();
const scale = loadedImages.get(sprite)?.scale ?? 1;
const spriteSize = getSpriteDimensions(sprite).scale(scale);
const alignPos = getAlignment(align, spriteSize.x, spriteSize.y);

visualObj.pos = alignPos;
},
};
}
10 changes: 2 additions & 8 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type * as KA from "kaboom";
import type { LayerPlugin } from "plugins/layer";
import type { Choice } from "actions/textbox";
import type { VisualAlign } from "./components/visual";
export type {
VisualComp,
VisuaLEffectsOpt,
Expand All @@ -9,6 +10,7 @@ export type {
OptByEffects,
FadeEffectOpt,
AppearFromEffectOpt,
VisualAlign,
} from "./components/visual";
export type { LayerPlugin, Choice };

Expand Down Expand Up @@ -199,14 +201,6 @@ export interface NormalAction extends BaseAction {
type: "normal";
}

export type VisualAlign =
| "left"
| "right"
| "center"
| "truecenter"
| "trueleft"
| "trueright";

export interface VisualAction extends BaseAction {
type: "visual";
/** If the visual will fadeIn. */
Expand Down
7 changes: 4 additions & 3 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type * as KA from "kaboom";
import { getGameData } from "game";
import { VisualAlign } from "types";
import { VisualAlign } from "components/visual";

export function getAlignment(
align: VisualAlign,
Expand Down Expand Up @@ -31,10 +31,11 @@ export function getSpriteDimensions(sprite: string): KA.Vec2 {
return k.vec2(spr.width, spr.height);
}

export function onAddObj(obj: KA.GameObj, action: (obj: KA.GameObj) => void) {
export function onAddObj(obj: KA.GameObj, action: (obj2: KA.GameObj) => void) {
console.log(obj);
const { k } = getGameData();

k.onAdd((o) => {
return k.onAdd((o) => {
if (o.id === obj.id) {
action(o);
}
Expand Down

0 comments on commit 40f3d72

Please sign in to comment.