Implement basic gun controller
All checks were successful
Basic checks / Basic build-and-test supertask (push) Successful in 7m3s
All checks were successful
Basic checks / Basic build-and-test supertask (push) Successful in 7m3s
The spacebar fires the gun, bullets are spawned on top of the ship with a velocity that sends them forward (relative to the ship). I still need a despawn mechanism, and a fire rate control. To despawn things, I'm already planning a `Lifetime` component. For rate of fire, an additional component will be created and attached to the player ship.
This commit is contained in:
@@ -10,9 +10,12 @@ pub(crate) const PLAYER_SHIP_COLOR: Color = Color::srgb(1.0, 1.0, 1.0);
|
|||||||
pub(crate) const SHIP_THRUSTER_COLOR_ACTIVE: Color = Color::srgb(1.0, 0.2, 0.2);
|
pub(crate) const SHIP_THRUSTER_COLOR_ACTIVE: Color = Color::srgb(1.0, 0.2, 0.2);
|
||||||
pub(crate) const SHIP_THRUSTER_COLOR_INACTIVE: Color = Color::srgb(0.5, 0.5, 0.5);
|
pub(crate) const SHIP_THRUSTER_COLOR_INACTIVE: Color = Color::srgb(0.5, 0.5, 0.5);
|
||||||
pub(crate) const ASTEROID_SMALL_COLOR: Color = Color::srgb(1.0, 0., 0.);
|
pub(crate) const ASTEROID_SMALL_COLOR: Color = Color::srgb(1.0, 0., 0.);
|
||||||
|
pub(crate) const BULLET_COLOR: Color = Color::srgb(0.0, 0.1, 0.9);
|
||||||
// TODO: asteroid medium & large
|
// TODO: asteroid medium & large
|
||||||
|
|
||||||
pub(crate) const SHIP_THRUST: f32 = 1.0;
|
pub(crate) const SHIP_THRUST: f32 = 1.0;
|
||||||
pub(crate) const SHIP_ROTATION: f32 = 4.0; // +/- rotation speed in... radians per frame
|
pub(crate) const SHIP_ROTATION: f32 = 4.0; // +/- rotation speed in... radians per frame
|
||||||
|
|
||||||
|
pub(crate) const BULLET_SPEED: f32 = 150.0;
|
||||||
|
|
||||||
pub const RNG_SEED: [u8; 32] = *b"12345678909876543210123456789098";
|
pub const RNG_SEED: [u8; 32] = *b"12345678909876543210123456789098";
|
||||||
|
|||||||
@@ -12,3 +12,10 @@ pub(crate) struct AsteroidDestroy(pub Entity);
|
|||||||
|
|
||||||
// TODO: BulletDestroy
|
// TODO: BulletDestroy
|
||||||
// Which depends on the still-pending Bullet component creation.
|
// Which depends on the still-pending Bullet component creation.
|
||||||
|
|
||||||
|
/// Signals that a particular bullet has been destroyed.
|
||||||
|
/// Used to despawn the bullet after it strikes an Asteroid.
|
||||||
|
///
|
||||||
|
/// TODO: Maybe use it for lifetime expiration (which is also a TODO item).
|
||||||
|
#[derive(Event)]
|
||||||
|
pub(crate) struct BulletDestroy(pub Entity);
|
||||||
|
|||||||
45
src/lib.rs
45
src/lib.rs
@@ -8,8 +8,9 @@ mod title_screen;
|
|||||||
|
|
||||||
use crate::asteroids::{Asteroid, AsteroidSpawner};
|
use crate::asteroids::{Asteroid, AsteroidSpawner};
|
||||||
use crate::config::{
|
use crate::config::{
|
||||||
ASTEROID_SMALL_COLOR, BACKGROUND_COLOR, PLAYER_SHIP_COLOR, SHIP_ROTATION, SHIP_THRUST,
|
ASTEROID_SMALL_COLOR, BACKGROUND_COLOR, BULLET_COLOR, BULLET_SPEED, PLAYER_SHIP_COLOR,
|
||||||
SHIP_THRUSTER_COLOR_ACTIVE, SHIP_THRUSTER_COLOR_INACTIVE, WINDOW_SIZE,
|
SHIP_ROTATION, SHIP_THRUST, SHIP_THRUSTER_COLOR_ACTIVE, SHIP_THRUSTER_COLOR_INACTIVE,
|
||||||
|
WINDOW_SIZE,
|
||||||
};
|
};
|
||||||
use crate::physics::AngularVelocity;
|
use crate::physics::AngularVelocity;
|
||||||
use crate::ship::Ship;
|
use crate::ship::Ship;
|
||||||
@@ -50,6 +51,7 @@ impl Plugin for AsteroidPlugin {
|
|||||||
(
|
(
|
||||||
input_ship_thruster,
|
input_ship_thruster,
|
||||||
input_ship_rotation,
|
input_ship_rotation,
|
||||||
|
input_ship_shoot,
|
||||||
physics::wrap_entities,
|
physics::wrap_entities,
|
||||||
asteroids::tick_asteroid_manager,
|
asteroids::tick_asteroid_manager,
|
||||||
asteroids::spawn_asteroid.after(asteroids::tick_asteroid_manager),
|
asteroids::spawn_asteroid.after(asteroids::tick_asteroid_manager),
|
||||||
@@ -163,8 +165,8 @@ struct WorldSize {
|
|||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct GameAssets {
|
struct GameAssets {
|
||||||
meshes: [Handle<Mesh>; 4],
|
meshes: [Handle<Mesh>; 5],
|
||||||
materials: [Handle<ColorMaterial>; 6],
|
materials: [Handle<ColorMaterial>; 7],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameAssets {
|
impl GameAssets {
|
||||||
@@ -199,6 +201,10 @@ impl GameAssets {
|
|||||||
fn asteroid_large(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
fn asteroid_large(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
||||||
(self.meshes[3].clone(), self.materials[3].clone())
|
(self.meshes[3].clone(), self.materials[3].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bullet(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
||||||
|
(self.meshes[4].clone(), self.materials[6].clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWorld for GameAssets {
|
impl FromWorld for GameAssets {
|
||||||
@@ -213,6 +219,7 @@ impl FromWorld for GameAssets {
|
|||||||
world_meshes.add(Circle::new(10.0)),
|
world_meshes.add(Circle::new(10.0)),
|
||||||
world_meshes.add(Circle::new(20.0)),
|
world_meshes.add(Circle::new(20.0)),
|
||||||
world_meshes.add(Circle::new(40.0)),
|
world_meshes.add(Circle::new(40.0)),
|
||||||
|
world_meshes.add(Circle::new(0.2)),
|
||||||
];
|
];
|
||||||
let mut world_materials = world.resource_mut::<Assets<ColorMaterial>>();
|
let mut world_materials = world.resource_mut::<Assets<ColorMaterial>>();
|
||||||
let materials = [
|
let materials = [
|
||||||
@@ -223,6 +230,7 @@ impl FromWorld for GameAssets {
|
|||||||
// TODO: asteroid medium and large colors
|
// TODO: asteroid medium and large colors
|
||||||
world_materials.add(ASTEROID_SMALL_COLOR),
|
world_materials.add(ASTEROID_SMALL_COLOR),
|
||||||
world_materials.add(ASTEROID_SMALL_COLOR),
|
world_materials.add(ASTEROID_SMALL_COLOR),
|
||||||
|
world_materials.add(BULLET_COLOR),
|
||||||
];
|
];
|
||||||
GameAssets { meshes, materials }
|
GameAssets { meshes, materials }
|
||||||
}
|
}
|
||||||
@@ -287,6 +295,35 @@ fn input_ship_rotation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn input_ship_shoot(
|
||||||
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
ship: Single<(&Transform, &physics::Velocity), With<Ship>>,
|
||||||
|
game_assets: Res<GameAssets>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
let (ship_pos, ship_vel) = *ship;
|
||||||
|
|
||||||
|
// Derive bullet velocity, add to the ship's velocity
|
||||||
|
let bullet_vel = (ship_pos.rotation * Vec3::X).xy() * BULLET_SPEED;
|
||||||
|
let bullet_vel = bullet_vel + ship_vel.0;
|
||||||
|
|
||||||
|
// TODO: create a timer for the gun fire rate.
|
||||||
|
// For now, spawn one for each press of the spacebar.
|
||||||
|
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||||
|
commands.spawn((
|
||||||
|
ship::Bullet,
|
||||||
|
Collider::ball(0.2),
|
||||||
|
Sensor,
|
||||||
|
ActiveEvents::COLLISION_EVENTS,
|
||||||
|
ActiveCollisionTypes::STATIC_STATIC,
|
||||||
|
physics::Velocity(bullet_vel),
|
||||||
|
Mesh2d(game_assets.bullet().0),
|
||||||
|
MeshMaterial2d(game_assets.bullet().1),
|
||||||
|
ship_pos.clone(), // clone ship transform
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn spawn_ui(mut commands: Commands, score: Res<Score>, lives: Res<Lives>) {
|
fn spawn_ui(mut commands: Commands, score: Res<Score>, lives: Res<Lives>) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Text::new(format!("Score: {score:?} | Lives: {lives:?}")),
|
Text::new(format!("Score: {score:?} | Lives: {lives:?}")),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::WorldSize;
|
|||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Clone, Component)]
|
||||||
pub(crate) struct Velocity(pub(crate) bevy::math::Vec2);
|
pub(crate) struct Velocity(pub(crate) bevy::math::Vec2);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ use bevy_rapier2d::prelude::*;
|
|||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Ship;
|
pub struct Ship;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Bullet;
|
||||||
|
|
||||||
pub fn spawn_player(mut commands: Commands, game_assets: Res<GameAssets>) {
|
pub fn spawn_player(mut commands: Commands, game_assets: Res<GameAssets>) {
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
|
|||||||
Reference in New Issue
Block a user