From c81d17ce3178ae1f532efc460349194e36846895 Mon Sep 17 00:00:00 2001 From: Patrick Gelvin Date: Sun, 24 Aug 2025 09:50:58 -0700 Subject: [PATCH] Initial fuckery with ecs tilemap --- Cargo.toml | 1 + src/assets.rs | 17 +++++++--- src/game/map.rs | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ src/game/mod.rs | 2 ++ src/main.rs | 31 ++++++++++++++++-- 5 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 src/game/map.rs diff --git a/Cargo.toml b/Cargo.toml index f4ae34e..fdc5601 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] bevy = { version = "0.16.1", features = ["dynamic_linking"] } bevy-inspector-egui = "0.33.1" +bevy_ecs_tilemap = "0.16.0" [profile.dev] opt-level = 1 diff --git a/src/assets.rs b/src/assets.rs index 8fddd7f..c2f780a 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -2,14 +2,14 @@ use bevy::prelude::*; use std::path::Path; pub struct TileImage { - name: &'static str, - thumbnail_handle: Handle, - tile_handle: Handle, + pub name: &'static str, + pub thumbnail_handle: Handle, + pub tile_handle: Handle, } #[derive(Resource)] pub struct AssetLibrary { - tile_images: Vec, + pub tile_images: Vec, } impl AssetLibrary { @@ -59,6 +59,15 @@ impl AssetLibrary { Self { tile_images } } + pub fn get_index(&self, name: &str) -> Option { + self + .tile_images + .iter() + .enumerate() + .find(|(_, tile)| tile.name == name) + .map(|(index, _)| index as u32) + } + pub fn get_thumbnail(&self, name: &str) -> Option> { self .tile_images diff --git a/src/game/map.rs b/src/game/map.rs new file mode 100644 index 0000000..beb850e --- /dev/null +++ b/src/game/map.rs @@ -0,0 +1,85 @@ +use bevy::prelude::*; +use bevy_ecs_tilemap::prelude::*; + +use crate::assets::AssetLibrary; + +pub fn setup_test_tilemap(mut commands: Commands, assets: Res) { + let tilemap_entity = commands.spawn_empty().id(); + let tilemap_id = TilemapId(tilemap_entity); + + let map_size = TilemapSize { x: 9, y: 9 }; + let mut tile_storage = TileStorage::empty(map_size); + + vec![ + ( + (0, 0), + assets.get_index("corner-sw-1-wall").unwrap(), + TileFlip::default(), + ), + ( + (1, 0), + 17, + TileFlip { + y: true, + ..Default::default() + }, + ), + ((2, 0), 8, TileFlip::default()), + ( + (0, 1), + 17, + TileFlip { + d: true, + ..Default::default() + }, + ), + ((1, 1), 16, TileFlip::default()), + ( + (2, 1), + 17, + TileFlip { + x: true, + d: true, + ..Default::default() + }, + ), + ((0, 2), 4, TileFlip::default()), + ((1, 2), 17, TileFlip::default()), + ((2, 2), 0, TileFlip::default()), + ] + .iter() + .for_each(|((x, y), texture_index, flip)| { + let position = TilePos { x: *x, y: *y }; + let tile_entity = commands + .spawn(TileBundle { + position, + tilemap_id, + texture_index: TileTextureIndex(*texture_index), + flip: *flip, + ..Default::default() + }) + .id(); + tile_storage.set(&position, tile_entity); + }); + + let tile_size = TilemapTileSize { x: 48.0, y: 48.0 }; + let grid_size = tile_size.into(); + let map_type = TilemapType::default(); + + let texture_handles = assets + .tile_images + .iter() + .map(|image| image.tile_handle.clone()) + .collect(); + + commands.entity(tilemap_entity).insert(TilemapBundle { + grid_size, + map_type, + size: map_size, + storage: tile_storage, + texture: TilemapTexture::Vector(texture_handles), + tile_size, + anchor: TilemapAnchor::BottomLeft, + ..Default::default() + }); +} diff --git a/src/game/mod.rs b/src/game/mod.rs index 159a5b7..abafc61 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,5 +1,7 @@ use bevy::prelude::*; +pub mod map; + /// Data component for info about the player's current set of cards. /// /// [`Self::capacity`] is the maximum hand size. diff --git a/src/main.rs b/src/main.rs index ebf503f..c097645 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use bevy::{color::palettes::css::GREEN, prelude::*, window::WindowResolution}; +use bevy_ecs_tilemap::prelude::*; use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; use crate::{ @@ -24,12 +25,38 @@ fn main() { .add_plugins(EguiPlugin::default()) .add_plugins(WorldInspectorPlugin::new()) .add_plugins(widgets::GameUiPlugin) - .add_systems(Startup, (setup, assets::load_assets, dummy_machine)) + .add_plugins(TilemapPlugin) + .init_resource::() + .register_type::() + .add_systems( + Startup, + ( + setup, + assets::load_assets, + game::map::setup_test_tilemap, + dummy_machine, + ) + .chain(), + ) .run(); } fn setup(mut commands: Commands) { - commands.spawn(Camera2d); + commands.spawn(( + Camera2d, + Projection::Orthographic(OrthographicProjection { + scaling_mode: bevy::render::camera::ScalingMode::AutoMin { + min_width: 360.0, + min_height: 240.0, + }, + ..OrthographicProjection::default_2d() + }), + Transform::from_translation(Vec3 { + x: 72., + y: 72., + z: 0., + }), + )); } /// Generic utility for despawning entities that have a given component.