use bevy::{prelude::*, sprite::SpriteBundle, DefaultPlugins};
use bevy_tiles::{commands::TileCommandExt, coords::CoordIterator, tiles_2d::*, TilesPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(TilesPlugin)
.add_systems(Startup, spawn)
.add_systems(Update, move_character)
.add_systems(PostUpdate, sync_tile_transforms)
.run();
}
#[derive(Component)]
struct Block;
#[derive(Component)]
struct Character;
#[derive(Component)]
struct GameLayer;
fn spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
let block = asset_server.load("block.png");
let character = asset_server.load("character.png");
commands.spawn(Camera2dBundle::default());
let mut map = commands.spawn_map(16, GameLayer);
let sprite_bundle = SpriteBundle {
texture: block,
..Default::default()
};
map.spawn_tile_batch(
CoordIterator::new([-5, 5], [5, 5])
.chain(CoordIterator::new([-5, -5], [5, -5]))
.chain(CoordIterator::new([5, -4], [5, 4]))
.chain(CoordIterator::new([-5, -4], [-5, 4])),
move |_| (Block, sprite_bundle.clone()),
);
map.spawn_tile(
IVec2::ZERO,
(
Character,
SpriteBundle {
texture: character,
..Default::default()
},
),
);
}
fn move_character(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut commands: Commands,
map: Query<Entity, With<GameLayer>>,
character: Query<&TileCoord, With<Character>>,
walls_maps: TileMapQuery<(), With<Block>>,
) {
let map_id = map.single();
let walls = walls_maps.get_map(map_id).unwrap();
let x = keyboard_input.just_pressed(KeyCode::KeyD) as i32
- keyboard_input.just_pressed(KeyCode::KeyA) as i32;
let y = keyboard_input.just_pressed(KeyCode::KeyW) as i32
- keyboard_input.just_pressed(KeyCode::KeyS) as i32;
let char_c = IVec2::from(*character.get_single().unwrap());
let new_coord = char_c + IVec2::new(x, y);
if (x != 0 || y != 0) && walls.get_at(new_coord).is_none() {
commands.move_tile(map_id, char_c, new_coord);
}
}
fn sync_tile_transforms(mut tiles: Query<(&TileCoord, &mut Transform), Changed<TileCoord>>) {
for (tile_c, mut transform) in tiles.iter_mut() {
transform.translation = Vec3::from((Vec2::from(*tile_c) * Vec2::ONE * 16.0, 0.0));
}
}