Compare commits

..

2 Commits

Author SHA1 Message Date
Mark a75ca14ead
More cleanup 2024-01-01 16:43:29 -08:00
Mark 2c953b95a3
Minor cleanup 2024-01-01 16:38:12 -08:00
12 changed files with 101 additions and 84 deletions

11
Cargo.lock generated
View File

@ -585,6 +585,7 @@ dependencies = [
"galactica-gameobject", "galactica-gameobject",
"galactica-render", "galactica-render",
"galactica-shipbehavior", "galactica-shipbehavior",
"galactica-ui",
"galactica-world", "galactica-world",
"image", "image",
"nalgebra", "nalgebra",
@ -650,6 +651,16 @@ dependencies = [
"galactica-world", "galactica-world",
] ]
[[package]]
name = "galactica-ui"
version = "0.0.0"
dependencies = [
"cgmath",
"galactica-content",
"galactica-render",
"galactica-world",
]
[[package]] [[package]]
name = "galactica-world" name = "galactica-world"
version = "0.0.0" version = "0.0.0"

View File

@ -35,6 +35,7 @@ members = [
"crates/world", "crates/world",
"crates/shipbehavior", "crates/shipbehavior",
"crates/gameobject", "crates/gameobject",
"crates/ui",
] ]
@ -46,6 +47,7 @@ galactica-constants = { path = "crates/constants" }
galactica-world = { path = "crates/world" } galactica-world = { path = "crates/world" }
galactica-shipbehavior = { path = "crates/shipbehavior" } galactica-shipbehavior = { path = "crates/shipbehavior" }
galactica-gameobject = { path = "crates/gameobject" } galactica-gameobject = { path = "crates/gameobject" }
galactica-ui = { path = "crates/ui" }
# Files # Files
image = { version = "0.24", features = ["png"] } image = { version = "0.24", features = ["png"] }

View File

