Minor reorganization

master
Mark 2023-12-29 15:14:04 -08:00
parent c6f22557f2
commit da1b38cd33
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
22 changed files with 156 additions and 107 deletions

12
Cargo.lock generated
View File

@ -573,6 +573,17 @@ version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
[[package]]
name = "galactica-content"
version = "0.0.0"
dependencies = [
"anyhow",
"cgmath",
"serde",
"toml",
"walkdir",
]
[[package]]
name = "game"
version = "0.1.0"
@ -581,6 +592,7 @@ dependencies = [
"bytemuck",
"cgmath",
"crossbeam",
"galactica-content",
"image",
"nalgebra",
"pollster",

View File

@ -26,7 +26,15 @@ panic = "abort"
incremental = false
rpath = false
[workspace]
members = ["crates/content"]
[dependencies]
# Internal crates
galactica-content = { path = "crates/content" }
# Files
image = { version = "0.24", features = ["png"] }
toml = "0.8.8"
@ -35,12 +43,13 @@ serde = { version = "1.0.193", features = ["derive"] }
winit = "0.28"
wgpu = "0.18"
bytemuck = { version = "1.12", features = ["derive"] }
# Physics
rapier2d = "0.17.2"
nalgebra = "0.32.3"
crossbeam = "0.8.3"
# Misc helpers
pollster = "0.3"
anyhow = "1.0"
cgmath = "0.18.0"
rand = "0.8.5"
walkdir = "2.4.0"
rapier2d = "0.17.2"
nalgebra = "0.32.3"
crossbeam = "0.8.3"

11
crates/content/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "galactica-content"
version = "0.0.0"
edition = "2021"
[dependencies]
toml = "0.8.8"
serde = { version = "1.0.193", features = ["derive"] }
anyhow = "1.0"
cgmath = "0.18.0"
walkdir = "2.4.0"

View File

@ -1,8 +1,8 @@
#![allow(dead_code)]
mod engine;
mod gun;
mod ship;
mod system;
mod util;
pub use engine::Engine;
pub use gun::{Gun, Projectile};

View File

@ -1,14 +1,15 @@
use cgmath::Point2;
use std::time::Instant;
use winit::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode};
use super::{
camera::Camera,
system::System,
util,
world::{ShipGun, ShipHandle, ShipOutfit, World},
InputStatus,
use super::{camera::Camera, outfits, system::System, util};
use crate::{
consts,
content::Content,
inputstatus::InputStatus,
physics::{Physics, ShipHandle},
render::Sprite,
};
use crate::{consts, content::Content, render::Sprite};
pub struct Game {
pub input: InputStatus,
@ -19,23 +20,32 @@ pub struct Game {
paused: bool,
pub time_scale: f32,
world: World,
world: Physics,
}
impl Game {
pub fn new(ct: Content) -> Self {
let mut world = World::new();
let mut world = Physics::new();
let c = world.add_ship(
&ct.ships[0],
vec![
ShipOutfit::Gun(ShipGun::new(ct.guns[0].clone(), 1)),
ShipOutfit::Gun(ShipGun::new(ct.guns[0].clone(), 2)),
ShipOutfit::Engine(ct.engines[0].clone()),
outfits::ShipOutfit::Gun(outfits::ShipGun::new(ct.guns[0].clone(), 1)),
outfits::ShipOutfit::Gun(outfits::ShipGun::new(ct.guns[0].clone(), 2)),
outfits::ShipOutfit::Engine(ct.engines[0].clone()),
],
Point2 { x: 0.0, y: 0.0 },
);
world.add_ship(&ct.ships[0], vec![]);
world.add_ship(&ct.ships[0], vec![], Point2 { x: 300.0, y: 300.0 });
world.add_ship(
&ct.ships[0],
vec![],
Point2 {
x: -300.0,
y: 300.0,
},
);
Game {
last_update: Instant::now(),

View File

@ -1,11 +1,10 @@
mod camera;
mod game;
mod inputstatus;
pub mod objects;
pub mod outfits;
mod system;
mod systemobject;
mod util;
mod world;
pub use game::Game;
pub use inputstatus::InputStatus;
pub use systemobject::SystemObject;

5
src/game/objects/mod.rs Normal file
View File

@ -0,0 +1,5 @@
mod projectile;
mod ship;
pub use projectile::{Projectile, ProjectileBuilder};
pub use ship::Ship;

View File

@ -6,16 +6,39 @@ use rapier2d::geometry::ColliderBuilder;
use rapier2d::pipeline::ActiveEvents;
use super::ProjectileBuilder;
use super::{outfits::ShipOutfits, InputStatus, ShipControls, ShipOutfit, ShipTickResult};
use crate::game::{util, world::ShipHandle};
use crate::{
content,
game::{outfits, util},
inputstatus::InputStatus,
physics::ShipHandle,
render::{Sprite, SpriteTexture},
};
pub struct ShipControls {
pub left: bool,
pub right: bool,
pub thrust: bool,
pub guns: bool,
}
impl ShipControls {
pub fn new() -> Self {
ShipControls {
left: false,
right: false,
thrust: false,
guns: false,
}
}
}
pub struct ShipTickResult {
pub projectiles: Vec<ProjectileBuilder>,
}
pub struct Ship {
pub physics_handle: ShipHandle,
outfits: ShipOutfits,
outfits: outfits::ShipOutfits,
sprite: SpriteTexture,
size: f32,
@ -26,8 +49,12 @@ pub struct Ship {
}
impl Ship {
pub fn new(c: &content::Ship, outfits: Vec<ShipOutfit>, physics_handle: ShipHandle) -> Self {
let mut o = ShipOutfits::new(c);
pub fn new(
c: &content::Ship,
outfits: Vec<outfits::ShipOutfit>,
physics_handle: ShipHandle,
) -> Self {
let mut o = outfits::ShipOutfits::new(c);
for x in outfits.into_iter() {
o.add(x)
}

View File

@ -1,13 +0,0 @@
mod physicswrapper;
mod projectile;
mod ship;
mod world;
pub use projectile::{Projectile, ProjectileBuilder};
pub use ship::{Ship, ShipControls, ShipGun, ShipOutfit, ShipOutfits, ShipTickResult};
pub use world::World;
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
#[derive(Debug, Copy, Clone)]
pub struct ShipHandle(pub(in super::super) RigidBodyHandle, ColliderHandle);

View File

@ -1,29 +0,0 @@
mod outfits;
mod ship;
pub use outfits::{ShipGun, ShipOutfit, ShipOutfits};
pub use ship::Ship;
use super::{super::InputStatus, ProjectileBuilder};
pub struct ShipControls {
pub left: bool,
pub right: bool,
pub thrust: bool,
pub guns: bool,
}
impl ShipControls {
pub fn new() -> Self {
ShipControls {
left: false,
right: false,
thrust: false,
guns: false,
}
}
}
pub struct ShipTickResult {
pub projectiles: Vec<ProjectileBuilder>,
}

View File

@ -1,10 +1,11 @@
mod consts;
mod content;
mod game;
mod inputstatus;
mod physics;
mod render;
mod util;
use anyhow::Result;
use galactica_content as content;
use winit::{
event::{Event, KeyboardInput, WindowEvent},
event_loop::{ControlFlow, EventLoop},

9
src/physics/mod.rs Normal file
View File

@ -0,0 +1,9 @@
mod physics;
mod wrapper;
pub use physics::Physics;
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
#[derive(Debug, Copy, Clone)]
pub struct ShipHandle(pub(super) RigidBodyHandle, ColliderHandle);

View File

@ -1,3 +1,4 @@
use cgmath::Point2;
use crossbeam::channel::Receiver;
use nalgebra::vector;
use rapier2d::{
@ -7,57 +8,59 @@ use rapier2d::{
};
use std::collections::HashMap;
use super::{
physicswrapper::PhysicsWrapper, Projectile, ProjectileBuilder, Ship, ShipHandle, ShipOutfit,
use super::{wrapper::Wrapper, ShipHandle};
use crate::{
content,
game::{objects, outfits},
render::Sprite,
};
use crate::{content, render::Sprite};
/// Keeps track of all objects in the world that we can interact with.
/// Also wraps our physics engine
pub struct World {
physics: PhysicsWrapper,
projectiles: HashMap<ColliderHandle, Projectile>,
ships: HashMap<ColliderHandle, Ship>,
pub struct Physics {
wrapper: Wrapper,
projectiles: HashMap<ColliderHandle, objects::Projectile>,
ships: HashMap<ColliderHandle, objects::Ship>,
collision_handler: ChannelEventCollector,
collision_queue: Receiver<CollisionEvent>,
}
// Private methods
impl World {
impl Physics {
fn remove_projectile(&mut self, c: ColliderHandle) {
let p = match self.projectiles.remove(&c) {
Some(p) => p,
None => return,
};
self.physics.rigid_body_set.remove(
self.wrapper.rigid_body_set.remove(
p.rigid_body,
&mut self.physics.im,
&mut self.physics.collider_set,
&mut self.physics.ij,
&mut self.physics.mj,
&mut self.wrapper.im,
&mut self.wrapper.collider_set,
&mut self.wrapper.ij,
&mut self.wrapper.mj,
true,
);
}
fn remove_ship(&mut self, h: ShipHandle) {
self.physics.rigid_body_set.remove(
self.wrapper.rigid_body_set.remove(
h.0,
&mut self.physics.im,
&mut self.physics.collider_set,
&mut self.physics.ij,
&mut self.physics.mj,
&mut self.wrapper.im,
&mut self.wrapper.collider_set,
&mut self.wrapper.ij,
&mut self.wrapper.mj,
true,
);
self.ships.remove(&h.1);
}
fn add_projectile(&mut self, pb: ProjectileBuilder) -> ColliderHandle {
let r = self.physics.rigid_body_set.insert(pb.rigid_body.build());
let c = self.physics.collider_set.insert_with_parent(
fn add_projectile(&mut self, pb: objects::ProjectileBuilder) -> ColliderHandle {
let r = self.wrapper.rigid_body_set.insert(pb.rigid_body.build());
let c = self.wrapper.collider_set.insert_with_parent(
pb.collider.build(),
r,
&mut self.physics.rigid_body_set,
&mut self.wrapper.rigid_body_set,
);
self.projectiles.insert(c, pb.build(r, c));
return c;
@ -65,13 +68,13 @@ impl World {
}
// Public methods
impl World {
impl Physics {
pub fn new() -> Self {
let (collision_send, collision_queue) = crossbeam::channel::unbounded();
let (contact_force_send, _) = crossbeam::channel::unbounded();
Self {
physics: PhysicsWrapper::new(),
wrapper: Wrapper::new(),
projectiles: HashMap::new(),
ships: HashMap::new(),
collision_handler: ChannelEventCollector::new(collision_send, contact_force_send),
@ -79,21 +82,26 @@ impl World {
}
}
pub fn add_ship(&mut self, ct: &content::Ship, outfits: Vec<ShipOutfit>) -> ShipHandle {
pub fn add_ship(
&mut self,
ct: &content::Ship,
outfits: Vec<outfits::ShipOutfit>,
position: Point2<f32>,
) -> ShipHandle {
let rb = RigidBodyBuilder::dynamic()
.translation(vector![0.0, 0.0])
.translation(vector![position.x, position.y])
.can_sleep(false);
let cl = ColliderBuilder::ball(50.0).restitution(0.7).mass(1.0);
let r = self.physics.rigid_body_set.insert(rb.build());
let c = self.physics.collider_set.insert_with_parent(
let r = self.wrapper.rigid_body_set.insert(rb.build());
let c = self.wrapper.collider_set.insert_with_parent(
cl.build(),
r,
&mut self.physics.rigid_body_set,
&mut self.wrapper.rigid_body_set,
);
let h = ShipHandle(r, c);
self.ships.insert(c, Ship::new(ct, outfits, h));
self.ships.insert(c, objects::Ship::new(ct, outfits, h));
return h;
}
@ -106,7 +114,7 @@ impl World {
to_remove.push(s.physics_handle);
continue;
}
let r = &mut self.physics.rigid_body_set[s.physics_handle.0];
let r = &mut self.wrapper.rigid_body_set[s.physics_handle.0];
res.push(s.tick(r, t));
}
for r in to_remove {
@ -119,7 +127,7 @@ impl World {
}
// Update physics
self.physics.step(t, &self.collision_handler);
self.wrapper.step(t, &self.collision_handler);
// Handle collision events
while let Ok(event) = &self.collision_queue.try_recv() {
@ -159,22 +167,22 @@ impl World {
}
pub fn get_rigid_body(&self, r: RigidBodyHandle) -> &RigidBody {
&self.physics.rigid_body_set[r]
&self.wrapper.rigid_body_set[r]
}
pub fn get_ship_mut(&mut self, s: &ShipHandle) -> &mut Ship {
pub fn get_ship_mut(&mut self, s: &ShipHandle) -> &mut objects::Ship {
self.ships.get_mut(&s.1).unwrap()
}
pub fn get_ship_sprites(&self) -> impl Iterator<Item = Sprite> + '_ {
self.ships
.values()
.map(|x| x.get_sprite(&self.physics.rigid_body_set[x.physics_handle.0]))
.map(|x| x.get_sprite(&self.wrapper.rigid_body_set[x.physics_handle.0]))
}
pub fn get_projectile_sprites(&self) -> impl Iterator<Item = Sprite> + '_ {
self.projectiles
.values()
.map(|x| x.get_sprite(&self.physics.rigid_body_set[x.rigid_body]))
.map(|x| x.get_sprite(&self.wrapper.rigid_body_set[x.rigid_body]))
}
}

View File

@ -8,7 +8,7 @@ use rapier2d::{
pipeline::{EventHandler, PhysicsPipeline},
};
pub(super) struct PhysicsWrapper {
pub(super) struct Wrapper {
pub rigid_body_set: RigidBodySet,
pub collider_set: ColliderSet,
@ -22,7 +22,7 @@ pub(super) struct PhysicsWrapper {
pub ccd: CCDSolver,
}
impl PhysicsWrapper {
impl Wrapper {
pub fn new() -> Self {
Self {
rigid_body_set: RigidBodySet::new(),