//! This example showcases a 2D top-down camera with smooth player tracking. //! //! ## Controls //! //! | Key Binding | Action | //! |:---------------------|:--------------| //! | `W` | Move up | //! | `S` | Move down | //! | `A` | Move left | //! | `D` | Move right | use bevy::{core_pipeline::bloom::Bloom, prelude::*}; /// Player movement speed factor. const PLAYER_SPEED: f32 = 100.; /// How quickly should the camera snap to the desired location. const CAMERA_DECAY_RATE: f32 = 2.; #[derive(Component)] struct Player; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, (setup_scene, setup_instructions, setup_camera)) .add_systems(Update, (move_player, update_camera).chain()) .run(); } fn setup_scene( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { // World where we move the player commands.spawn(( Mesh2d(meshes.add(Rectangle::new(1000., 700.))), MeshMaterial2d(materials.add(Color::srgb(0.2, 0.2, 0.3))), )); // Player commands.spawn(( Player, Mesh2d(meshes.add(Circle::new(25.))), MeshMaterial2d(materials.add(Color::srgb(6.25, 9.4, 9.1))), // RGB values exceed 1 to achieve a bright color for the bloom effect Transform::from_xyz(0., 0., 2.), )); } fn setup_instructions(mut commands: Commands) { commands.spawn( TextBundle::from_section( "Move the light with WASD.\nThe camera will smoothly track the light.", TextStyle::default(), ) .with_style(Style { position_type: PositionType::Absolute, bottom: Val::Px(12.0), left: Val::Px(12.0), ..default() }), ); } fn setup_camera(mut commands: Commands) { commands.spawn(( Camera2d, Camera { hdr: true, // HDR is required for the bloom effect ..default() }, Bloom::NATURAL, )); } /// Update the camera position by tracking the player. fn update_camera( mut camera: Query<&mut Transform, (With, Without)>, player: Query<&Transform, (With, Without)>, time: Res