@ -30,6 +30,11 @@ impl Ship {
} }
} }
/// Has this ship been destroyed?
pub fn is_destroyed(&self) -> bool {
self.hull <= 0.0
}
pub fn handle_projectile_collision(&mut self, ct: &content::Content, p: &Projectile) -> bool { pub fn handle_projectile_collision(&mut self, ct: &content::Content, p: &Projectile) -> bool {
let f = ct.get_faction(self.faction); let f = ct.get_faction(self.faction);
let r = f.relationships.get(&p.faction).unwrap(); let r = f.relationships.get(&p.faction).unwrap();

10
crates/ui/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "galactica-ui"
version = "0.0.0"
edition = "2021"
[dependencies]
galactica-content = { path = "../content" }
galactica-world = { path = "../world" }
galactica-render = { path = "../render" }
cgmath = "0.18.0"

3
crates/ui/src/lib.rs Normal file
View File

@ -0,0 +1,3 @@
mod radar;
pub use radar::build_radar;

51
crates/ui/src/radar.rs Normal file
View File

@ -0,0 +1,51 @@
use cgmath::{Deg, InnerSpace, Point2};
use galactica_content as content;
use galactica_render::{AnchoredUiPosition, UiSprite};
use galactica_world::{util, ShipPhysicsHandle, World};
pub fn build_radar(
player: &ShipPhysicsHandle,
physics: &World,
ct: &content::Content,
) -> Vec<UiSprite> {
let mut out = Vec::new();
let radar_range = 2000.0;
let radar_size = 300.0;
out.push(UiSprite {
texture: ct.get_texture_handle("ui::radar"),
pos: AnchoredUiPosition::NorthWest(Point2 { x: 10.0, y: -10.0 }),
dimensions: Point2 {
x: radar_size,
y: radar_size,
},
angle: Deg(0.0),
});
let (_, pr) = physics.get_ship_body(player).unwrap();
let pr = util::rigidbody_position(pr);
for (s, r) in physics.iter_ship_body() {
if s.physics_handle == *player {
continue;
}
let r = util::rigidbody_position(r);
let d = r - pr;
let m = d.magnitude() / radar_range;
if m < 0.8 {
out.push(UiSprite {
texture: ct.get_texture_handle("ui::blip"),
pos: AnchoredUiPosition::NorthWest(
Point2 {
x: radar_size / 2.0 + 10.0,
y: radar_size / -2.0 - 10.0,
} + (d / radar_range * 150.0),
),
dimensions: Point2 { x: 1.0, y: 1.0 } * 5.0f32.min((0.8 - m) * 50.0),
angle: Deg(0.0),
});
}
}
return out;
}

View File

@ -49,8 +49,8 @@ impl ShipWorldObject {
} }
} }
/// Apply the effects of all active controls /// Step this ship's state by t seconds
pub fn tick(&mut self, r: &mut RigidBody, t: f32) { pub fn step(&mut self, r: &mut RigidBody, t: f32) {
let ship_rot = util::rigidbody_rotation(r); let ship_rot = util::rigidbody_rotation(r);
let engine_force = ship_rot * t; let engine_force = ship_rot * t;

View File

@ -133,7 +133,6 @@ impl<'a> World {
} }
/// Add a ship to this physics system /// Add a ship to this physics system
/// TODO: decouple from Ship::new()
pub fn add_ship( pub fn add_ship(
&mut self, &mut self,
ct: &content::Content, ct: &content::Content,
@ -149,6 +148,7 @@ impl<'a> World {
// (Collider starts pointing east, sprite starts pointing north.) // (Collider starts pointing east, sprite starts pointing north.)
.rotation(PI / -2.0) .rotation(PI / -2.0)
.mass(ship_content.mass); .mass(ship_content.mass);
// TODO: only build colliders once
let rb = RigidBodyBuilder::dynamic() let rb = RigidBodyBuilder::dynamic()
.angular_damping(ship_content.angular_drag) .angular_damping(ship_content.angular_drag)
@ -171,26 +171,25 @@ impl<'a> World {
/// Step this physics system by `t` seconds /// Step this physics system by `t` seconds
pub fn step(&mut self, t: f32, ct: &content::Content) { pub fn step(&mut self, t: f32, ct: &content::Content) {
// Run ship updates // Run ship updates
// TODO: Clean this mess // TODO: maybe reorganize projectile creation?
let mut ps = Vec::new(); let mut projectiles = Vec::new();
let mut to_remove = Vec::new(); let mut to_remove = Vec::new();
for (_, s) in &mut self.ships { for (_, s) in &mut self.ships {
if s.ship.hull <= 0.0 { if s.ship.is_destroyed() {
to_remove.push(s.physics_handle); to_remove.push(s.physics_handle);
continue; continue;
} }
let r = &mut self.wrapper.rigid_body_set[s.physics_handle.0]; let r = &mut self.wrapper.rigid_body_set[s.physics_handle.0];
s.tick(r, t); s.step(r, t);
if s.controls.guns { if s.controls.guns {
ps.push((s.physics_handle, s.ship.fire_guns())); projectiles.push((s.physics_handle, s.ship.fire_guns()));
} }
} }
for r in to_remove { let _ = projectiles
self.remove_ship(r); .into_iter()
} .map(|(s, p)| self.add_projectiles(&s, p));
for (s, p) in ps { let _ = to_remove.into_iter().map(|s| self.remove_ship(s));
self.add_projectiles(&s, p);
}
// Update physics // Update physics
self.wrapper.step(t, &self.collision_handler); self.wrapper.step(t, &self.collision_handler);

View File

@ -1,72 +1,17 @@
use cgmath::{Deg, InnerSpace, Point2}; use cgmath::Point2;
use content::SystemHandle; use content::SystemHandle;
use std::time::Instant; use std::time::Instant;
use winit::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode}; use winit::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode};
use super::camera::Camera; use crate::camera::Camera;
use crate::{content, inputstatus::InputStatus}; use crate::{content, inputstatus::InputStatus};
use galactica_constants; use galactica_constants;
use galactica_gameobject as object; use galactica_gameobject as object;
use galactica_render::{AnchoredUiPosition, ObjectSprite, UiSprite}; use galactica_render::{ObjectSprite, UiSprite};
use galactica_shipbehavior::{behavior, ShipBehavior}; use galactica_shipbehavior::{behavior, ShipBehavior};
use galactica_ui as ui;
use galactica_world::{util, ShipPhysicsHandle, World}; use galactica_world::{util, ShipPhysicsHandle, World};
struct Ui {}
impl Ui {
fn new() -> Self {
Self {}
}
fn build_radar(
&self,
player: &ShipPhysicsHandle,
physics: &World,
ct: &content::Content,
) -> Vec<UiSprite> {
let mut out = Vec::new();
let radar_range = 2000.0;
let radar_size = 300.0;
out.push(UiSprite {
texture: ct.get_texture_handle("ui::radar"),
pos: AnchoredUiPosition::NorthWest(Point2 { x: 10.0, y: -10.0 }),
dimensions: Point2 {
x: radar_size,
y: radar_size,
},
angle: Deg(0.0),
});
let (_, pr) = physics.get_ship_body(player).unwrap();
let pr = util::rigidbody_position(pr);
for (s, r) in physics.iter_ship_body() {
if s.physics_handle == *player {
continue;
}
let r = util::rigidbody_position(r);
let d = r - pr;
let m = d.magnitude() / radar_range;
if m < 0.8 {
out.push(UiSprite {
texture: ct.get_texture_handle("ui::blip"),
pos: AnchoredUiPosition::NorthWest(
Point2 {
x: radar_size / 2.0 + 10.0,
y: radar_size / -2.0 - 10.0,
} + (d / radar_range * 150.0),
),
dimensions: Point2 { x: 1.0, y: 1.0 } * 5.0f32.min((0.8 - m) * 50.0),
angle: Deg(0.0),
});
}
}
return out;
}
}
pub struct Game { pub struct Game {
pub input: InputStatus, pub input: InputStatus,
pub last_update: Instant, pub last_update: Instant,
@ -76,7 +21,6 @@ pub struct Game {
paused: bool, paused: bool,
pub time_scale: f32, pub time_scale: f32,
ui: Ui,
physics: World, physics: World,
shipbehaviors: Vec<Box<dyn ShipBehavior>>, shipbehaviors: Vec<Box<dyn ShipBehavior>>,
playerbehavior: behavior::Player, playerbehavior: behavior::Player,
@ -151,7 +95,6 @@ impl Game {
shipbehaviors, shipbehaviors,
content: ct, content: ct,
playerbehavior: behavior::Player::new(h1), playerbehavior: behavior::Player::new(h1),
ui: Ui::new(),
} }
} }
@ -236,8 +179,6 @@ impl Game {
} }
pub fn get_ui_sprites(&self) -> Vec<UiSprite> { pub fn get_ui_sprites(&self) -> Vec<UiSprite> {
return self return ui::build_radar(&self.player, &self.physics, &self.content);
.ui
.build_radar(&self.player, &self.physics, &self.content);
} }
} }

View File

@ -1,6 +0,0 @@
//! This module is responsible for high-level game control logic.
mod camera;
mod game;
pub use game::Game;

View File

@ -1,3 +1,4 @@
mod camera;
mod game; mod game;
mod inputstatus; mod inputstatus;