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

Make tilemap respond to Anchor component. #596

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2ae34df
feature: Make tilemap respond to Anchor component.
shanecelis Feb 3, 2025
e75fcd4
style: Reformat.
shanecelis Feb 3, 2025
ea0a71a
bug: Only compile anchor example with "render".
shanecelis Feb 3, 2025
3a1fbfb
feature: Use TilemapAnchor, not sprite::Anchor.
shanecelis Feb 4, 2025
897d197
feature: Update all examples that use center.
shanecelis Feb 4, 2025
50f678f
style: Reformat.
shanecelis Feb 4, 2025
32235a5
refactor: Move non-generic code to helper.
shanecelis Feb 4, 2025
b822b67
doc: Document sparsely; add derives.
shanecelis Feb 4, 2025
3facd3b
feature: Register `TilemapAnchor` type.
shanecelis Feb 5, 2025
77cc2cb
style: Reformat.
shanecelis Feb 5, 2025
f85f198
refactor: Add anchor arg to `center_in_world()`.
shanecelis Feb 10, 2025
9c695cb
chore: Listen to clippy.
shanecelis Feb 10, 2025
5a925ba
style: Reformat.
shanecelis Feb 10, 2025
a93013d
refactor: Use Transform instead of += Vec2.
shanecelis Feb 10, 2025
9d539ff
refactor: Make as_offset() public.
shanecelis Feb 11, 2025
93db3f5
chore: Remove duplicate feature in Cargo.
shanecelis Feb 11, 2025
a80fa01
chore: Accept Clippy's new advice.
shanecelis Feb 23, 2025
8bdfd43
doc: Explain anchor offset better.
shanecelis Feb 26, 2025
94fd026
refactor: Require TilemapTileSize arg for 3 fns.
shanecelis Mar 4, 2025
2e68c93
feature: TAB changes grid size in hex_neighbors.
shanecelis Mar 4, 2025
808e717
style: Reformat.
shanecelis Mar 4, 2025
533a30d
feature: UI label and inst. in hex_neighbors.
shanecelis Mar 4, 2025
48483df
chore: Permit too many args in example.
shanecelis Mar 4, 2025
94e4587
refactor: Remove comment and named option.
shanecelis Mar 4, 2025
fe9fa3a
feature: Replace anchor.rs with hex_neighbors.
shanecelis Mar 8, 2025
d10dc7f
feature: Restore original hex_neighbors.
shanecelis Mar 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ features = [
"multi_threaded",
"default_font",
"webgl2",
"default_font",
"bevy_gizmos",
]

[target.'cfg(unix)'.dev-dependencies.bevy]
Expand All @@ -74,7 +74,7 @@ features = [
"multi_threaded",
"default_font",
"webgl2",
"default_font",
"bevy_gizmos",
]


