Skip to main content

traaains/game/
camera.rs

1use bevy::{
2    app::{Plugin, Startup, Update},
3    camera::{Camera, Camera2d, OrthographicProjection, Projection},
4    ecs::{
5        query::With,
6        system::{Commands, Query, Res, Single},
7    },
8    input::{ButtonInput, keyboard::KeyCode, mouse::AccumulatedMouseScroll},
9    input_focus::InputFocus,
10    math::Vec3,
11    time::Time,
12    transform::components::Transform,
13};
14
15const CAMERA_MOVE_SPEED: f32 = 256.0;
16const CAMERA_ZOOM_SPEED: f32 = 0.5;
17
18pub struct CameraPlugin;
19
20fn setup(mut cmd: Commands) {
21    let mut ortho = OrthographicProjection::default_2d();
22    ortho.scale = 0.5;
23
24    cmd.spawn((
25        Camera2d,
26        Projection::Orthographic(ortho),
27        Transform::from_translation(Vec3::new(0.0, 50.0, 0.0)),
28    ));
29}
30
31fn movement(
32    keyboard_input: Res<ButtonInput<KeyCode>>,
33    mut camera_transform: Query<&mut Transform, With<Camera2d>>,
34    time: Res<Time>,
35    input_focus: Res<InputFocus>,
36) {
37    if input_focus.get().is_some() {
38        return;
39    }
40
41    if keyboard_input.pressed(KeyCode::KeyW) {
42        for mut transform in &mut camera_transform {
43            transform.translation.y += time.delta_secs() * CAMERA_MOVE_SPEED;
44        }
45    }
46    if keyboard_input.pressed(KeyCode::KeyS) {
47        for mut transform in &mut camera_transform {
48            transform.translation.y -= time.delta_secs() * CAMERA_MOVE_SPEED;
49        }
50    }
51    if keyboard_input.pressed(KeyCode::KeyD) {
52        for mut transform in &mut camera_transform {
53            transform.translation.x += time.delta_secs() * CAMERA_MOVE_SPEED;
54        }
55    }
56    if keyboard_input.pressed(KeyCode::KeyA) {
57        for mut transform in &mut camera_transform {
58            transform.translation.x -= time.delta_secs() * CAMERA_MOVE_SPEED;
59        }
60    }
61}
62
63fn zoom(
64    mut camera: Single<&mut Projection, With<Camera>>,
65    mouse_wheel_input: Res<AccumulatedMouseScroll>,
66) {
67    if mouse_wheel_input.delta.y != 0.0 {
68        match &mut **camera {
69            Projection::Orthographic(op) => {
70                let delta = (-mouse_wheel_input.delta.y * CAMERA_ZOOM_SPEED).exp();
71                op.scale = (op.scale * delta).clamp(0.01, 5.0);
72            }
73            _ => unimplemented!(),
74        }
75    }
76}
77
78impl Plugin for CameraPlugin {
79    fn build(&self, app: &mut bevy::app::App) {
80        app.add_systems(Startup, setup)
81            .add_systems(Update, (movement, zoom));
82    }
83}