mod config; use crate::config::{BACKGROUND_COLOR, PLAYER_SHIP_COLOR, SHIP_THRUST, SHIP_ROTATION}; use bevy::{prelude::*, sprite::MaterialMesh2dBundle}; pub struct AsteroidPlugin; impl Plugin for AsteroidPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, (spawn_camera, spawn_player)) .insert_resource(ClearColor(BACKGROUND_COLOR)) .add_systems(FixedUpdate, (input_ship_thruster, input_ship_rotation)) .add_systems(FixedPostUpdate, ( integrate_velocity, update_positions, apply_rotation_to_mesh, )); } } #[derive(Component)] struct Position(bevy::math::Vec2); #[derive(Component)] struct Velocity(bevy::math::Vec2); #[derive(Component)] struct Rotation(f32); #[derive(Component)] struct Ship; fn spawn_camera(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); } fn spawn_player( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { commands.spawn(( Ship, Position(Vec2::default()), Velocity(Vec2::ZERO), Rotation(0.0), MaterialMesh2dBundle { mesh: meshes.add(Triangle2d::new( Vec2::new( 0.5, 0.0) * 20.0, Vec2::new(-0.5, 0.25) * 20.0, Vec2::new(-0.5, -0.25) * 20.0 )).into(), material: materials.add(PLAYER_SHIP_COLOR), transform: Transform::default(), ..default() }, )); } /* Checks if "W" is pressed and increases velocity accordingly. */ fn input_ship_thruster( keyboard_input: Res>, mut query: Query<(&mut Velocity, &Rotation), With>, ) { let Ok((mut velocity, rotation)) = query.get_single_mut() else { let count = query.iter().count(); panic!("There should be exactly one player ship! Instead, there seems to be {count}."); }; if keyboard_input.pressed(KeyCode::KeyW) { velocity.0 += Vec2::from_angle(rotation.0) * SHIP_THRUST; } } /* Checks if "A" or "D" is pressed and updates the player's Rotation component accordingly Does *not* rotate the graphical widget! (that's done by the `apply_rotation_to_mesh` system) */ fn input_ship_rotation( keyboard_input: Res>, mut query: Query<&mut Rotation, With>, ) { let Ok(mut rotation) = query.get_single_mut() else { let count = query.iter().count(); panic!("There should be exactly one player ship! Instead, there seems to be {count}."); }; if keyboard_input.pressed(KeyCode::KeyA) { rotation.0 += SHIP_ROTATION; } else if keyboard_input.pressed(KeyCode::KeyD) { rotation.0 -= SHIP_ROTATION; } } /* Add velocity to position */ fn integrate_velocity(mut query: Query<(&mut Position, &Velocity)>, time: Res