This commit is contained in:
Schluffe
2026-02-25 00:58:53 +01:00
parent 51a0fe38ef
commit 9ab90b579c
9 changed files with 166 additions and 74 deletions
+18 -18
View File
@@ -5,15 +5,15 @@
"": { "": {
"name": "nage", "name": "nage",
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.3.14", "@biomejs/biome": "latest",
"@types/bun": "1.3.8", "@types/bun": "latest",
"lz-string": "1.5.0", "lz-string": "latest",
"solid-js": "1.9.11", "solid-js": "latest",
"vite": "7.3.1", "vite": "latest",
"vite-plugin-solid": "2.11.10", "vite-plugin-solid": "latest",
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "5.9.3", "typescript": "latest",
}, },
}, },
}, },
@@ -54,23 +54,23 @@
"@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
"@biomejs/biome": ["@biomejs/biome@2.3.14", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.14", "@biomejs/cli-darwin-x64": "2.3.14", "@biomejs/cli-linux-arm64": "2.3.14", "@biomejs/cli-linux-arm64-musl": "2.3.14", "@biomejs/cli-linux-x64": "2.3.14", "@biomejs/cli-linux-x64-musl": "2.3.14", "@biomejs/cli-win32-arm64": "2.3.14", "@biomejs/cli-win32-x64": "2.3.14" }, "bin": { "biome": "bin/biome" } }, "sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA=="], "@biomejs/biome": ["@biomejs/biome@2.4.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.4", "@biomejs/cli-darwin-x64": "2.4.4", "@biomejs/cli-linux-arm64": "2.4.4", "@biomejs/cli-linux-arm64-musl": "2.4.4", "@biomejs/cli-linux-x64": "2.4.4", "@biomejs/cli-linux-x64-musl": "2.4.4", "@biomejs/cli-win32-arm64": "2.4.4", "@biomejs/cli-win32-x64": "2.4.4" }, "bin": { "biome": "bin/biome" } }, "sha512-tigwWS5KfJf0cABVd52NVaXyAVv4qpUXOWJ1rxFL8xF1RVoeS2q/LK+FHgYoKMclJCuRoCWAPy1IXaN9/mS61Q=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A=="], "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jZ+Xc6qvD6tTH5jM6eKX44dcbyNqJHssfl2nnwT6vma6B1sj7ZLTGIk6N5QwVBs5xGN52r3trk5fgd3sQ9We9A=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA=="], "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dh1a/+W+SUCXhEdL7TiX3ArPTFCQKJTI1mGncZNWfO+6suk+gYA4lNyJcBB+pwvF49uw0pEbUS49BgYOY4hzUg=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ=="], "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg=="], "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+sPAXq3bxmFwhVFJnSwkSF5Rw2ZAJMH3MF6C9IveAEOdSpgajPhoQhbbAK12SehN9j2QrHpk4J/cHsa/HqWaYQ=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.14", "", { "os": "linux", "cpu": "x64" }, "sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA=="], "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.14", "", { "os": "linux", "cpu": "x64" }, "sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ=="], "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A=="], "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.14", "", { "os": "win32", "cpu": "x64" }, "sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ=="], "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.4", "", { "os": "win32", "cpu": "x64" }, "sha512-gnOHKVPFAAPrpoPt2t+Q6FZ7RPry/FDV3GcpU53P3PtLNnQjBmKyN2Vh/JtqXet+H4pme8CC76rScwdjDcT1/A=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="],
@@ -192,7 +192,7 @@
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
"@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="], "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
@@ -206,7 +206,7 @@
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
"bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="], "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
"caniuse-lite": ["caniuse-lite@1.0.30001763", "", {}, "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ=="], "caniuse-lite": ["caniuse-lite@1.0.30001763", "", {}, "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ=="],
+29
View File
@@ -0,0 +1,29 @@
import { drawSprite, type Sprite, spriteSheetMap } from "#/engine/Sprite.ts";
import type { Vector } from "#/engine/Vector.ts";
export type Drawable = {
position: Vector;
sprite: Sprite;
};
export function isDrawable<T>(
entity: {
position?: Vector;
sprite?: Sprite;
} & T,
): entity is Drawable & T {
return (
typeof entity.position === "object" && typeof entity.sprite === "object"
);
}
export function draw(ctx: CanvasRenderingContext2D, drawable: Drawable): void {
drawSprite(
ctx,
spriteSheetMap.get(drawable.sprite.src)!,
drawable.sprite.xStart,
drawable.sprite.yStart,
drawable.position.x,
drawable.position.y,
);
}
+42 -26
View File
@@ -1,3 +1,4 @@
import { type Drawable, draw, isDrawable } from "#/engine/Drawable.ts";
import { import {
entityMap, entityMap,
entityProcessMap, entityProcessMap,
@@ -5,7 +6,7 @@ import {
} from "#/engine/Entity.ts"; } from "#/engine/Entity.ts";
import { type Graph, getNeighbours } from "#/engine/Graph.ts"; import { type Graph, getNeighbours } from "#/engine/Graph.ts";
import { useWithAsyncCache } from "#/engine/lib/cache.ts"; import { useWithAsyncCache } from "#/engine/lib/cache.ts";
import { playAnimation } from "./Sprite"; import { animateSprite, type SpriteAnimation } from "#/engine/Sprite.ts";
export type EntityData = { export type EntityData = {
name: string; name: string;
@@ -22,11 +23,13 @@ export type SceneData = {
export type EntityMap = Map< export type EntityMap = Map<
string, string,
{ {
process: ProcessEntity<object>; process: ProcessEntity<{ id: number }>;
instances: Array<object>; instances: Array<{ id: number }>;
} }
>; >;
export type AnimationMap = Map<number, SpriteAnimation>;
export type Scene = { export type Scene = {
data: SceneData; data: SceneData;
entityMap: EntityMap; entityMap: EntityMap;
@@ -49,7 +52,11 @@ export const sceneDataMap = new Map<string, SceneData>();
export const sceneEntiyMap = new Map<string, EntityMap>(); export const sceneEntiyMap = new Map<string, EntityMap>();
export const sceneGraph: Graph<string> = new Map(); export const sceneGraph: Graph<string> = new Map();
const sceneInstancesDrawMap = new Map<string, Array<object>>(); const sceneInstancesDrawMap = new Map<
string,
Array<Drawable & { id: number }>
>();
const sceneInstancesAnimationMap = new Map<string, AnimationMap>();
export const [loadScene, sceneCache] = useWithAsyncCache( export const [loadScene, sceneCache] = useWithAsyncCache(
async (name: string) => { async (name: string) => {
@@ -60,7 +67,7 @@ export const [loadScene, sceneCache] = useWithAsyncCache(
entityInstanceMap.clear(); entityInstanceMap.clear();
await Promise.all( await Promise.all(
data.entities.map(async (entityData: EntityData) => { data.entities.map(async (entityData: EntityData, index: number) => {
await import(`#/game/entities/${entityData.name}/entity.ts`); await import(`#/game/entities/${entityData.name}/entity.ts`);
if (!entityInstanceMap.has(entityData.name)) { if (!entityInstanceMap.has(entityData.name)) {
@@ -75,6 +82,7 @@ export const [loadScene, sceneCache] = useWithAsyncCache(
structuredClone({ structuredClone({
...entityMap.get(entityData.name)!, ...entityMap.get(entityData.name)!,
...entityData, ...entityData,
id: index,
}), }),
); );
} catch (error) { } catch (error) {
@@ -104,19 +112,17 @@ function processEntities(delta: number): void {
} }
} }
// TODO: type stuff and fixme WIP
function processSystems(ctx: CanvasRenderingContext2D, delta: number): void { function processSystems(ctx: CanvasRenderingContext2D, delta: number): void {
const drawables = sceneInstancesDrawMap.get(currentScene.data.name)!; const drawables = sceneInstancesDrawMap.get(currentScene.data.name)!;
const animationsMap = sceneInstancesAnimationMap.get(currentScene.data.name)!;
for (const drawable of drawables.sort( for (const drawable of drawables.sort(
(a, b) => a.position.y - b.position.y, (a, b) => a.position.y - b.position.y,
)) { )) {
playAnimation( if (animationsMap.has(drawable.id)) {
ctx, animateSprite(animationsMap.get(drawable.id)!, delta);
drawable.animation, }
drawable.position.x, draw(ctx, drawable);
drawable.position.y,
delta,
);
} }
} }
@@ -176,19 +182,29 @@ export async function setScene(name: string): Promise<void> {
const data = sceneDataMap.get(name)!; const data = sceneDataMap.get(name)!;
const process = sceneProcessMap.get(name)!; const process = sceneProcessMap.get(name)!;
const entityInstanceMap = sceneEntiyMap.get(name)!; const entityInstanceMap = sceneEntiyMap.get(name)!;
// TODO: test for drawable first
sceneInstancesDrawMap.set( const drawableInstances: Array<Drawable & { id: number }> = [];
data.name, sceneInstancesDrawMap.set(data.name, drawableInstances);
entityInstanceMap.values().reduce(
(acc, cur) => { const animateInstances: AnimationMap = new Map();
for (const instance of cur.instances) { sceneInstancesAnimationMap.set(data.name, animateInstances);
acc.push(instance);
} for (const entity of entityInstanceMap.values()) {
return acc; for (const instance of entity.instances) {
}, if (isDrawable(instance)) {
[] as Array<object>, drawableInstances.push(instance);
), }
); if (
(instance as { id: number; animation: SpriteAnimation }).animation !==
undefined
) {
animateInstances.set(
instance.id,
(instance as { id: number; animation: SpriteAnimation }).animation, // FIXME
);
}
}
}
const preProcess = scenePreProcessMap.get(name); const preProcess = scenePreProcessMap.get(name);
if (preProcess) { if (preProcess) {
+21 -18
View File
@@ -1,4 +1,12 @@
import { loadImage } from "./lib/loadImage"; import { loadImage } from "#/engine/lib/loadImage.ts";
export type Sprite = {
src: string;
xStart: number;
yStart: number;
width: number;
height: number;
};
export type SpriteSheet = { export type SpriteSheet = {
image: HTMLImageElement; image: HTMLImageElement;
@@ -9,7 +17,7 @@ export type SpriteSheet = {
}; };
export type SpriteAnimation = { export type SpriteAnimation = {
src: string; sprite: Sprite;
xIndex: number; xIndex: number;
yIndex: number; yIndex: number;
frameTime: number; frameTime: number;
@@ -49,12 +57,14 @@ export async function useSpriteSheetSrc(
} }
export function createSpriteAnimation( export function createSpriteAnimation(
src: string, sprite: Sprite,
frameTime: number, frameTime: number,
yIndex: number, yIndex: number,
): SpriteAnimation { ): SpriteAnimation {
sprite.yStart = yIndex * spriteSheetMap.get(sprite.src)!.frameHeight;
return { return {
src, sprite,
xIndex: 0, xIndex: 0,
yIndex, yIndex,
frameTime, frameTime,
@@ -65,8 +75,8 @@ export function createSpriteAnimation(
export function drawSprite( export function drawSprite(
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
sheet: SpriteSheet, sheet: SpriteSheet,
xIndex: number, xStart: number,
yIndex: number, yStart: number,
x: number, x: number,
y: number, y: number,
width?: number, width?: number,
@@ -74,8 +84,8 @@ export function drawSprite(
): void { ): void {
ctx.drawImage( ctx.drawImage(
sheet.image, sheet.image,
xIndex * sheet.frameWidth, xStart,
yIndex * sheet.frameHeight, yStart,
sheet.frameWidth, sheet.frameWidth,
sheet.frameHeight, sheet.frameHeight,
x, x,
@@ -85,15 +95,8 @@ export function drawSprite(
); );
} }
export function playAnimation( export function animateSprite(animation: SpriteAnimation, delta: number): void {
ctx: CanvasRenderingContext2D, const sheet = spriteSheetMap.get(animation.sprite.src)!;
animation: SpriteAnimation,
x: number,
y: number,
delta: number,
): void {
const sheet = spriteSheetMap.get(animation.src)!;
if ((animation.frameDelta += delta) > animation.frameTime) { if ((animation.frameDelta += delta) > animation.frameTime) {
animation.frameDelta = 0; animation.frameDelta = 0;
if ((animation.xIndex += 1) >= sheet.xFrames) { if ((animation.xIndex += 1) >= sheet.xFrames) {
@@ -101,5 +104,5 @@ export function playAnimation(
} }
} }
drawSprite(ctx, sheet, animation.xIndex, animation.yIndex, x, y); animation.sprite.xStart = animation.xIndex * sheet.frameWidth;
} }
+11 -1
View File
@@ -5,6 +5,7 @@ import { keyboardInput } from "#/engine/Keyboard.ts";
import { pointer } from "#/engine/Pointer.ts"; import { pointer } from "#/engine/Pointer.ts";
import { import {
createSpriteAnimation, createSpriteAnimation,
type Sprite,
type SpriteAnimation, type SpriteAnimation,
useSpriteSheetSrc, useSpriteSheetSrc,
} from "#/engine/Sprite.ts"; } from "#/engine/Sprite.ts";
@@ -15,17 +16,26 @@ export type Hero = {
position: Vector; position: Vector;
velocity: Vector; velocity: Vector;
body: Circle; body: Circle;
sprite: Sprite;
animation: SpriteAnimation; animation: SpriteAnimation;
}; };
const speed = 0.05; const speed = 0.05;
const idleSheet = await useSpriteSheetSrc(charIdle, 2, 4); const idleSheet = await useSpriteSheetSrc(charIdle, 2, 4);
const sprite = {
src: idleSheet,
xStart: 0,
yStart: 0,
width: 16,
height: 16,
};
const state: Hero = { const state: Hero = {
position: createVector(), position: createVector(),
velocity: createVector(), velocity: createVector(),
body: createCircle(createVector(), 4), body: createCircle(createVector(), 4),
animation: createSpriteAnimation(idleSheet, 500, 2), sprite,
animation: createSpriteAnimation(sprite, 500, 2),
}; };
const process = defineEntity("hero", state); const process = defineEntity("hero", state);
+10 -2
View File
@@ -1,11 +1,19 @@
import { defineEntity } from "#/engine/Entity.ts"; import { defineEntity } from "#/engine/Entity.ts";
import { createSpriteAnimation, useSpriteSheetSrc } from "#/engine/Sprite.ts"; import { createSpriteAnimation, useSpriteSheetSrc } from "#/engine/Sprite.ts";
import { createVector } from "#/engine/Vector"; import { createVector } from "#/engine/Vector.ts";
import portal from "#/game/assets/portal.png"; import portal from "#/game/assets/portal.png";
const portalSheet = await useSpriteSheetSrc(portal, 3, 1); const portalSheet = await useSpriteSheetSrc(portal, 3, 1);
const sprite = {
src: portalSheet,
xStart: 0,
yStart: 0,
width: 16,
height: 16,
};
defineEntity("portal", { defineEntity("portal", {
position: createVector(64, 64), position: createVector(64, 64),
animation: createSpriteAnimation(portalSheet, 400, 0), sprite,
animation: createSpriteAnimation(sprite, 400, 0),
}); });
+29 -2
View File
@@ -1,6 +1,7 @@
import { defineEntity } from "#/engine/Entity.ts"; import { defineEntity } from "#/engine/Entity.ts";
import { import {
createSpriteAnimation, createSpriteAnimation,
type Sprite,
type SpriteAnimation, type SpriteAnimation,
useSpriteSheetSrc, useSpriteSheetSrc,
} from "#/engine/Sprite.ts"; } from "#/engine/Sprite.ts";
@@ -9,11 +10,28 @@ import { viewport } from "#/engine/Viewport.ts";
import charIdle from "#/game/assets/char-idle.png"; import charIdle from "#/game/assets/char-idle.png";
import charWalk from "#/game/assets/char-walk.png"; import charWalk from "#/game/assets/char-walk.png";
const sprites = { const sheets = {
idle: await useSpriteSheetSrc(charIdle, 2, 4), idle: await useSpriteSheetSrc(charIdle, 2, 4),
walk: await useSpriteSheetSrc(charWalk, 4, 4), walk: await useSpriteSheetSrc(charWalk, 4, 4),
}; };
const sprites = {
idle: {
src: sheets.idle,
xStart: 0,
yStart: 0,
width: 16,
height: 16,
},
walk: {
src: sheets.walk,
xStart: 0,
yStart: 0,
width: 16,
height: 16,
},
};
const animations = { const animations = {
idle: createSpriteAnimation(sprites.idle, 500, 2), idle: createSpriteAnimation(sprites.idle, 500, 2),
walk: createSpriteAnimation(sprites.walk, 250, 2), walk: createSpriteAnimation(sprites.walk, 250, 2),
@@ -26,11 +44,18 @@ const process = defineEntity<{
idle: SpriteAnimation; idle: SpriteAnimation;
walk: SpriteAnimation; walk: SpriteAnimation;
}; };
sprite: Sprite;
sprites: {
idle: Sprite;
walk: Sprite;
};
stuff: number; stuff: number;
}>("testEntity", { }>("testEntity", {
position: createVector(), position: createVector(),
animations,
animation: animations.idle, animation: animations.idle,
animations,
sprite: sprites.idle,
sprites,
stuff: 1, stuff: 1,
}); });
@@ -39,8 +64,10 @@ process((entity, _delta) => {
if (entity.position.x > viewport.canvas.width - 16) { if (entity.position.x > viewport.canvas.width - 16) {
entity.stuff = -1; entity.stuff = -1;
entity.animation = entity.animations.walk; entity.animation = entity.animations.walk;
entity.sprite = entity.sprites.walk;
} else if (entity.position.x < 0) { } else if (entity.position.x < 0) {
entity.stuff = 1; entity.stuff = 1;
entity.animation = entity.animations.idle; entity.animation = entity.animations.idle;
entity.sprite = entity.sprites.idle;
} }
}); });
+4 -5
View File
@@ -3,7 +3,6 @@ import { pointer } from "#/engine/Pointer.ts";
import { defineScene } from "#/engine/Scene.ts"; import { defineScene } from "#/engine/Scene.ts";
import { spriteSheetMap } from "#/engine/Sprite.ts"; import { spriteSheetMap } from "#/engine/Sprite.ts";
import { createVector } from "#/engine/Vector"; import { createVector } from "#/engine/Vector";
import type { Hero } from "#/game/entities/hero/entity.ts";
import data from "./data.json"; import data from "./data.json";
const { process, preProcess, linkScenes } = defineScene(data); const { process, preProcess, linkScenes } = defineScene(data);
@@ -12,11 +11,11 @@ linkScenes(["fooScene"] as const);
preProcess((entityInstanceMap) => { preProcess((entityInstanceMap) => {
const entry = entityInstanceMap.get("hero")!; const entry = entityInstanceMap.get("hero")!;
const instance = entry.instances[0] as Hero; const instance = entry.instances[0];
const sheet = spriteSheetMap.get(instance.animation.src)!; // const sheet = spriteSheetMap.get(instance.animation.src)!;
instance.position.x = data.width - sheet.frameHeight; instance.position.x = data.width - 16;
instance.position.y = data.height - sheet.frameWidth; instance.position.y = data.height - 16;
}); });
const cirle = createCircle(createVector(), 4); const cirle = createCircle(createVector(), 4);
+2 -2
View File
@@ -8,8 +8,8 @@
"check": "biome check --write" "check": "biome check --write"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.3.14", "@biomejs/biome": "2.4.4",
"@types/bun": "1.3.8", "@types/bun": "1.3.9",
"lz-string": "1.5.0", "lz-string": "1.5.0",
"solid-js": "1.9.11", "solid-js": "1.9.11",
"vite": "7.3.1", "vite": "7.3.1",