Basic right-click movement
This commit is contained in:
parent
b562abe976
commit
accda086f4
BIN
assets/pawn.aseprite
Normal file
BIN
assets/pawn.aseprite
Normal file
Binary file not shown.
BIN
assets/pawn.png
Normal file
BIN
assets/pawn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 442 B |
139
src/main.rs
139
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<Image>,
|
||||
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<Image>, tile_size: TilemapTileSize) {
|
||||
commands.spawn(PawnBundle {
|
||||
transform: Transform::from_xyz(0.0, 0.0, 1.0),
|
||||
fn make_pawn(
|
||||
commands: &mut Commands,
|
||||
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,
|
||||
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 },
|
||||
..Default::default()
|
||||
});
|
||||
})
|
||||
.insert(PlayerCharacter {})
|
||||
.set_parent(tilemap_entity);
|
||||
info!("Pawn at {:?}", pos);
|
||||
}
|
||||
|
||||
fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
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 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<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() {
|
||||
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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user