import {
Application,
Container,
Graphics,
Rectangle,
Sprite,
Text,
Texture,
} from "pixi.js";
import { CompositeTilemap, Tilemap } from "@pixi/tilemap";
async function setup() {
const app = new Application();
await app.init({ background: "#111111", resizeTo: window, antialias: true });
document.getElementById("pixi-container")!.appendChild(app.canvas);
return app;
}
function makeBlockTextures(app: Application): [Texture, Texture, Texture] {
const red_box = new Graphics();
red_box.rect(0, 0, 50, 50);
red_box.fill(0xff0000);
const green_box = new Graphics();
green_box.rect(0, 0, 50, 50);
green_box.fill(0x00ff00);
const blue_box = new Graphics();
blue_box.rect(0, 0, 50, 50);
blue_box.fill(0x0000ff);
return [
app.renderer.generateTexture(red_box),
app.renderer.generateTexture(green_box),
app.renderer.generateTexture(blue_box),
];
}
function drawBlocks(
app: Application,
red_texture: Texture,
green_texture: Texture,
blue_texture: Texture,
) {
const red_sprite = new Sprite(red_texture);
red_sprite.x = 100;
red_sprite.y = 100;
app.stage.addChild(red_sprite);
const green_sprite = new Sprite(green_texture);
green_sprite.x = 200;
green_sprite.y = 100;
app.stage.addChild(green_sprite);
const blue_sprite = new Sprite(blue_texture);
blue_sprite.x = 300;
blue_sprite.y = 100;
app.stage.addChild(blue_sprite);
}
function drawCompositeTilemap(
app: Application,
red_texture: Texture,
green_texture: Texture,
blue_texture: Texture,
) {
const tilemap = new CompositeTilemap();
tilemap.tile(red_texture, 0, 0);
tilemap.tile(green_texture, 100, 0);
tilemap.tile(blue_texture, 200, 0);
tilemap.x = 100;
tilemap.y = 200;
app.stage.addChild(tilemap);
return tilemap;
}
function makeAtlas(
app: Application,
red_texture: Texture,
green_texture: Texture,
blue_texture: Texture,
): [Texture, Texture, Texture, Texture] {
const container = new Container();
const red_sprite = new Sprite(red_texture);
const green_sprite = new Sprite(green_texture);
const blue_sprite = new Sprite(blue_texture);
red_sprite.x = 0;
red_sprite.y = 0;
green_sprite.x = 50;
green_sprite.y = 0;
blue_sprite.x = 100;
blue_sprite.y = 0;
container.addChild(red_sprite);
container.addChild(green_sprite);
container.addChild(blue_sprite);
const atlas = app.renderer.generateTexture(container);
const redTex = new Texture({
source: atlas.source,
frame: new Rectangle(0, 0, 50, 50),
});
const greenTex = new Texture({
source: atlas.source,
frame: new Rectangle(50, 0, 50, 50),
});
const blueTex = new Texture({
source: atlas.source,
frame: new Rectangle(100, 0, 50, 50),
});
return [atlas, redTex, greenTex, blueTex];
}
function drawPlainTilemap(
app: Application,
atlas: Texture,
red_texture2: Texture,
green_texture2: Texture,
blue_texture2: Texture,
) {
const tilemap = new Tilemap(atlas.source);
tilemap.tile(red_texture2, 0, 0);
tilemap.tile(green_texture2, 100, 0);
tilemap.tile(blue_texture2, 200, 0);
tilemap.x = 100;
tilemap.y = 300;
app.stage.addChild(tilemap);
return tilemap;
}
function animateCounter(label: Text, frame: number) {
label.text = `frame: ${frame}`;
}
function animateCompositeTilemap(
tilemap: CompositeTilemap,
textures: Texture[],
frame: number,
) {
tilemap.clear();
const offset = Math.floor(frame / 50);
const idx0 = (offset + 0) % 3;
const idx1 = (offset + 1) % 3;
const idx2 = (offset + 2) % 3;
tilemap.tile(textures[idx0], 0, 0);
tilemap.tile(textures[idx1], 100, 0);
tilemap.tile(textures[idx2], 200, 0);
}
function animatePlainTilemap(
tilemap: Tilemap,
textures: Texture[],
frame: number,
) {
tilemap.clear();
const offset = Math.floor(frame / 50);
const idx0 = (offset + 0) % 3;
const idx1 = (offset + 1) % 3;
const idx2 = (offset + 2) % 3;
tilemap.tile(textures[idx0], 0, 0);
tilemap.tile(textures[idx1], 100, 0);
tilemap.tile(textures[idx2], 200, 0);
}
(async () => {
const app = await setup();
const [red_texture1, green_texture1, blue_texture1] = makeBlockTextures(app);
const [atlas, red_texture2, green_texture2, blue_texture2] = makeAtlas(
app,
red_texture1,
green_texture1,
blue_texture1,
);
drawBlocks(app, red_texture1, green_texture1, blue_texture1);
const compositeTilemap = drawCompositeTilemap(
app,
red_texture1,
green_texture1,
blue_texture1,
);
const tilemap = drawPlainTilemap(
app,
atlas,
red_texture2,
green_texture2,
blue_texture2,
);
const frameLabel = new Text({
text: "frame: 0",
style: { fill: 0xffffff, fontSize: 14 },
});
frameLabel.x = 8;
frameLabel.y = 8;
app.stage.addChild(frameLabel);
const texlist1 = [red_texture1, green_texture1, blue_texture1];
const texlist2 = [red_texture2, green_texture2, blue_texture2];
let frame = 0;
app.ticker.add(() => {
frame++;
animateCounter(frameLabel, frame);
animateCompositeTilemap(compositeTilemap, texlist1, frame);
animatePlainTilemap(tilemap, texlist2, frame);
});
})();