From b43a57e0d54048bd8eaa86eef26c2b8242a59b7c Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Tue, 26 Nov 2024 13:21:05 -0600 Subject: [PATCH] Dummy ship, single input, and motion integrator The ship, such as it is, exists and moves when the player presses "W". Position is updated according to velocity, and the mesh transform is updated to match the position. --- .gitignore | 1 + Cargo.toml | 7 ++++ src/config.rs | 12 +++++++ src/lib.rs | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 ++++++ 5 files changed, 124 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/config.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2922330 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "asteroids" +version = "0.1.0" +edition = "2021" + +[dependencies] +bevy = "0.14.2" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..8176131 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,12 @@ +/* + Global constants used all over the program. Rather than leaving them scattered +where ever they happen to be needed, I'm concentrating them here. +*/ + +use bevy::color::Color; + +pub(crate) const BACKGROUND_COLOR: Color = Color::srgb(0.3, 0.3, 0.3); +pub(crate) const PLAYER_SHIP_COLOR: Color = Color::srgb(1.0, 1.0, 1.0); + +pub(crate) const SHIP_THRUST_LIMIT: f32 = 10.0; +pub(crate) const SHIP_ROTATION_LIMIT: f32 = 5.0; // +/- rotation speed in... uunniittss diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..94d6735 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,94 @@ +mod config; + +use crate::config::{BACKGROUND_COLOR, PLAYER_SHIP_COLOR}; + +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) + // .add_systems(FixedUpdate, input_ship_rotation); + .add_systems(FixedPostUpdate, (integrate_velocity, update_positions)); + } +} + +#[derive(Component)] +struct Position(bevy::math::Vec2); + +#[derive(Component)] +struct Velocity(bevy::math::Vec2); + +#[derive(Component)] +struct Rotation(bevy::prelude::Quat); + +#[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), + MaterialMesh2dBundle { + mesh: meshes.add(Circle::new(10.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, With>, +) { + let Ok(mut velocity) = query.get_single_mut() else { + let count = query.iter().count(); + panic!("There should be exactly one player ship! Instead, there seem to be {count}."); + }; + + if keyboard_input.pressed(KeyCode::KeyW) { + velocity.0 += Vec2::new(10.0, 0.0); + } +} + +/* + Checks if "A" or "D" is pressed and rotates the ship accordingly +*/ +fn input_ship_rotation( + keyboard_input: Res>, + mut query: Query<&mut Rotation, With>, +) { + todo!(); +} + +/* + Add velocity to position +*/ +fn integrate_velocity(mut query: Query<(&mut Position, &Velocity)>, time: Res