Expand Down Expand Up @@ -198,3 +198,7 @@ required-features = ["render"]
name = "visibility"
path = "examples/visibility.rs"
required-features = ["render"]
[[example]]
name = "anchor"
path = "examples/anchor.rs"
required-features = ["render"]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ A tilemap rendering plugin for [`bevy`](https://bevyengine.org/). It is more ECS
- GPU powered animations.
- Isometric and Hexagonal tile maps.
- Examples for integration with [Tiled](https://www.mapeditor.org/) and [LDTK](https://ldtk.io/) editors.
- Can `Anchor` tilemap like a sprite.

## Screenshots

Expand Down
2 changes: 1 addition & 1 deletion examples/accessing_tiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
map_type,
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
..Default::default()
},
LastUpdate(0.0),
Expand Down
159 changes: 159 additions & 0 deletions examples/anchor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
//! Demonstrate tilemap with an [Anchor] component.
use bevy::prelude::*;
use bevy_ecs_tilemap::prelude::*;
use rand::seq::SliceRandom;
use rand::thread_rng;

mod helpers;
use helpers::anchor::rotate_right;

fn color(s: &str) -> Color {
Srgba::hex(s).expect("hex color").into()
}

fn startup(
mut commands: Commands,
asset_server: Res<AssetServer>,
#[cfg(all(not(feature = "atlas"), feature = "render"))] array_texture_loader: Res<
ArrayTextureLoader,
>,
) {
commands.spawn(Camera2d);

let texture_handle: Handle<Image> = asset_server.load("tiles.png");

let map_size = TilemapSize { x: 12, y: 12 };

// Create a tilemap entity a little early.
// We want this entity early because we need to tell each tile which tilemap entity
// it is associated with. This is done with the TilemapId component on each tile.
// Eventually, we will insert the `TilemapBundle` bundle on the entity, which
// will contain various necessary components, such as `TileStorage`.
let tilemap_entity = commands.spawn_empty().id();

// To begin creating the map we will need a `TileStorage` component.
// This component is a grid of tile entities and is used to help keep track of individual
// tiles in the world. If you have multiple layers of tiles you would have a tilemap entity
// per layer, each with their own `TileStorage` component.
let mut tile_storage = TileStorage::empty(map_size);

let mut rng = thread_rng();
let colors: Vec<Color> = vec![
color("FFBE0B"),
color("FB5607"),
color("FF006E"),
color("8338EC"),
color("3A86FF"),
];

// Spawn the elements of the tilemap.
// Alternatively, you can use helpers::filling::fill_tilemap.
for x in 0..map_size.x {
for y in 0..map_size.y {
let tile_pos = TilePos { x, y };
let tile_entity = commands
.spawn(TileBundle {
position: tile_pos,
tilemap_id: TilemapId(tilemap_entity),
color: TileColor(*colors.choose(&mut rng).unwrap()),
..Default::default()
})
.id();
tile_storage.set(&tile_pos, tile_entity);
}
}

let tile_size = TilemapTileSize { x: 16.0, y: 16.0 };
let grid_size = tile_size.into();
let map_type = TilemapType::default();

// The tilemap is placed at the origin, but its anchor can change.
commands.entity(tilemap_entity).insert(TilemapBundle {
grid_size,
map_type,
size: map_size,
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: Transform::IDENTITY,
anchor: TilemapAnchor::TopLeft,
..Default::default()
});

// Add atlas to array texture loader so it's preprocessed before we need to use it.
// Only used when the atlas feature is off and we are using array textures.
#[cfg(all(not(feature = "atlas"), feature = "render"))]
{
array_texture_loader.add(TilemapArrayTexture {
texture: TilemapTexture::Single(asset_server.load("tiles.png")),
tile_size,
..Default::default()
});
}
}

fn mark_origin(mut gizmos: Gizmos) {
gizmos.axes_2d(Transform::IDENTITY, 1000.0);
}

fn change_anchor(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut query: Query<&mut TilemapAnchor, With<TilemapTexture>>,
text: Single<Entity, With<Text>>,
mut writer: TextUiWriter,
) {
if keyboard_input.just_pressed(KeyCode::Space) {
for mut anchor in &mut query {
*anchor = rotate_right(&anchor);
*writer.text(*text, 1) = format!("{:?}", *anchor);
}
}
}

fn main() {
App::new()
.add_plugins(
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
title: String::from("Anchor Example - Press Space to change anchor."),
resolution: Vec2::splat(450.0).into(),
..Default::default()
}),
..default()
})
.set(ImagePlugin::default_nearest()),
)
.add_plugins(TilemapPlugin)
.add_systems(Startup, startup)
.add_systems(Startup, setup_header)
.add_systems(Update, helpers::camera::movement)
.add_systems(Update, change_anchor)
.add_systems(Update, mark_origin)
.run();
}

fn setup_header(mut commands: Commands) {
let font_size = 15.0;
commands
.spawn((
Text::new("Anchor: "),
TextLayout::new_with_justify(JustifyText::Center),
TextFont {
font_size,
..default()
},
Node {
top: Val::Px(10.0),
left: Val::Px(10.0),
..default()
},
))
.with_child((
TextSpan::new("TopLeft"),
TextFont {
font_size,
..default()
},
));
}
5 changes: 3 additions & 2 deletions examples/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn create_background(mut commands: Commands, asset_server: Res<AssetServer>) {
tile_size,
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
transform: get_tilemap_center_transform(&size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
..Default::default()
});
}
Expand Down Expand Up @@ -117,7 +117,8 @@ fn create_animated_flowers(mut commands: Commands, asset_server: Res<AssetServer
tile_size,
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 1.0),
anchor: TilemapAnchor::Center,
transform: Transform::from_xyz(0.0, 0.0, 1.0),
..Default::default()
});
}
Expand Down
2 changes: 1 addition & 1 deletion examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn startup(
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
..Default::default()
});

