tilemap icon indicating copy to clipboard operation
tilemap copied to clipboard

Question: Is there a way to use this with `@pixi/spritesheet`?

Open earthiverse opened this issue 1 year ago • 7 comments

I am currently adding tiles as individual sprites / animated sprites to a container, but performance is not ideal on large maps, and I was wondering if this could help me improve performance.

I'm using Typescript, and I have a sprite sheet that I created and I want to use.

import { Assets } from "@pixi/assets";
import { Spritesheet } from "@pixi/spritesheet";

const sheetJson = await fetch("src/assets/map.json");
const sheetImage = await Assets.load("src/assets/map.png");
const spritesheet = new Spritesheet(sheetImage, await sheetJson.json());
await this.spritesheet.parse();

earthiverse avatar May 08 '24 01:05 earthiverse

Tilemap is already optimized to work with spritesheets.

ivanpopelyshev avatar May 08 '24 08:05 ivanpopelyshev

Tilemap is already optimized to work with spritesheets.

Is there example code anywhere? I'm using @pixi/tilemap 4.1.0 and @pixi/* 7.4.2

I can get the textures from the spritesheet and create an animated sprite with

const textures = spritesheet.animations[key];
const sprite = new AnimatedSprite(textures)

But I have no idea how to create a TileSheet with the textures from the spritesheet. This is what I tried, but I get The tile texture was not found in the tilemap tileset.

const tilemap = new Tilemap(spritesheet.baseTexture);
const textures = spritesheet.animations[key];
tilemap.tile(textures[0], 0, 0);

earthiverse avatar May 08 '24 22:05 earthiverse

I tried with the latest pixi.js 8.1.0 and @pixi/tilemap 5.0.1, and I can now tile static textures with

const tilemap = new Tilemap(spritesheet.textureSource);
const textures = spritesheet.animations[key];
tilemap.tile(textures[0], 0, 0);

earthiverse avatar May 09 '24 00:05 earthiverse

@earthiverse I'm not sure what is your exact use case, but remember, that animations in Tilemap are handled differently than in SpriteAnimations. SpriteAnimations changes texture (so, it's placement on spritesheet doesn't matter), but in Tileset all frames have to be in a fixed grid close to first tile. (you just provide number of frames and rows) - see basic example.

Also, you actually may not need to put each individual sprite in the spritesheet, as you can just provide whole tileset TextureSource and place tile providing source position by hand:

const tilemap = new Tilemap(textureSource);
// place tile, i.e. rect on textureSource image (sourceX, sourceY, tileWidth, tileHeight) on (targetX, targetY) position.
this.tilemap.tile(0, targetX, targetY, {tileWidth, tileHeight, u: sourceX, v: sourceY});

This might be especially useful if you use some tilemap editor with fixed-tile tilemap image source.

ajur avatar May 12 '24 19:05 ajur

@ajur I can see how the code I posted is very misleading, sorry, I was just trying to get something working before moving on.

I ended up with different issues using tilemap with a large number of tiles. They just stopped rendering. I got this about 1/3 the way through tiling a map 3936 x 3272 with a tile size of 16 x 16 firefox_Big8cX7vnv

I do have a mix of animated and non-animated tiles in my project, but the animated tiles are only 3 frames.

Making 3 RenderTextures, and just rendering the tiles to the textures is working well enough for me. I made a large animated sprite from my 3 large render textures.

earthiverse avatar May 13 '24 06:05 earthiverse

Did you enable 32-bit indices?

ivanpopelyshev avatar May 13 '24 07:05 ivanpopelyshev

Did you enable 32-bit indices?

I did not.

The readme on the main page says for use32bitIndex to "please use PixiJS v5.1.0", I guess I'll try again and see if it works on newer versions of PixiJS, too.

earthiverse avatar May 28 '24 00:05 earthiverse