Basic right-click movement

This commit is contained in:
Gender Shrapnel 2022-12-24 02:43:18 +01:00
parent b562abe976
commit accda086f4
Signed by: modzero
GPG Key ID: 4E11A06C6D1E5213
3 changed files with 122 additions and 21 deletions

BIN
assets/pawn.aseprite Normal file

Binary file not shown.

BIN
assets/pawn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

View File

@ -4,7 +4,9 @@
use bevy::{ use bevy::{
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
input::mouse::MouseMotion, input::mouse::MouseMotion,
math::Vec4Swizzles,
prelude::*, prelude::*,
render::camera::RenderTarget,
}; };
use bevy_ecs_tilemap::prelude::*; use bevy_ecs_tilemap::prelude::*;
use defs::SurfaceDef; use defs::SurfaceDef;
@ -35,6 +37,9 @@ const TERRAINS: [SurfaceDef; 3] = [
}, },
]; ];
#[derive(Component)]
struct PlayerCharacter {}
#[derive(Component, Clone)] #[derive(Component, Clone)]
struct TileTerrain { struct TileTerrain {
terrain_id: usize, terrain_id: usize,
@ -46,9 +51,21 @@ impl TileTerrain {
} }
} }
#[derive(Component, Default, Clone, Copy, Debug)]
pub struct PawnPos {
pub x: u32,
pub y: u32,
}
#[derive(Component, Default, Clone, Copy, Debug)]
pub struct PawnDest {
pub x: u32,
pub y: u32,
}
#[derive(Bundle, Default)] #[derive(Bundle, Default)]
struct PawnBundle { struct PawnBundle {
position: TilePos, position: PawnPos,
sprite: Sprite, sprite: Sprite,
transform: Transform, transform: Transform,
global_transform: GlobalTransform, global_transform: GlobalTransform,
@ -62,7 +79,7 @@ fn make_ground_layer(
tilemap_size: TilemapSize, tilemap_size: TilemapSize,
texture_handle: Handle<Image>, texture_handle: Handle<Image>,
tile_size: TilemapTileSize, tile_size: TilemapTileSize,
) { ) -> Entity {
let mut tile_storage = TileStorage::empty(tilemap_size); let mut tile_storage = TileStorage::empty(tilemap_size);
let tilemap_entity = commands.spawn_empty().id(); let tilemap_entity = commands.spawn_empty().id();
@ -99,41 +116,59 @@ fn make_ground_layer(
transform: get_tilemap_center_transform(&tilemap_size, &grid_size, &map_type, 0.0), transform: get_tilemap_center_transform(&tilemap_size, &grid_size, &map_type, 0.0),
..Default::default() ..Default::default()
}); });
tilemap_entity
} }
fn make_pawn(commands: &mut Commands, texture_handle: Handle<Image>, tile_size: TilemapTileSize) { fn make_pawn(
commands.spawn(PawnBundle { commands: &mut Commands,
transform: Transform::from_xyz(0.0, 0.0, 1.0), tilemap_entity: Entity,
texture_handle: Handle<Image>,
tile_size: &TilemapTileSize,
map_size: &TilemapSize,
) {
let pos = PawnPos {
x: map_size.x / 2,
y: map_size.y / 2,
};
commands
.spawn(PawnBundle {
position: pos,
transform: Transform::from_xyz(
(pos.x as f32) * tile_size.x,
(pos.y as f32) * tile_size.y,
1.0,
),
texture: texture_handle, texture: texture_handle,
sprite: Sprite {
rect: Option::Some(Rect::new(
3. * tile_size.x,
4. * tile_size.y,
4. * tile_size.x,
5. * tile_size.y,
)),
..Default::default()
},
visibility: Visibility { is_visible: true }, visibility: Visibility { is_visible: true },
..Default::default() ..Default::default()
}); })
.insert(PlayerCharacter {})
.set_parent(tilemap_entity);
info!("Pawn at {:?}", pos);
} }
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) { fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
let texture_handle = asset_server.load("tileset.png"); let tileset_texture_handle = asset_server.load("tileset.png");
let pawn_texture_handle: Handle<Image> = asset_server.load("pawn.png");
let tilemap_size = TilemapSize { x: 320, y: 320 }; let tilemap_size = TilemapSize { x: 320, y: 320 };
let tile_size = TilemapTileSize { x: 32.0, y: 32.0 }; let tile_size = TilemapTileSize { x: 32.0, y: 32.0 };
make_ground_layer( let tilemap_entity = make_ground_layer(
&mut commands, &mut commands,
tilemap_size, tilemap_size,
texture_handle.clone(), tileset_texture_handle,
tile_size, tile_size,
); );
make_pawn(&mut commands, texture_handle, tile_size); make_pawn(
&mut commands,
tilemap_entity,
pawn_texture_handle,
&tile_size,
&tilemap_size,
);
} }
fn mouse_motion( fn mouse_motion(
@ -151,6 +186,70 @@ fn mouse_motion(
} }
} }
fn pawn_control(
mut commands: Commands,
wnds: Res<Windows>,
buttons: Res<Input<MouseButton>>,
query: Query<Entity, With<PlayerCharacter>>,
camera_q: Query<(&GlobalTransform, &Camera)>,
tilemap_q: Query<(&TilemapSize, &TilemapGridSize, &TilemapType, &Transform)>,
) {
if buttons.just_released(MouseButton::Right) {
let (cam_gt, cam) = camera_q.single();
let wnd = if let RenderTarget::Window(id) = cam.target {
wnds.get(id).unwrap()
} else {
wnds.get_primary().unwrap()
};
if let Some(screen_pos) = wnd.cursor_position() {
query.for_each(|entity| {
if let Some(world_ray) = cam.viewport_to_world(cam_gt, screen_pos) {
let (map_size, map_grid_size, map_type, map_t) = tilemap_q.single();
let tilemap_pos = (map_t.compute_matrix().inverse()
* Vec4::from((world_ray.origin, 1.0)))
.xy();
info!("WP {:?} {:?}", world_ray.origin, tilemap_pos);
if let Some(tile_pos) =
TilePos::from_world_pos(&tilemap_pos, map_size, map_grid_size, map_type)
{
info!("{:?}", tile_pos);
commands.entity(entity).insert(PawnDest {
x: tile_pos.x,
y: tile_pos.y,
});
}
}
});
}
}
}
fn pawn_motion(
mut commands: Commands,
mut pawn_q: Query<(Entity, &mut PawnPos, &mut Transform, Option<&PawnDest>)>,
tilemap_q: Query<(&TilemapGridSize, &TilemapTileSize, &TilemapType)>,
) {
let (map_grid_size, map_tile_size, map_type) = tilemap_q.single();
pawn_q.for_each_mut(|(entity, mut pos, mut transform, dest)| match dest {
Some(d) => {
pos.x = d.x;
pos.y = d.y;
transform.translation = Vec3::from((
(pos.x as f32) * map_tile_size.x,
(pos.y as f32) * map_tile_size.y,
1.0,
));
commands.entity(entity).remove::<PawnDest>();
}
None => {
let world_pos = TilePos::new(pos.x, pos.y).center_in_world(map_grid_size, map_type);
transform.translation.x = world_pos.x;
transform.translation.y = world_pos.y;
}
})
}
fn main() { fn main() {
App::new() App::new()
@ -172,5 +271,7 @@ fn main() {
.add_plugin(TilemapPlugin) .add_plugin(TilemapPlugin)
.add_startup_system(startup) .add_startup_system(startup)
.add_system(mouse_motion) .add_system(mouse_motion)
.add_system(pawn_control)
.add_system(pawn_motion)
.run(); .run();
} }