From accda086f403e5672a15880111328888c11b6f5f Mon Sep 17 00:00:00 2001 From: ModZero Date: Sat, 24 Dec 2022 02:43:18 +0100 Subject: [PATCH] Basic right-click movement --- assets/pawn.aseprite | Bin 0 -> 1130 bytes assets/pawn.png | Bin 0 -> 442 bytes src/main.rs | 143 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 122 insertions(+), 21 deletions(-) create mode 100644 assets/pawn.aseprite create mode 100644 assets/pawn.png diff --git a/assets/pawn.aseprite b/assets/pawn.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..0d7af7f16d2e18e139de124f756f9dde992a4316 GIT binary patch literal 1130 zcmcJMYe-XJ7{}kad25D3W*C{LGBs*7Z!>GD%r2s3rf6iNoF`YCYpb=&T9k!pEp3vP zIJ+n`FI}YqqYvHOlCVuG$Yy3`7s*JvU|E`{|7NIAUwaPccb@aU=kWhM=g2vPyfm^1 zZZ<9g!O+FY|rUVmZ^T3qE05DV-1;)f^ zKz`-{aINwcNLMo8ddnNI<=G&}pa`kF*a+tDEd*t9Ik+Z01>7OhffqtULECB?Y}4KV z_2mhmPQ_>B7=S}CFNFp}U;^mF9pbQtGJGKmQ)t2wg0O=cydVW5=-6Et1{P32KEjcV zSY#p)X^651aO@Z$Zk=&CX@36*W_7I7wQGWw1W@xwdMk3V$3&39XTl^J)c`i1Xhqrb>a&}l9e9gI!>y1O_b?v1`|m$F|7RQB4hN{EA%4?l;Vq z)}6EJZVqyHMqFMur9zcI;eDEQP?y?gjn;-uY`eBhd{+5-QNxeU#*%%RAN1cQpO2_) z?YYjCECEjxYKwWJ zV5aoZBe7VjH*j6?^kcEO|9eo_{Cl<5v?dp`!t0D7H`tK4Ijmkb_oyZ>Y$$#eSI&N! z!aWw(e74SPbPZg3A!APuE4H|szs@lP8-LYl%qQm(PkeGZGuBylqJViA!uH8q;V0smW5t}g<0~-mb{fb5@A})`wiZq BVx<58 literal 0 HcmV?d00001 diff --git a/assets/pawn.png b/assets/pawn.png new file mode 100644 index 0000000000000000000000000000000000000000..4ac4ae5171a5af35b6194420932832e1e2ac49eb GIT binary patch literal 442 zcmV;r0Y(0aP)Px$bV)=(R9J=Wm%mB_K@i42MeI`O8(78m3WWnD5b*)>23BXRQYhjhh@?qn*jEt) zmlLiDT&qQ%AaI3Xqs3XsE|+!x&F&ov`oR¬f{KnZ1Pt{<=1Nl9D*8m35CE`RE->#5 z$N*knfvVNrGuHk=REK!kKKZtureiXM^9Xvqt4d`m$Fu@aFU;~n97Ih(SX(9+?7lw& zP>-N4*Kv?PLz^*|YbT5Vx+1O+!2qFh=|ZajF8T*B0;K6UsCZ~T093l?@~ literal 0 HcmV?d00001 diff --git a/src/main.rs b/src/main.rs index bf556b0..86976c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,9 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, input::mouse::MouseMotion, + math::Vec4Swizzles, prelude::*, + render::camera::RenderTarget, }; use bevy_ecs_tilemap::prelude::*; use defs::SurfaceDef; @@ -35,6 +37,9 @@ const TERRAINS: [SurfaceDef; 3] = [ }, ]; +#[derive(Component)] +struct PlayerCharacter {} + #[derive(Component, Clone)] struct TileTerrain { 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)] struct PawnBundle { - position: TilePos, + position: PawnPos, sprite: Sprite, transform: Transform, global_transform: GlobalTransform, @@ -62,7 +79,7 @@ fn make_ground_layer( tilemap_size: TilemapSize, texture_handle: Handle, tile_size: TilemapTileSize, -) { +) -> Entity { let mut tile_storage = TileStorage::empty(tilemap_size); 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), ..Default::default() }); + tilemap_entity } -fn make_pawn(commands: &mut Commands, texture_handle: Handle, tile_size: TilemapTileSize) { - commands.spawn(PawnBundle { - transform: Transform::from_xyz(0.0, 0.0, 1.0), - 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, - )), +fn make_pawn( + commands: &mut Commands, + tilemap_entity: Entity, + texture_handle: Handle, + 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, + visibility: Visibility { is_visible: true }, ..Default::default() - }, - visibility: Visibility { is_visible: true }, - ..Default::default() - }); + }) + .insert(PlayerCharacter {}) + .set_parent(tilemap_entity); + info!("Pawn at {:?}", pos); } fn startup(mut commands: Commands, asset_server: Res) { 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 = asset_server.load("pawn.png"); let tilemap_size = TilemapSize { x: 320, y: 320 }; let tile_size = TilemapTileSize { x: 32.0, y: 32.0 }; - make_ground_layer( + let tilemap_entity = make_ground_layer( &mut commands, tilemap_size, - texture_handle.clone(), + tileset_texture_handle, 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( @@ -151,6 +186,70 @@ fn mouse_motion( } } +fn pawn_control( + mut commands: Commands, + wnds: Res, + buttons: Res>, + query: Query>, + 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::(); + } + 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() { App::new() @@ -172,5 +271,7 @@ fn main() { .add_plugin(TilemapPlugin) .add_startup_system(startup) .add_system(mouse_motion) + .add_system(pawn_control) + .add_system(pawn_motion) .run(); }