fix: use spritesheets instead of loading every image individually

This commit is contained in:
trafficlunar 2024-12-07 16:45:04 +00:00
parent 2670fbb1e8
commit 63d81a45f2
274 changed files with 35 additions and 24 deletions

View file

@ -15,13 +15,15 @@ import {
MenubarSubTrigger,
MenubarTrigger,
} from "@/components/ui/menubar";
import { ToggleGroup, ToggleGroupItem } from "./components/ui/toggle-group";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import ThemeChanger from "./components/menubar/theme-changer";
import Blocks from "./components/blocks";
import Cursor from "./components/cursor";
import CursorInformation from "./components/cursor-information";
import spritesheet from "@/lib/data/blocks/programmer-art/spritesheet.json";
// Set scale mode to NEAREST
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
@ -35,6 +37,7 @@ function App() {
const [dragging, setDragging] = useState(false);
const [scale, setScale] = useState(1);
const [blocks, setBlocks] = useState<Block[]>([]);
const [textures, setTextures] = useState<Record<string, PIXI.Texture>>({});
const [cssCursor, setCssCursor] = useState("grab");
const [tool, setTool] = useState<Tool>("hand");
@ -110,7 +113,7 @@ function App() {
e.preventDefault();
const scaleChange = e.deltaY > 0 ? -0.1 : 0.1;
const newScale = Math.min(Math.max(scale + (scaleChange * scale), 0.25), 32);
const newScale = Math.min(Math.max(scale + scaleChange * scale, 0.25), 32);
setScale(newScale);
setCoords({
@ -131,7 +134,13 @@ function App() {
resizeCanvas();
window.addEventListener("resize", resizeCanvas);
}
const loadSpritesheet = async () => {
const sheet = new PIXI.Spritesheet(PIXI.BaseTexture.from("/blocks/programmer-art/spritesheet.png"), spritesheet);
await sheet.parse();
setTextures(sheet.textures);
};
loadSpritesheet();
}, []);
return (
@ -196,7 +205,7 @@ function App() {
style={{ cursor: cssCursor }}
>
<Container x={coords.x} y={coords.y} scale={scale}>
<Blocks blocks={blocks} setBlocks={setBlocks} />
{textures && <Blocks blocks={blocks} setBlocks={setBlocks} textures={textures} />}
<Cursor localMousePosition={localMousePosition} />
</Container>
</Stage>

View file

@ -1,13 +1,19 @@
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { Texture } from "pixi.js";
import { Sprite } from "@pixi/react";
import blocksData from "@/lib/data/blocks/programmer-art/average_colors.json";
import welcomeBlocksData from "@/lib/data/welcome.json";
import { Sprite } from "@pixi/react";
function Blocks({ blocks, setBlocks }: { blocks: Block[]; setBlocks: React.Dispatch<React.SetStateAction<Block[]>> }) {
const [images, setImages] = useState<{ [key: string]: HTMLImageElement }>({});
function Blocks({
blocks,
setBlocks,
textures,
}: {
blocks: Block[];
setBlocks: React.Dispatch<React.SetStateAction<Block[]>>;
textures: Record<string, Texture>;
}) {
const findClosestBlock = (r: number, g: number, b: number, a: number) => {
let closestBlock = "";
let closestDistance = Infinity;
@ -24,17 +30,6 @@ function Blocks({ blocks, setBlocks }: { blocks: Block[]; setBlocks: React.Dispa
};
useEffect(() => {
// Load images
const loadedImages: { [key: string]: HTMLImageElement } = {};
for (const name of Object.keys(blocksData)) {
const image = new Image();
image.src = `/blocks/programmer-art/${name}.png`;
loadedImages[name] = image;
}
setImages(loadedImages);
// TESTING: convert image to blocks
const image = new Image();
image.src = "/bliss.png";
@ -72,9 +67,15 @@ function Blocks({ blocks, setBlocks }: { blocks: Block[]; setBlocks: React.Dispa
return (
<>
{blocks.map((block, index) => (
<Sprite key={index} image={images[block.name]} x={block.x * 16} y={block.y * 16} />
))}
{blocks.map((block, index) => {
const texture = textures[block.name];
if (!texture) {
console.warn(`Texture not found for block: ${block.name}`);
return null;
}
return <Sprite key={index} texture={texture} x={block.x * 16} y={block.y * 16} />;
})}
</>
);
}

File diff suppressed because one or more lines are too long