update project
Some checks failed
CI / Tests (push) Failing after 1m33s
CI / Clippy lints (push) Failing after 1m40s
CI / Bevy lints (push) Failing after 2m14s

This commit is contained in:
2026-03-01 16:23:42 -05:00
parent 634fd5430c
commit 0e8a071a36
8 changed files with 172 additions and 100 deletions

View File

@@ -8,7 +8,8 @@ use plugins::GamePlugin;
mod components;
mod resources;
const NAME: &str = "Space Game";
fn main() {
fn main()
{
App::new()
.add_plugins((
DefaultPlugins
@@ -17,7 +18,7 @@ fn main() {
title: NAME.into(),
name: Some(NAME.into()),
#[cfg(debug_assertions)]
resolution: (1920., 1080.).into(),
resolution: (1920, 1080).into(),
present_mode: PresentMode::AutoNoVsync,
#[cfg(not(debug_assertions))]
mode: bevy::window::WindowMode::BorderlessFullscreen,
@@ -30,9 +31,7 @@ fn main() {
watch_for_changes_override: Some(true),
..Default::default()
}),
EguiPlugin {
enable_multipass_for_primary_context: true,
},
EguiPlugin::default(),
WorldInspectorPlugin::new(),
GamePlugin,
))

View File

@@ -7,8 +7,10 @@ use crate::{components::camera::*, states::play::PlaySystems};
pub struct CameraPlugin;
impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
impl Plugin for CameraPlugin
{
fn build(&self, app: &mut App)
{
app.add_systems(Update, camera_pitch.in_set(PlaySystems));
app.add_systems(
PostUpdate,
@@ -23,12 +25,16 @@ impl Plugin for CameraPlugin {
pub fn camera_attachment(
attachment_targets: Query<&GlobalTransform>,
cam: Single<(&mut Transform, &CameraAttachment, &CameraMode)>,
) {
)
{
let (mut transform, attach, mode) = cam.into_inner();
if let Ok(tgt) = attachment_targets.get(attach.0) {
match mode {
CameraMode::Player => {
if let Ok(tgt) = attachment_targets.get(attach.0)
{
match mode
{
CameraMode::Player =>
{
transform.rotation = tgt.rotation();
transform.translation = tgt.translation();
}
@@ -38,8 +44,10 @@ pub fn camera_attachment(
}
}
pub fn camera_pitch(cam_query: Query<(&mut Transform, &CameraPitch)>) {
for (mut cam_transform, pitch) in cam_query {
pub fn camera_pitch(cam_query: Query<(&mut Transform, &CameraPitch)>)
{
for (mut cam_transform, pitch) in cam_query
{
cam_transform.rotation = Quat::from_rotation_x(pitch.0);
}
}
@@ -47,20 +55,25 @@ pub fn camera_pitch(cam_query: Query<(&mut Transform, &CameraPitch)>) {
#[cfg(feature = "dev")]
pub fn camera_toggle(
key: Res<ButtonInput<KeyCode>>,
mut window: Single<&mut Window, With<PrimaryWindow>>,
mut cursor_options: Single<&mut CursorOptions, With<PrimaryWindow>>,
camera: Single<&mut CameraMode>,
) {
)
{
use bevy::window::CursorGrabMode;
let mut mode = camera.into_inner();
if key.just_pressed(KeyCode::Escape) {
if window.cursor_options.visible {
if key.just_pressed(KeyCode::Escape)
{
if cursor_options.visible
{
*mode = CameraMode::Player;
window.cursor_options.grab_mode = CursorGrabMode::Locked;
window.cursor_options.visible = false;
} else {
cursor_options.grab_mode = CursorGrabMode::Locked;
cursor_options.visible = false;
}
else
{
*mode = CameraMode::Disabled;
window.cursor_options.grab_mode = CursorGrabMode::None;
window.cursor_options.visible = true;
cursor_options.grab_mode = CursorGrabMode::None;
cursor_options.visible = true;
}
}
}

View File

@@ -16,8 +16,10 @@ use bevy_rapier3d::prelude::*;
#[derive(Default)]
pub struct GamePlugin;
impl Plugin for GamePlugin {
fn build(&self, app: &mut bevy::app::App) {
impl Plugin for GamePlugin
{
fn build(&self, app: &mut bevy::app::App)
{
app.add_plugins((
FollowCamPlugin,
CameraPlugin,
@@ -40,8 +42,9 @@ fn setup_scene(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut window: Single<&mut Window, With<PrimaryWindow>>,
) {
mut window: Single<&mut CursorOptions, With<PrimaryWindow>>,
)
{
window.cursor_options.visible = false;
window.cursor_options.grab_mode = CursorGrabMode::Locked;
@@ -105,11 +108,8 @@ fn setup_scene(
}
#[allow(dead_code)]
fn spawn_ship(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
fn spawn_ship(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<StandardMaterial>>)
{
let window_material = materials.add(Color::linear_rgba(1.0, 0.0, 1.0, 0.5));
let material = materials.add(Color::BLACK);

View File

@@ -15,8 +15,10 @@ use crate::{
pub struct PlayerPlugin;
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut App) {
impl Plugin for PlayerPlugin
{
fn build(&self, app: &mut App)
{
app.add_systems(PreUpdate, (keyboard_input, player_look).in_set(InputWorldSystems));
app.add_systems(
Update,
@@ -28,7 +30,8 @@ impl Plugin for PlayerPlugin {
}
}
fn apply_forces(player: Single<(&mut PlayerVelocity, &PlayerForce), With<Player>>, time: Res<Time>) {
fn apply_forces(player: Single<(&mut PlayerVelocity, &PlayerForce), With<Player>>, time: Res<Time>)
{
let (mut vel, force) = player.into_inner();
vel.0 += force.0 * time.delta_secs();
@@ -45,23 +48,31 @@ fn apply_gravity(
With<Player>,
>,
time: Res<Time>,
) {
)
{
let (mut vel, dir, scale, output) = player.into_inner();
let Some(grav) = dir.0.map(|d| d.as_vec3()) else {
let Some(grav) = dir.0.map(|d| d.as_vec3())
else
{
return;
};
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
if !is_grounded {
if !is_grounded
{
vel.0 += grav * scale.0 * 9.47 * time.delta_secs();
} else {
}
else
{
let dot = vel.0.dot(grav);
if dot > f32::EPSILON {
if dot > f32::EPSILON
{
vel.0 -= dot * grav;
}
}
}
fn apply_drag(player: Single<(&mut PlayerVelocity, &PlayerDrag), With<Player>>, time: Res<Time>) {
fn apply_drag(player: Single<(&mut PlayerVelocity, &PlayerDrag), With<Player>>, time: Res<Time>)
{
let (mut vel, drag) = player.into_inner();
vel.0 *= (1.0 - drag.0 * time.delta_secs()).max(0.0);
}
@@ -77,7 +88,8 @@ fn apply_motion(
With<Player>,
>,
time: Res<Time>,
) {
)
{
let (mut controller, transform, vel, motion) = player.into_inner();
// let max_vel = vel.0.clamp_length_max(500.0);
let global_motion = transform.rotation * motion.0;
@@ -97,26 +109,34 @@ fn keyboard_input(
),
With<Player>,
>,
) {
)
{
let (mut motion, mut vel, speed, jump, transform, output) = player.into_inner();
let mut move_vec = Vec3::ZERO;
if key.pressed(KeyCode::KeyW) {
if key.pressed(KeyCode::KeyW)
{
move_vec.z = -1.0;
} else if key.pressed(KeyCode::KeyS) {
}
else if key.pressed(KeyCode::KeyS)
{
move_vec.z = 1.0;
}
if key.pressed(KeyCode::KeyA) {
if key.pressed(KeyCode::KeyA)
{
move_vec.x = -1.0;
} else if key.pressed(KeyCode::KeyD) {
}
else if key.pressed(KeyCode::KeyD)
{
move_vec.x = 1.0;
}
move_vec = move_vec.normalize_or_zero() * speed.0;
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
if key.just_pressed(KeyCode::Space) && is_grounded {
if key.just_pressed(KeyCode::Space) && is_grounded
{
vel.0 += transform.up() * jump.0;
}
@@ -131,9 +151,10 @@ fn keyboard_input(
fn player_look(
mut player: Single<&mut Transform, With<Player>>,
mut cam_pitch: Single<&mut CameraPitch>,
mouse_motion: EventReader<MouseMotion>,
mouse_motion: MessageReader<MouseMotion>,
time: Res<Time>,
) {
)
{
let delta = get_mouse_delta(mouse_motion) * -time.delta_secs();
let up = player.up();
player.rotate_axis(up, delta.x);
@@ -150,15 +171,19 @@ fn align_with_gravity(
With<Player>,
>,
time: Res<Time>,
) {
)
{
let (mut transform, grav, output) = player.into_inner();
let is_grounded = output.map(|o| o.grounded).unwrap_or(false);
if !is_grounded {
if !is_grounded
{
return;
}
let Some(grav_dir) = grav.0 else {
let Some(grav_dir) = grav.0
else
{
return;
};

View File

@@ -9,8 +9,10 @@ use crate::{
pub struct ShipPlugin;
impl Plugin for ShipPlugin {
fn build(&self, app: &mut App) {
impl Plugin for ShipPlugin
{
fn build(&self, app: &mut App)
{
app.add_systems(Update, spawn_ship.in_set(PlayStartupSystems));
app.add_systems(Update, ship_controls.in_set(PlaySystems));
@@ -22,7 +24,8 @@ impl Plugin for ShipPlugin {
#[derive(Resource, Debug, Reflect)]
struct ShipMesh(Handle<Scene>);
fn spawn_ship(mut commads: Commands, assets: Res<AssetServer>) {
fn spawn_ship(mut commads: Commands, assets: Res<AssetServer>)
{
let scene = assets.load(GltfAssetLabel::Scene(0).from_asset("models/Ship.glb"));
commads.insert_resource(ShipMesh(scene.clone()));
@@ -46,37 +49,50 @@ fn spawn_ship(mut commads: Commands, assets: Res<AssetServer>) {
}
fn ship_controls(
ship_query: Single<(&Transform, &mut Velocity, &mut Damping), With<Ship>>,
ship_query: Single<(&Transform, &mut Velocity), With<Ship>>,
key: Res<ButtonInput<KeyCode>>,
time: Res<Time>,
mouse_motion: EventReader<MouseMotion>,
) {
mouse_motion: MessageReader<MouseMotion>,
)
{
let (transform, mut vel, mut damp) = ship_query.into_inner();
let mut move_vec = Vec3::ZERO;
if key.pressed(KeyCode::KeyW) {
if key.pressed(KeyCode::KeyW)
{
move_vec.z = -1.0;
} else if key.pressed(KeyCode::KeyS) {
}
else if key.pressed(KeyCode::KeyS)
{
move_vec.z = 1.0;
}
if key.pressed(KeyCode::KeyA) {
if key.pressed(KeyCode::KeyA)
{
move_vec.x = -1.0;
} else if key.pressed(KeyCode::KeyD) {
}
else if key.pressed(KeyCode::KeyD)
{
move_vec.x = 1.0;
}
if key.pressed(KeyCode::Space) {
if key.pressed(KeyCode::Space)
{
move_vec.y = 1.0;
} else if key.pressed(KeyCode::ShiftLeft) {
}
else if key.pressed(KeyCode::ShiftLeft)
{
move_vec.y = -1.0;
}
if key.pressed(KeyCode::ControlLeft) {
if key.pressed(KeyCode::ControlLeft)
{
damp.linear_damping = 0.8;
damp.angular_damping = 0.8;
} else {
}
else
{
damp.linear_damping = 0.0;
damp.angular_damping = 0.0;
}
@@ -84,11 +100,16 @@ fn ship_controls(
const ROLL_SPEED: f32 = 1.0;
const DEAD_ZONE: f32 = 0.1;
const INPUT_CURVE: f32 = 3.0;
let yaw = if key.pressed(KeyCode::KeyQ) {
let yaw = if key.pressed(KeyCode::KeyQ)
{
Vec3::Y * ROLL_SPEED
} else if key.pressed(KeyCode::KeyE) {
}
else if key.pressed(KeyCode::KeyE)
{
Vec3::Y * -ROLL_SPEED
} else {
}
else
{
Vec3::ZERO
};
@@ -110,22 +131,33 @@ fn ship_controls(
}
#[cfg(feature = "dev-viz")]
fn ship_debug(mut gizmos: Gizmos, ship: Single<&Transform, With<Ship>>) {
fn ship_debug(mut gizmos: Gizmos, ship: Single<&Transform, With<Ship>>)
{
use std::ops::Range;
let base = ship.translation.floor();
const GRID: Range<i32> = -10..10;
for x in GRID {
for y in GRID {
for z in GRID {
for x in GRID
{
for y in GRID
{
for z in GRID
{
let p = base + Vec3::new(x as f32, y as f32, z as f32);
let color = if x == 0 && y == 0 {
let color = if x == 0 && y == 0
{
LinearRgba::BLUE
} else if x == 0 && z == 0 {
}
else if x == 0 && z == 0
{
LinearRgba::GREEN
} else if y == 0 && z == 0 {
}
else if y == 0 && z == 0
{
LinearRgba::RED
} else {
}
else
{
LinearRgba::gray(0.2).with_alpha(0.2)
};
gizmos.sphere(p, 0.01, color);

View File

@@ -1,8 +1,10 @@
use bevy::{input::mouse::MouseMotion, prelude::*};
pub fn get_mouse_delta(mut mouse_motion: EventReader<MouseMotion>) -> Vec2 {
pub fn get_mouse_delta(mut mouse_motion: MessageReader<MouseMotion>) -> Vec2
{
let mut delta = Vec2::ZERO;
for e in mouse_motion.read() {
for e in mouse_motion.read()
{
delta += e.delta;
}
return delta;