Expand Down
2 changes: 1 addition & 1 deletion examples/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
render_settings: TilemapRenderSettings {
render_chunk_size: UVec2::new(256, 256),
..Default::default()
Expand Down
3 changes: 1 addition & 2 deletions examples/colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {

let tile_size = TilemapTileSize { x: 16.0, y: 16.0 };
let grid_size = tile_size.into();
let map_type = TilemapType::default();

commands.entity(tilemap_entity).insert(TilemapBundle {
grid_size,
Expand All @@ -85,7 +84,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
texture: TilemapTexture::Single(texture_handle),
tile_size,
map_type: TilemapType::Square,
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
..Default::default()
});
}
Expand Down
6 changes: 3 additions & 3 deletions examples/custom_shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn startup(
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle.clone()),
tile_size,
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
material: my_material_handle.clone(),
..Default::default()
});
Expand All @@ -84,8 +84,8 @@ fn startup(
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
tile_size: TilemapTileSize { x: 16.0, y: 16.0 },
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 1.0)
* Transform::from_xyz(32.0, 32.0, 0.0),
anchor: TilemapAnchor::Center,
transform: Transform::from_xyz(32.0, 32.0, 1.0),
material: my_material_handle,
..Default::default()
});
Expand Down
2 changes: 1 addition & 1 deletion examples/game_of_life.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
storage: tile_storage,
texture: TilemapTexture::Single(texture_handle),
tile_size,
transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
anchor: TilemapAnchor::Center,
..Default::default()
},
LastUpdate(0.0),
Expand Down
20 changes: 20 additions & 0 deletions examples/helpers/anchor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use bevy::prelude::Vec2;
use bevy_ecs_tilemap::anchor::TilemapAnchor;

#[allow(dead_code)]
pub fn rotate_right(anchor: &TilemapAnchor) -> TilemapAnchor {
use TilemapAnchor::*;
match anchor {
TopLeft => TopCenter,
TopCenter => TopRight,
TopRight => CenterRight,
CenterRight => BottomRight,
BottomRight => BottomCenter,
BottomCenter => BottomLeft,
BottomLeft => CenterLeft,
CenterLeft => Center,
Center => Custom(Vec2::splat(0.25)),
Custom(_) => None,
None => TopLeft,
}
}
10 changes: 3 additions & 7 deletions examples/helpers/ldtk.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bevy_ecs_tilemap::{
helpers::geometry::get_tilemap_center_transform,
anchor::TilemapAnchor,
map::{TilemapId, TilemapSize, TilemapTexture, TilemapTileSize},
tiles::{TileBundle, TilePos, TileStorage, TileTextureIndex},
TilemapBundle,
Expand Down Expand Up @@ -227,12 +227,8 @@ pub fn process_loaded_tile_maps(
storage,
texture: TilemapTexture::Single(texture),
tile_size,
transform: get_tilemap_center_transform(
&size,
&grid_size,
&map_type,
layer_id as f32,
),
anchor: TilemapAnchor::Center,
transform: Transform::from_xyz(0.0, 0.0, layer_id as f32),
..default()
});
}
Expand Down
1 change: 1 addition & 0 deletions examples/helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod anchor;
pub mod camera;
pub mod ldtk;
pub mod tiled;
8 changes: 2 additions & 6 deletions examples/helpers/tiled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,8 @@ pub fn process_loaded_maps(
texture: tilemap_texture.clone(),
tile_size,
spacing: tile_spacing,
transform: get_tilemap_center_transform(
&map_size,
&grid_size,
&map_type,
layer_index as f32,
) * Transform::from_xyz(offset_x, -offset_y, 0.0),
anchor: TilemapAnchor::Center,
transform: Transform::from_xyz(offset_x, -offset_y, layer_index as f32),
map_type,
render_settings: *render_settings,
..Default::default()
Expand Down
Loading