use bevy::{ prelude::*, render::{camera::Camera, render_graph::base::camera::CAMERA_2D}, }; #[derive(Default, Debug)] struct Player { entity: Option, x: isize, y: isize, } #[derive(Default)] struct GameState { player: Player, score: u32, camera_focus: Vec3, } fn main() { App::build() .init_resource::() .add_plugins(DefaultPlugins) .add_startup_system(setup.system()) .add_system(movement.system()) .add_system(focus_camera.system()) .run(); } fn setup( mut commands: Commands, mut state: ResMut, mut materials: ResMut>, ) { state.score = 0; // assuming that bounds are (900, 600) state.player.x = 0; state.player.y = -50; // cameras commands.spawn_bundle(OrthographicCameraBundle::new_2d()); commands.spawn_bundle(UiCameraBundle::default()); // create the player state.player.entity = Some( commands .spawn_bundle(SpriteBundle { material: materials.add(Color::GOLD.into()), transform: Transform::from_xyz(0.0, -50.0, 1.0), sprite: Sprite::new(Vec2::new(30.0, 30.0)), ..Default::default() }) .id(), ); // Add walls! let wall_thickness = 10.0; let bounds = Vec2::new(900.0, 600.0); // left commands.spawn_bundle(SpriteBundle { transform: Transform::from_xyz(-bounds.x / 2.0, 0.0, 0.0), sprite: Sprite::new(Vec2::new(wall_thickness, bounds.y + wall_thickness)), ..Default::default() }); // right commands.spawn_bundle(SpriteBundle { transform: Transform::from_xyz(bounds.x / 2.0, 0.0, 0.0), sprite: Sprite::new(Vec2::new(wall_thickness, bounds.y + wall_thickness)), ..Default::default() }); // bottom commands.spawn_bundle(SpriteBundle { transform: Transform::from_xyz(0.0, -bounds.y / 2.0, 0.0), sprite: Sprite::new(Vec2::new(bounds.x + wall_thickness, wall_thickness)), ..Default::default() }); commands.spawn_bundle(SpriteBundle { transform: Transform::from_xyz(0.0, bounds.y / 2.0, 0.0), sprite: Sprite::new(Vec2::new(bounds.x + wall_thickness, wall_thickness)), ..Default::default() }); } fn movement( keyboard_input: Res>, mut query: Query<&mut Transform>, mut game: ResMut, ) { let mut moved = false; if keyboard_input.pressed(KeyCode::Left) { game.player.x -= 5; moved = true; } if keyboard_input.pressed(KeyCode::Right) { game.player.x += 5; moved = true; } if keyboard_input.pressed(KeyCode::Up) { game.player.y += 5; moved = true; } if keyboard_input.pressed(KeyCode::Down) { game.player.y -= 5; moved = true; } // limit movement of player game.player.x = game.player.x.min(435).max(-435); game.player.y = game.player.y.min(285).max(-285); if moved { if let Some(entity) = game.player.entity { *query.get_mut(entity).unwrap() = Transform { translation: Vec3::new(game.player.x as f32, game.player.y as f32, 0.0), ..Default::default() }; } } } fn focus_camera( mut game: ResMut, mut transforms: QuerySet<(Query<(&mut Transform, &Camera)>, Query<&Transform>)>, ) { if let Some(player_entity) = game.player.entity { if let Ok(player_transform) = transforms.q1().get(player_entity) { game.camera_focus = player_transform.translation; } } for (mut transform, camera) in transforms.q0_mut().iter_mut() { if camera.name == Some(CAMERA_2D.to_string()) { *transform.translation = *game.camera_focus; } } }