Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added keyboard movement #63

Merged
merged 4 commits into from
Aug 19, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 94 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,23 @@ pub struct PanCamPlugin;
#[derive(Debug, Clone, Copy, SystemSet, PartialEq, Eq, Hash)]
pub struct PanCamSystemSet;

/// Which keys move the camera in particular directions for keyboard movement.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Reflect)]
pub struct DirectionKeys {
up: Vec<KeyCode>,
down: Vec<KeyCode>,
left: Vec<KeyCode>,
right: Vec<KeyCode>,
}
johanhelsing marked this conversation as resolved.
Show resolved Hide resolved

impl Plugin for PanCamPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(do_camera_movement, do_camera_zoom).in_set(PanCamSystemSet),
)
.register_type::<PanCam>();
.register_type::<PanCam>()
.register_type::<DirectionKeys>();

#[cfg(feature = "bevy_egui")]
{
Expand Down Expand Up @@ -179,8 +189,10 @@ fn clamp_to_safe_zone(pos: Vec2, aabb: Aabb2d, bounded_area_size: Vec2) -> Vec2
fn do_camera_movement(
primary_window: Query<&Window, With<PrimaryWindow>>,
mouse_buttons: Res<ButtonInput<MouseButton>>,
keyboard_buttons: Res<ButtonInput<KeyCode>>,
mut query: Query<(&PanCam, &mut Transform, &OrthographicProjection)>,
mut last_pos: Local<Option<Vec2>>,
time: Res<Time>,
) {
let Ok(window) = primary_window.get_single() else {
return;
Expand All @@ -196,21 +208,82 @@ fn do_camera_movement(
let delta_device_pixels = current_pos - last_pos.unwrap_or(current_pos);

for (cam, mut transform, projection) in &mut query {
if !cam.enabled
|| !cam
.grab_buttons
.iter()
.any(|btn| mouse_buttons.pressed(*btn) && !mouse_buttons.just_pressed(*btn))
{
if !cam.enabled {
continue;
}

let proj_area_size = projection.area.size();
let world_units_per_device_pixel = proj_area_size / window_size;

let mouse_delta = if !cam
.grab_buttons
.iter()
.any(|btn| mouse_buttons.pressed(*btn) && !mouse_buttons.just_pressed(*btn))
{
None
} else {
Some(delta_device_pixels * proj_area_size / window_size)
};

let mut direction = Vec2::ZERO;

if cam
.move_keys
.left
.iter()
.any(|key| keyboard_buttons.pressed(*key))
{
direction.x += 1.;
}

if cam
.move_keys
.right
.iter()
.any(|key| keyboard_buttons.pressed(*key))
johanhelsing marked this conversation as resolved.
Show resolved Hide resolved
{
direction.x -= 1.;
}

if cam
.move_keys
.up
.iter()
.any(|key| keyboard_buttons.pressed(*key))
{
direction.y -= 1.;
}

if cam
.move_keys
.down
.iter()
.any(|key| keyboard_buttons.pressed(*key))
{
direction.y += 1.;
}
Toniman575 marked this conversation as resolved.
Show resolved Hide resolved

let keyboard_delta = if direction.length_squared() == 0. {
Toniman575 marked this conversation as resolved.
Show resolved Hide resolved
None
} else {
Some(
time.delta_seconds() * direction.normalize_or_zero() * cam.speed * projection.scale,
)
};

if mouse_delta.is_none() && keyboard_delta.is_none() {
continue;
}

// The proposed new camera position
let delta_world = delta_device_pixels * world_units_per_device_pixel;
let proposed_cam_pos = transform.translation.truncate() - delta_world;
let mut proposed_cam_pos = transform.translation.truncate();

if let Some(mouse_delta) = mouse_delta {
proposed_cam_pos -= mouse_delta;
}

if let Some(keyboard_delta) = keyboard_delta {
proposed_cam_pos -= keyboard_delta;
}

transform.translation = clamp_to_safe_zone(proposed_cam_pos, cam.aabb(), proj_area_size)
.extend(transform.translation.z);
Expand All @@ -222,6 +295,10 @@ fn do_camera_movement(
#[derive(Component, Reflect)]
#[reflect(Component)]
pub struct PanCam {
/// The keyboard keys that will be used to move the camera
pub move_keys: DirectionKeys,
/// Speed for keyboard movement
johanhelsing marked this conversation as resolved.
Show resolved Hide resolved
pub speed: f32,
/// The mouse buttons that will be used to drag and pan the camera
pub grab_buttons: Vec<MouseButton>,
/// Whether camera currently responds to user input
Expand Down Expand Up @@ -296,6 +373,13 @@ impl PanCam {
impl Default for PanCam {
fn default() -> Self {
Self {
move_keys: DirectionKeys {
up: vec![KeyCode::ArrowUp, KeyCode::KeyW],
down: vec![KeyCode::ArrowDown, KeyCode::KeyS],
left: vec![KeyCode::ArrowLeft, KeyCode::KeyA],
right: vec![KeyCode::ArrowRight, KeyCode::KeyD],
},
speed: 200.,
grab_buttons: vec![MouseButton::Left, MouseButton::Right, MouseButton::Middle],
enabled: true,
zoom_to_cursor: true,
Expand Down
Loading