mouse camera controls
This commit is contained in:
@@ -1,46 +1,59 @@
|
|||||||
use bevy::{input::ButtonInput, math::Vec3, prelude::*, render::camera::Camera};
|
use bevy::{
|
||||||
|
input::{mouse::MouseWheel, ButtonInput},
|
||||||
|
prelude::*,
|
||||||
|
render::camera::Camera,
|
||||||
|
window::PrimaryWindow,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::TileOffset;
|
use crate::TileOffset;
|
||||||
|
|
||||||
// Todo: Middle mouse button should drag the playfield around
|
pub fn mouse_zoom(
|
||||||
// Zoom with + and -
|
mut evr_scroll: EventReader<MouseWheel>,
|
||||||
#[allow(dead_code)]
|
mut query: Query<&mut OrthographicProjection, With<Camera>>,
|
||||||
pub fn movement(
|
|
||||||
time: Res<Time>,
|
|
||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
||||||
mut query: Query<(&mut Transform, &mut TileOffset, &mut OrthographicProjection), With<Camera>>,
|
|
||||||
) {
|
) {
|
||||||
for (mut transform, mut offset, mut ortho) in query.iter_mut() {
|
use bevy::input::mouse::MouseScrollUnit;
|
||||||
let mut direction = Vec3::ZERO;
|
for ev in evr_scroll.read() {
|
||||||
|
match ev.unit {
|
||||||
|
MouseScrollUnit::Line => {
|
||||||
|
let scroll = ev.y / 10.0;
|
||||||
|
|
||||||
if keyboard_input.pressed(KeyCode::KeyA) {
|
for mut ortho in query.iter_mut() {
|
||||||
direction -= Vec3::new(1.0, 0.0, 0.0);
|
ortho.scale -= scroll;
|
||||||
|
ortho.scale = ortho.scale.clamp(0.5, 1.0);
|
||||||
|
dbg!(ortho.scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseScrollUnit::Pixel => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if keyboard_input.pressed(KeyCode::KeyD) {
|
pub fn mouse_movement(
|
||||||
direction += Vec3::new(1.0, 0.0, 0.0);
|
primary_window: Query<&Window, With<PrimaryWindow>>,
|
||||||
}
|
mouse_buttons: Res<ButtonInput<MouseButton>>,
|
||||||
|
mut query: Query<(&mut Transform, &mut TileOffset, &OrthographicProjection), With<Camera>>,
|
||||||
|
mut last_pos: Local<Option<Vec2>>,
|
||||||
|
) {
|
||||||
|
if !mouse_buttons.pressed(MouseButton::Middle) {
|
||||||
|
*last_pos = None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if keyboard_input.pressed(KeyCode::KeyW) {
|
let Ok(window) = primary_window.get_single() else {
|
||||||
direction += Vec3::new(0.0, 1.0, 0.0);
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
if keyboard_input.pressed(KeyCode::KeyS) {
|
for (mut transform, mut offset, ortho) in query.iter_mut() {
|
||||||
direction -= Vec3::new(0.0, 1.0, 0.0);
|
let current_pos = match window.cursor_position() {
|
||||||
}
|
Some(c) => Vec2::new(c.x, -c.y),
|
||||||
|
None => return,
|
||||||
if keyboard_input.pressed(KeyCode::KeyZ) {
|
};
|
||||||
ortho.scale += time.delta_seconds();
|
let delta_device_pixels = current_pos - last_pos.unwrap_or(current_pos);
|
||||||
}
|
*last_pos = Some(current_pos);
|
||||||
|
|
||||||
if keyboard_input.pressed(KeyCode::KeyX) {
|
|
||||||
ortho.scale -= time.delta_seconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
ortho.scale = ortho.scale.clamp(0.5, 1.0);
|
|
||||||
|
|
||||||
let z = transform.translation.z;
|
let z = transform.translation.z;
|
||||||
offset.translation += time.delta_seconds() * direction * (16.0 * 8.0);
|
offset.translation.x -= delta_device_pixels.x * ortho.scale;
|
||||||
|
offset.translation.y -= delta_device_pixels.y * ortho.scale;
|
||||||
|
|
||||||
offset.x = (offset.translation.x / 16.0) as isize;
|
offset.x = (offset.translation.x / 16.0) as isize;
|
||||||
offset.y = (offset.translation.y / 16.0) as isize;
|
offset.y = (offset.translation.y / 16.0) as isize;
|
||||||
|
@@ -86,7 +86,13 @@ impl Plugin for GridPlugin {
|
|||||||
app.add_systems(Startup, generate_grid);
|
app.add_systems(Startup, generate_grid);
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
First,
|
First,
|
||||||
(camera::movement, update_cursor_pos, click_tile).chain(),
|
(
|
||||||
|
camera::mouse_movement,
|
||||||
|
camera::mouse_zoom,
|
||||||
|
update_cursor_pos,
|
||||||
|
click_tile,
|
||||||
|
)
|
||||||
|
.chain(),
|
||||||
);
|
);
|
||||||
app.add_systems(Update, update_tiles);
|
app.add_systems(Update, update_tiles);
|
||||||
}
|
}
|
||||||
@@ -131,7 +137,6 @@ fn generate_grid(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is where we check which tile the cursor is hovered over.
|
|
||||||
fn click_tile(
|
fn click_tile(
|
||||||
buttons: Res<ButtonInput<MouseButton>>,
|
buttons: Res<ButtonInput<MouseButton>>,
|
||||||
cursor_pos: Res<CursorPos>,
|
cursor_pos: Res<CursorPos>,
|
||||||
@@ -146,18 +151,13 @@ fn click_tile(
|
|||||||
let offset = offset.single();
|
let offset = offset.single();
|
||||||
|
|
||||||
for (map_size, grid_size, tile_storage, map_transform) in tilemap_q.iter() {
|
for (map_size, grid_size, tile_storage, map_transform) in tilemap_q.iter() {
|
||||||
// Grab the cursor position from the `Res<CursorPos>`
|
|
||||||
let cursor_pos: Vec2 = cursor_pos.0;
|
let cursor_pos: Vec2 = cursor_pos.0;
|
||||||
// We need to make sure that the cursor's world position is correct relative to the map
|
|
||||||
// due to any map transformation.
|
|
||||||
let cursor_in_map_pos: Vec2 = {
|
let cursor_in_map_pos: Vec2 = {
|
||||||
// Extend the cursor_pos vec3 by 0.0 and 1.0
|
|
||||||
let cursor_pos = Vec4::from((cursor_pos, 0.0, 1.0));
|
let cursor_pos = Vec4::from((cursor_pos, 0.0, 1.0));
|
||||||
let cursor_in_map_pos = map_transform.compute_matrix().inverse() * cursor_pos;
|
let cursor_in_map_pos = map_transform.compute_matrix().inverse() * cursor_pos;
|
||||||
cursor_in_map_pos.xy()
|
cursor_in_map_pos.xy()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Once we have a world position we can transform it into a possible tile position.
|
|
||||||
let Some(tile_pos) = TilePos::from_world_pos(
|
let Some(tile_pos) = TilePos::from_world_pos(
|
||||||
&cursor_in_map_pos,
|
&cursor_in_map_pos,
|
||||||
map_size,
|
map_size,
|
||||||
|
Reference in New Issue
Block a user