Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to make a tilemap with atlas? #527

Open
kyrosle opened this issue Mar 30, 2024 · 3 comments
Open

how to make a tilemap with atlas? #527

kyrosle opened this issue Mar 30, 2024 · 3 comments

Comments

@kyrosle
Copy link

kyrosle commented Mar 30, 2024

I want to create a tilemap where the image source comes from a large PNG file accompanied by XML data, similar to:

    <sprite n="part_0" x="380" y="94" w="32" h="32"/>
    <sprite n="part_1" x="482" y="94" w="32" h="32"/>
    <sprite n="part_2" x="904" y="60" w="32" h="32"/>

I have already loaded the large PNG and the XML file into a structure that contains a Handle and a Vec. However, I found that the example I am following uses a single PNG asset. Is there any way to use the atlas mentioned above to create a tilemap?
GameSpritePositionData:

pub struct GameSprite {
  #[serde(rename = "@n")]
  pub n: String,
  #[serde(rename = "@x")]
  pub x: f32,
  #[serde(rename = "@y")]
  pub y: f32,
  #[serde(rename = "@w")]
  pub w: f32,
  #[serde(rename = "@h")]
  pub h: f32,
}
@StarArawn
Copy link
Owner

You simply need to convert the x and y values to a tile id. Typically in an atlas texture the tiles are read row by row. Take a 128x64 atlas where each tile is 32x32. We can figure out how many tiles we have quickly by dividing the atlas size by the tile size. To get the atlas tile id you would simply do the following:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=534552b0eccb0b6602f84d2ff7502798

Let me know if you have any other questions!

@kyrosle
Copy link
Author

kyrosle commented Mar 31, 2024

However, sometimes the atlas might not have assets of the same size, possibly including tiles, characters, etc. Does the tile ID refer to this?

        let tile_entity = commands
            .spawn((
                TileBundle {
                    position: tile_pos,
                    tilemap_id: TilemapId(tilemap_entity),
                    texture_index: TileTextureIndex(0), // <--- this
                    ..Default::default()
                },
                // To enable animation, we must insert the `AnimatedTile` component on
                // each tile that is to be animated.
                AnimatedTile {
                    start: 0,
                    end: 13,
                    speed: 0.95,
                },
            ))
            .id();

        tile_storage.set(&tile_pos, tile_entity);

@ThunderSizzle
Copy link

@kyrosle: In my learning about sprites and atlases, no, it doesn't handle this. It assumes every sprite is normalized in shape (e.g. every rectangle is the same size).

I was trying to use bevy's TextureAtlasBuilder, which was causing very wonky results for that very reason. TileAtlasBuilder works much better, but every sprite still needs to be the exact same size at design time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants