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}