use bevy::{
math::{ivec2, uvec2},
prelude::*,
window::WindowResolution,
};
use bevy_simple_tilemap::prelude::*;
fn main() {
App::new()
.add_plugins(
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
resolution: WindowResolution::new(1280, 720).with_scale_factor_override(1.0),
..Default::default()
}),
..default()
})
.set(ImagePlugin::default_nearest()),
)
.add_plugins(SimpleTileMapPlugin)
.add_systems(Startup, setup)
.add_systems(Update, input_system)
.add_systems(FixedUpdate, (update_tiles1_system, update_tiles2_system))
.insert_resource(Time::<Fixed>::from_seconds(0.05))
.run();
}
fn input_system(
mut camera_transform_query: Query<&mut Transform, With<Camera2d>>,
mut tilemap_visible_query: Query<&mut Visibility, With<TileMap>>,
keyboard_input: Res<ButtonInput<KeyCode>>,
time: Res<Time>,
) {
const MOVE_SPEED: f32 = 1000.0;
const ZOOM_SPEED: f32 = 10.0;
if let Some(mut tf) = camera_transform_query.iter_mut().next() {
if keyboard_input.pressed(KeyCode::KeyX) {
tf.scale -= Vec3::splat(ZOOM_SPEED) * time.delta_secs();
} else if keyboard_input.pressed(KeyCode::KeyZ) {
tf.scale += Vec3::splat(ZOOM_SPEED) * time.delta_secs();
}
if keyboard_input.pressed(KeyCode::KeyA) {
tf.translation.x -= MOVE_SPEED * time.delta_secs();
} else if keyboard_input.pressed(KeyCode::KeyD) {
tf.translation.x += MOVE_SPEED * time.delta_secs();
}
if keyboard_input.pressed(KeyCode::KeyS) {
tf.translation.y -= MOVE_SPEED * time.delta_secs();
} else if keyboard_input.pressed(KeyCode::KeyW) {
tf.translation.y += MOVE_SPEED * time.delta_secs();
}
if keyboard_input.just_pressed(KeyCode::KeyV) {
let mut visibility = tilemap_visible_query.iter_mut().next().unwrap();
if *visibility == Visibility::Hidden {
*visibility = Visibility::Visible;
} else {
*visibility = Visibility::Hidden;
}
}
}
}
fn update_tiles1_system(mut query: Query<(&mut TileMap, &mut TileMap1)>) {
for (mut tilemap, state) in query.iter_mut() {
let state = state.into_inner();
let pos = &mut state.pos;
let sprite_index = &mut state.sprite_index;
tilemap.set_tile(
pos.extend(1),
Some(Tile {
sprite_index: *sprite_index,
..Default::default()
}),
);
pos.x += 1;
if pos.x > 9 {
pos.x = 0;
pos.y += 1;
if pos.y > 9 {
pos.y = 0;
*sprite_index += 1;
if *sprite_index > 3 {
*sprite_index = 0;
}
}
}
}
}
fn update_tiles2_system(mut query: Query<(&mut TileMap, &mut TileMap2)>) {
for (mut tilemap, state) in query.iter_mut() {
let state = state.into_inner();
let pos = &mut state.pos;
let direction = &mut state.direction;
let level = &mut state.level;
if *level > 4 {
tilemap.clear_layer(1);
*pos = ivec2(0, 0);
*level = 0;
}
tilemap.set_tile(
pos.extend(1),
Some(Tile {
sprite_index: 3,
..Default::default()
}),
);
match *direction {
0 => {
pos.x += 1;
if pos.x > (8 - *level) {
*direction += 1;
}
}
1 => {
pos.y += 1;
if pos.y > (8 - *level) {
*direction += 1;
}
}
2 => {
pos.x -= 1;
if pos.x < (1 + *level) {
*direction += 1;
}
}
3 => {
pos.y -= 1;
if pos.y < (2 + *level) {
*direction = 0;
*level += 1;
}
}
_ => {}
};
}
}
#[derive(Component)]
struct TileMap1 {
pos: IVec2,
sprite_index: u32,
}
#[derive(Component)]
struct TileMap2 {
pos: IVec2,
direction: u8,
level: i32,
}
fn setup(
asset_server: Res<AssetServer>,
mut commands: Commands,
mut texture_atlases: ResMut<Assets<TextureAtlasLayout>>,
) {
let image = asset_server.load("textures/tilesheet.png");
let atlas = TextureAtlasLayout::from_grid(uvec2(16, 16), 4, 1, Some(uvec2(1, 1)), None);
let atlas_handle = texture_atlases.add(atlas);
let mut tiles = Vec::new();
for y in 0..10 {
for x in 0..10 {
tiles.push((
IVec3::new(x, y, 0),
Some(Tile {
sprite_index: 2,
..Default::default()
}),
));
}
}
let tilemap1 = {
let mut tilemap = TileMap::new(image.clone(), atlas_handle.clone());
tilemap.set_tiles(tiles.clone());
(
tilemap,
Transform {
scale: Vec3::splat(3.0),
translation: Vec3::new(-500.0, -(16.0 * 3.0 * 10.0 / 2.0), 0.0),
..Default::default()
},
TileMap1 {
pos: ivec2(0, 0),
sprite_index: 0,
},
)
};
let tilemap2 = {
let mut tilemap = TileMap::new(image, atlas_handle);
tilemap.set_tiles(tiles);
(
tilemap,
Transform {
scale: Vec3::splat(3.0),
translation: Vec3::new(60.0, -(16.0 * 3.0 * 10.0 / 2.0), 0.0),
..Default::default()
},
TileMap2 {
pos: ivec2(0, 0),
direction: 0,
level: 0,
},
)
};
commands.spawn(Camera2d::default());
commands.spawn(tilemap1);
commands.spawn(tilemap2);
}