2d_top_down_camera/
2d_top_down_camera.rs1use bevy::{post_process::bloom::Bloom, prelude::*};
13
14const PLAYER_SPEED: f32 = 100.;
16
17const CAMERA_DECAY_RATE: f32 = 2.;
19
20#[derive(Component)]
21struct Player;
22
23fn main() {
24 App::new()
25 .add_plugins(DefaultPlugins)
26 .add_systems(Startup, (setup_scene, setup_instructions, setup_camera))
27 .add_systems(Update, (move_player, update_camera).chain())
28 .run();
29}
30
31fn setup_scene(
32 mut commands: Commands,
33 mut meshes: ResMut<Assets<Mesh>>,
34 mut materials: ResMut<Assets<ColorMaterial>>,
35) {
36 commands.spawn((
38 Mesh2d(meshes.add(Rectangle::new(1000., 700.))),
39 MeshMaterial2d(materials.add(Color::srgb(0.2, 0.2, 0.3))),
40 ));
41
42 commands.spawn((
44 Player,
45 Mesh2d(meshes.add(Circle::new(25.))),
46 MeshMaterial2d(materials.add(Color::srgb(6.25, 9.4, 9.1))), Transform::from_xyz(0., 0., 2.),
48 ));
49}
50
51fn setup_instructions(mut commands: Commands) {
52 commands.spawn((
53 Text::new("Move the light with WASD.\nThe camera will smoothly track the light."),
54 Node {
55 position_type: PositionType::Absolute,
56 bottom: px(12),
57 left: px(12),
58 ..default()
59 },
60 ));
61}
62
63fn setup_camera(mut commands: Commands) {
64 commands.spawn((Camera2d, Bloom::NATURAL));
65}
66
67fn update_camera(
69 mut camera: Single<&mut Transform, (With<Camera2d>, Without<Player>)>,
70 player: Single<&Transform, (With<Player>, Without<Camera2d>)>,
71 time: Res<Time>,
72) {
73 let Vec3 { x, y, .. } = player.translation;
74 let direction = Vec3::new(x, y, camera.translation.z);
75
76 camera
79 .translation
80 .smooth_nudge(&direction, CAMERA_DECAY_RATE, time.delta_secs());
81}
82
83fn move_player(
89 mut player: Single<&mut Transform, With<Player>>,
90 time: Res<Time>,
91 kb_input: Res<ButtonInput<KeyCode>>,
92) {
93 let mut direction = Vec2::ZERO;
94
95 if kb_input.pressed(KeyCode::KeyW) {
96 direction.y += 1.;
97 }
98
99 if kb_input.pressed(KeyCode::KeyS) {
100 direction.y -= 1.;
101 }
102
103 if kb_input.pressed(KeyCode::KeyA) {
104 direction.x -= 1.;
105 }
106
107 if kb_input.pressed(KeyCode::KeyD) {
108 direction.x += 1.;
109 }
110
111 let move_delta = direction.normalize_or_zero() * PLAYER_SPEED * time.delta_secs();
115 player.translation += move_delta.extend(0.);
116}