Compare commits
No commits in common. "54a1a26a2ca81a79797026645480e0c51dec9314" and "c6f22557f23db655e1a11b243a6a9dfd2da59ae6" have entirely different histories.
54a1a26a2c
...
c6f22557f2
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -573,17 +573,6 @@ version = "0.3.29"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "galactica-content"
|
|
||||||
version = "0.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"cgmath",
|
|
||||||
"serde",
|
|
||||||
"toml",
|
|
||||||
"walkdir",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "game"
|
name = "game"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -592,7 +581,6 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cgmath",
|
"cgmath",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"galactica-content",
|
|
||||||
"image",
|
"image",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
"pollster",
|
"pollster",
|
||||||
|
15
Cargo.toml
15
Cargo.toml
@ -26,15 +26,7 @@ panic = "abort"
|
|||||||
incremental = false
|
incremental = false
|
||||||
rpath = false
|
rpath = false
|
||||||
|
|
||||||
|
|
||||||
[workspace]
|
|
||||||
members = ["crates/content"]
|
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Internal crates
|
|
||||||
galactica-content = { path = "crates/content" }
|
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
image = { version = "0.24", features = ["png"] }
|
image = { version = "0.24", features = ["png"] }
|
||||||
toml = "0.8.8"
|
toml = "0.8.8"
|
||||||
@ -43,13 +35,12 @@ serde = { version = "1.0.193", features = ["derive"] }
|
|||||||
winit = "0.28"
|
winit = "0.28"
|
||||||
wgpu = "0.18"
|
wgpu = "0.18"
|
||||||
bytemuck = { version = "1.12", features = ["derive"] }
|
bytemuck = { version = "1.12", features = ["derive"] }
|
||||||
# Physics
|
|
||||||
rapier2d = "0.17.2"
|
|
||||||
nalgebra = "0.32.3"
|
|
||||||
crossbeam = "0.8.3"
|
|
||||||
# Misc helpers
|
# Misc helpers
|
||||||
pollster = "0.3"
|
pollster = "0.3"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cgmath = "0.18.0"
|
cgmath = "0.18.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
walkdir = "2.4.0"
|
walkdir = "2.4.0"
|
||||||
|
rapier2d = "0.17.2"
|
||||||
|
nalgebra = "0.32.3"
|
||||||
|
crossbeam = "0.8.3"
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
[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"
|
|
@ -17,18 +17,10 @@ pub(super) mod syntax {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an (foward) engine outfit that may be attached to a ship.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
/// The name of this outfit
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
/// How much thrust this engine produces
|
|
||||||
pub thrust: f32,
|
pub thrust: f32,
|
||||||
|
|
||||||
/// The flare sprite this engine creates.
|
|
||||||
/// Its location and size is determined by a ship's
|
|
||||||
/// engine points.
|
|
||||||
pub flare_sprite: String,
|
pub flare_sprite: String,
|
||||||
}
|
}
|
||||||
|
|
@ -27,54 +27,24 @@ pub(super) mod syntax {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a gun outfit.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Gun {
|
pub struct Gun {
|
||||||
/// The name of this gun
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
/// The projectile this gun produces
|
|
||||||
pub projectile: Projectile,
|
pub projectile: Projectile,
|
||||||
|
|
||||||
/// The accuracy of this gun.
|
|
||||||
/// Projectiles can be off center up to
|
|
||||||
/// `spread / 2` degrees in both directions.
|
|
||||||
///
|
|
||||||
/// (Forming a "fire cone" of `spread` degrees)
|
|
||||||
pub spread: Deg<f32>,
|
pub spread: Deg<f32>,
|
||||||
|
|
||||||
/// Average delay between projectiles, in seconds.
|
|
||||||
pub rate: f32,
|
pub rate: f32,
|
||||||
|
|
||||||
/// Random variation of projectile delay, in seconds.
|
|
||||||
/// Each shot waits (rate += rate_rng).
|
|
||||||
pub rate_rng: f32,
|
pub rate_rng: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a projectile that a [`Gun`] produces.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Projectile {
|
pub struct Projectile {
|
||||||
/// The projectile sprite
|
|
||||||
pub sprite: String,
|
pub sprite: String,
|
||||||
|
|
||||||
/// The average size of this projectile
|
|
||||||
/// (height in game units)
|
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
/// Random size variation
|
|
||||||
pub size_rng: f32,
|
pub size_rng: f32,
|
||||||
|
|
||||||
/// The speed of this projectile, in game units / second
|
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
/// Random speed variation
|
|
||||||
pub speed_rng: f32,
|
pub speed_rng: f32,
|
||||||
|
|
||||||
/// The lifespan of this projectile.
|
|
||||||
/// It will vanish if it lives this long without hitting anything.
|
|
||||||
pub lifetime: f32,
|
pub lifetime: f32,
|
||||||
/// Random lifetime variation
|
|
||||||
pub lifetime_rng: f32,
|
pub lifetime_rng: f32,
|
||||||
|
|
||||||
/// The damage this projectile does
|
|
||||||
pub damage: f32,
|
pub damage: f32,
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,8 @@
|
|||||||
#![warn(missing_docs)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
//! This subcrate is responsible for loading, parsing, validating game content,
|
|
||||||
//! which is usually stored in `./content`.
|
|
||||||
|
|
||||||
mod engine;
|
mod engine;
|
||||||
mod gun;
|
mod gun;
|
||||||
mod ship;
|
mod ship;
|
||||||
mod system;
|
mod system;
|
||||||
mod util;
|
|
||||||
|
|
||||||
pub use engine::Engine;
|
pub use engine::Engine;
|
||||||
pub use gun::{Gun, Projectile};
|
pub use gun::{Gun, Projectile};
|
||||||
@ -44,16 +39,9 @@ trait Build {
|
|||||||
/// Represents generic game content, not connected to any game objects.
|
/// Represents generic game content, not connected to any game objects.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Content {
|
pub struct Content {
|
||||||
/// Star systems
|
|
||||||
pub systems: Vec<system::System>,
|
pub systems: Vec<system::System>,
|
||||||
|
|
||||||
/// Ship bodies
|
|
||||||
pub ships: Vec<ship::Ship>,
|
pub ships: Vec<ship::Ship>,
|
||||||
|
|
||||||
/// Gun outfits
|
|
||||||
pub guns: Vec<gun::Gun>,
|
pub guns: Vec<gun::Gun>,
|
||||||
|
|
||||||
/// Engine outfits
|
|
||||||
pub engines: Vec<engine::Engine>,
|
pub engines: Vec<engine::Engine>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +79,6 @@ impl Content {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load content from a directory.
|
|
||||||
pub fn load_dir(path: &str) -> Result<Self> {
|
pub fn load_dir(path: &str) -> Result<Self> {
|
||||||
let mut content = Self {
|
let mut content = Self {
|
||||||
systems: Vec::new(),
|
systems: Vec::new(),
|
@ -32,50 +32,24 @@ pub(super) mod syntax {
|
|||||||
// Processed data structs.
|
// Processed data structs.
|
||||||
// These are exported.
|
// These are exported.
|
||||||
|
|
||||||
/// Represents a ship chassis.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Ship {
|
pub struct Ship {
|
||||||
/// This ship's name
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
/// This ship's sprite
|
|
||||||
pub sprite: String,
|
pub sprite: String,
|
||||||
|
|
||||||
/// The size of this ship.
|
|
||||||
/// Measured as unrotated height,
|
|
||||||
/// in terms of game units.
|
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
|
|
||||||
/// Engine points on this ship.
|
|
||||||
/// This is where engine flares are drawn.
|
|
||||||
pub engines: Vec<EnginePoint>,
|
pub engines: Vec<EnginePoint>,
|
||||||
|
|
||||||
/// Gun points on this ship.
|
|
||||||
/// A gun outfit can be mounted on each.
|
|
||||||
pub guns: Vec<GunPoint>,
|
pub guns: Vec<GunPoint>,
|
||||||
|
|
||||||
/// This ship's hull strength
|
|
||||||
pub hull: f32,
|
pub hull: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An engine point on a ship.
|
|
||||||
/// This is where flares are drawn.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EnginePoint {
|
pub struct EnginePoint {
|
||||||
/// This engine point's position, in game units,
|
|
||||||
/// relative to the ship's center.
|
|
||||||
pub pos: Point2<f32>,
|
pub pos: Point2<f32>,
|
||||||
|
|
||||||
/// The size of the flare that should be drawn
|
|
||||||
/// at this point, measured as height in game units.
|
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A gun point on a ship.
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct GunPoint {
|
pub struct GunPoint {
|
||||||
/// This gun point's position, in game units,
|
|
||||||
/// relative to the ship's center.
|
|
||||||
pub pos: Point2<f32>,
|
pub pos: Point2<f32>,
|
||||||
}
|
}
|
||||||
|
|
@ -77,36 +77,17 @@ pub(super) mod syntax {
|
|||||||
// Processed data structs.
|
// Processed data structs.
|
||||||
// These are exported.
|
// These are exported.
|
||||||
|
|
||||||
/// Represents a star system
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct System {
|
pub struct System {
|
||||||
/// This star system's name
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
/// Objects in this system
|
|
||||||
pub objects: Vec<Object>,
|
pub objects: Vec<Object>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an orbiting body in a star system
|
|
||||||
/// (A star, planet, moon, satellite, etc)
|
|
||||||
/// These may be landable and may be decorative.
|
|
||||||
/// System objects to not interact with the physics engine.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Object {
|
pub struct Object {
|
||||||
/// This object's sprite
|
|
||||||
pub sprite: String,
|
pub sprite: String,
|
||||||
|
|
||||||
/// This object's size.
|
|
||||||
/// Measured as height in game units.
|
|
||||||
/// This value is scaled for distance
|
|
||||||
/// (i.e, the z-value of position)
|
|
||||||
pub size: f32,
|
|
||||||
|
|
||||||
/// This object's position, in game coordinates,
|
|
||||||
/// relative to the system's center (0, 0).
|
|
||||||
pub position: Point3<f32>,
|
pub position: Point3<f32>,
|
||||||
|
pub size: f32,
|
||||||
/// This object's sprite's angle, in degrees.
|
|
||||||
pub angle: Deg<f32>,
|
pub angle: Deg<f32>,
|
||||||
}
|
}
|
||||||
|
|
@ -1,15 +1,14 @@
|
|||||||
use cgmath::Point2;
|
|
||||||
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, outfits, system::System};
|
use super::{
|
||||||
use crate::{
|
camera::Camera,
|
||||||
consts,
|
system::System,
|
||||||
content::Content,
|
util,
|
||||||
inputstatus::InputStatus,
|
world::{ShipGun, ShipHandle, ShipOutfit, World},
|
||||||
physics::{util, Physics, ShipHandle},
|
InputStatus,
|
||||||
render::Sprite,
|
|
||||||
};
|
};
|
||||||
|
use crate::{consts, content::Content, render::Sprite};
|
||||||
|
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
pub input: InputStatus,
|
pub input: InputStatus,
|
||||||
@ -20,32 +19,23 @@ pub struct Game {
|
|||||||
paused: bool,
|
paused: bool,
|
||||||
pub time_scale: f32,
|
pub time_scale: f32,
|
||||||
|
|
||||||
world: Physics,
|
world: World,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn new(ct: Content) -> Self {
|
pub fn new(ct: Content) -> Self {
|
||||||
let mut world = Physics::new();
|
let mut world = World::new();
|
||||||
|
|
||||||
let c = world.add_ship(
|
let c = world.add_ship(
|
||||||
&ct.ships[0],
|
&ct.ships[0],
|
||||||
vec![
|
vec![
|
||||||
outfits::ShipOutfit::Gun(outfits::ShipGun::new(ct.guns[0].clone(), 1)),
|
ShipOutfit::Gun(ShipGun::new(ct.guns[0].clone(), 1)),
|
||||||
outfits::ShipOutfit::Gun(outfits::ShipGun::new(ct.guns[0].clone(), 2)),
|
ShipOutfit::Gun(ShipGun::new(ct.guns[0].clone(), 2)),
|
||||||
outfits::ShipOutfit::Engine(ct.engines[0].clone()),
|
ShipOutfit::Engine(ct.engines[0].clone()),
|
||||||
],
|
],
|
||||||
Point2 { x: 0.0, y: 0.0 },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
world.add_ship(&ct.ships[0], vec![], Point2 { x: 300.0, y: 300.0 });
|
world.add_ship(&ct.ships[0], vec![]);
|
||||||
world.add_ship(
|
|
||||||
&ct.ships[0],
|
|
||||||
vec![],
|
|
||||||
Point2 {
|
|
||||||
x: -300.0,
|
|
||||||
y: 300.0,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Game {
|
Game {
|
||||||
last_update: Instant::now(),
|
last_update: Instant::now(),
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
//! This module contains high-level game control routines.
|
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod game;
|
mod game;
|
||||||
pub mod outfits;
|
mod inputstatus;
|
||||||
mod system;
|
mod system;
|
||||||
mod systemobject;
|
mod systemobject;
|
||||||
|
mod util;
|
||||||
|
mod world;
|
||||||
|
|
||||||
pub use game::Game;
|
pub use game::Game;
|
||||||
|
pub use inputstatus::InputStatus;
|
||||||
pub use systemobject::SystemObject;
|
pub use systemobject::SystemObject;
|
||||||
|
13
src/game/world/mod.rs
Normal file
13
src/game/world/mod.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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);
|
@ -8,7 +8,7 @@ use rapier2d::{
|
|||||||
pipeline::{EventHandler, PhysicsPipeline},
|
pipeline::{EventHandler, PhysicsPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) struct Wrapper {
|
pub(super) struct PhysicsWrapper {
|
||||||
pub rigid_body_set: RigidBodySet,
|
pub rigid_body_set: RigidBodySet,
|
||||||
pub collider_set: ColliderSet,
|
pub collider_set: ColliderSet,
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ pub(super) struct Wrapper {
|
|||||||
pub ccd: CCDSolver,
|
pub ccd: CCDSolver,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wrapper {
|
impl PhysicsWrapper {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
rigid_body_set: RigidBodySet::new(),
|
rigid_body_set: RigidBodySet::new(),
|
@ -4,10 +4,8 @@ use rapier2d::{
|
|||||||
geometry::{ColliderBuilder, ColliderHandle},
|
geometry::{ColliderBuilder, ColliderHandle},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use super::super::util;
|
||||||
physics::util,
|
use crate::render::{Sprite, SpriteTexture};
|
||||||
render::{Sprite, SpriteTexture},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ProjectileBuilder {
|
pub struct ProjectileBuilder {
|
||||||
pub rigid_body: RigidBodyBuilder,
|
pub rigid_body: RigidBodyBuilder,
|
29
src/game/world/ship/mod.rs
Normal file
29
src/game/world/ship/mod.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
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>,
|
||||||
|
}
|
@ -1,46 +1,21 @@
|
|||||||
use cgmath::{Deg, EuclideanSpace, Matrix2, Rad, Vector2};
|
use cgmath::{Deg, EuclideanSpace, Matrix2, Rad, Vector2};
|
||||||
use nalgebra::vector;
|
use nalgebra::vector;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rapier2d::{
|
use rapier2d::dynamics::{RigidBody, RigidBodyBuilder};
|
||||||
dynamics::{RigidBody, RigidBodyBuilder},
|
use rapier2d::geometry::ColliderBuilder;
|
||||||
geometry::ColliderBuilder,
|
use rapier2d::pipeline::ActiveEvents;
|
||||||
pipeline::ActiveEvents,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::ProjectileBuilder;
|
use super::ProjectileBuilder;
|
||||||
|
use super::{outfits::ShipOutfits, InputStatus, ShipControls, ShipOutfit, ShipTickResult};
|
||||||
|
use crate::game::{util, world::ShipHandle};
|
||||||
use crate::{
|
use crate::{
|
||||||
content,
|
content,
|
||||||
game::outfits,
|
|
||||||
inputstatus::InputStatus,
|
|
||||||
physics::{util, ShipHandle},
|
|
||||||
render::{Sprite, SpriteTexture},
|
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 struct Ship {
|
||||||
pub physics_handle: ShipHandle,
|
pub physics_handle: ShipHandle,
|
||||||
outfits: outfits::ShipOutfits,
|
outfits: ShipOutfits,
|
||||||
|
|
||||||
sprite: SpriteTexture,
|
sprite: SpriteTexture,
|
||||||
size: f32,
|
size: f32,
|
||||||
@ -51,12 +26,8 @@ pub struct Ship {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ship {
|
impl Ship {
|
||||||
pub fn new(
|
pub fn new(c: &content::Ship, outfits: Vec<ShipOutfit>, physics_handle: ShipHandle) -> Self {
|
||||||
c: &content::Ship,
|
let mut o = ShipOutfits::new(c);
|
||||||
outfits: Vec<outfits::ShipOutfit>,
|
|
||||||
physics_handle: ShipHandle,
|
|
||||||
) -> Self {
|
|
||||||
let mut o = outfits::ShipOutfits::new(c);
|
|
||||||
for x in outfits.into_iter() {
|
for x in outfits.into_iter() {
|
||||||
o.add(x)
|
o.add(x)
|
||||||
}
|
}
|
@ -1,4 +1,3 @@
|
|||||||
use cgmath::Point2;
|
|
||||||
use crossbeam::channel::Receiver;
|
use crossbeam::channel::Receiver;
|
||||||
use nalgebra::vector;
|
use nalgebra::vector;
|
||||||
use rapier2d::{
|
use rapier2d::{
|
||||||
@ -8,55 +7,57 @@ use rapier2d::{
|
|||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::{wrapper::Wrapper, ShipHandle};
|
use super::{
|
||||||
use crate::{content, game::outfits, objects, render::Sprite};
|
physicswrapper::PhysicsWrapper, Projectile, ProjectileBuilder, Ship, ShipHandle, ShipOutfit,
|
||||||
|
};
|
||||||
|
use crate::{content, render::Sprite};
|
||||||
|
|
||||||
/// Keeps track of all objects in the world that we can interact with.
|
/// Keeps track of all objects in the world that we can interact with.
|
||||||
/// Also wraps our physics engine
|
/// Also wraps our physics engine
|
||||||
pub struct Physics {
|
pub struct World {
|
||||||
wrapper: Wrapper,
|
physics: PhysicsWrapper,
|
||||||
projectiles: HashMap<ColliderHandle, objects::Projectile>,
|
projectiles: HashMap<ColliderHandle, Projectile>,
|
||||||
ships: HashMap<ColliderHandle, objects::Ship>,
|
ships: HashMap<ColliderHandle, Ship>,
|
||||||
|
|
||||||
collision_handler: ChannelEventCollector,
|
collision_handler: ChannelEventCollector,
|
||||||
collision_queue: Receiver<CollisionEvent>,
|
collision_queue: Receiver<CollisionEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
impl Physics {
|
impl World {
|
||||||
fn remove_projectile(&mut self, c: ColliderHandle) {
|
fn remove_projectile(&mut self, c: ColliderHandle) {
|
||||||
let p = match self.projectiles.remove(&c) {
|
let p = match self.projectiles.remove(&c) {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
self.wrapper.rigid_body_set.remove(
|
self.physics.rigid_body_set.remove(
|
||||||
p.rigid_body,
|
p.rigid_body,
|
||||||
&mut self.wrapper.im,
|
&mut self.physics.im,
|
||||||
&mut self.wrapper.collider_set,
|
&mut self.physics.collider_set,
|
||||||
&mut self.wrapper.ij,
|
&mut self.physics.ij,
|
||||||
&mut self.wrapper.mj,
|
&mut self.physics.mj,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_ship(&mut self, h: ShipHandle) {
|
fn remove_ship(&mut self, h: ShipHandle) {
|
||||||
self.wrapper.rigid_body_set.remove(
|
self.physics.rigid_body_set.remove(
|
||||||
h.0,
|
h.0,
|
||||||
&mut self.wrapper.im,
|
&mut self.physics.im,
|
||||||
&mut self.wrapper.collider_set,
|
&mut self.physics.collider_set,
|
||||||
&mut self.wrapper.ij,
|
&mut self.physics.ij,
|
||||||
&mut self.wrapper.mj,
|
&mut self.physics.mj,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
self.ships.remove(&h.1);
|
self.ships.remove(&h.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_projectile(&mut self, pb: objects::ProjectileBuilder) -> ColliderHandle {
|
fn add_projectile(&mut self, pb: ProjectileBuilder) -> ColliderHandle {
|
||||||
let r = self.wrapper.rigid_body_set.insert(pb.rigid_body.build());
|
let r = self.physics.rigid_body_set.insert(pb.rigid_body.build());
|
||||||
let c = self.wrapper.collider_set.insert_with_parent(
|
let c = self.physics.collider_set.insert_with_parent(
|
||||||
pb.collider.build(),
|
pb.collider.build(),
|
||||||
r,
|
r,
|
||||||
&mut self.wrapper.rigid_body_set,
|
&mut self.physics.rigid_body_set,
|
||||||
);
|
);
|
||||||
self.projectiles.insert(c, pb.build(r, c));
|
self.projectiles.insert(c, pb.build(r, c));
|
||||||
return c;
|
return c;
|
||||||
@ -64,13 +65,13 @@ impl Physics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Public methods
|
// Public methods
|
||||||
impl Physics {
|
impl World {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let (collision_send, collision_queue) = crossbeam::channel::unbounded();
|
let (collision_send, collision_queue) = crossbeam::channel::unbounded();
|
||||||
let (contact_force_send, _) = crossbeam::channel::unbounded();
|
let (contact_force_send, _) = crossbeam::channel::unbounded();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
wrapper: Wrapper::new(),
|
physics: PhysicsWrapper::new(),
|
||||||
projectiles: HashMap::new(),
|
projectiles: HashMap::new(),
|
||||||
ships: HashMap::new(),
|
ships: HashMap::new(),
|
||||||
collision_handler: ChannelEventCollector::new(collision_send, contact_force_send),
|
collision_handler: ChannelEventCollector::new(collision_send, contact_force_send),
|
||||||
@ -78,26 +79,21 @@ impl Physics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_ship(
|
pub fn add_ship(&mut self, ct: &content::Ship, outfits: Vec<ShipOutfit>) -> ShipHandle {
|
||||||
&mut self,
|
|
||||||
ct: &content::Ship,
|
|
||||||
outfits: Vec<outfits::ShipOutfit>,
|
|
||||||
position: Point2<f32>,
|
|
||||||
) -> ShipHandle {
|
|
||||||
let rb = RigidBodyBuilder::dynamic()
|
let rb = RigidBodyBuilder::dynamic()
|
||||||
.translation(vector![position.x, position.y])
|
.translation(vector![0.0, 0.0])
|
||||||
.can_sleep(false);
|
.can_sleep(false);
|
||||||
let cl = ColliderBuilder::ball(50.0).restitution(0.7).mass(1.0);
|
let cl = ColliderBuilder::ball(50.0).restitution(0.7).mass(1.0);
|
||||||
|
|
||||||
let r = self.wrapper.rigid_body_set.insert(rb.build());
|
let r = self.physics.rigid_body_set.insert(rb.build());
|
||||||
let c = self.wrapper.collider_set.insert_with_parent(
|
let c = self.physics.collider_set.insert_with_parent(
|
||||||
cl.build(),
|
cl.build(),
|
||||||
r,
|
r,
|
||||||
&mut self.wrapper.rigid_body_set,
|
&mut self.physics.rigid_body_set,
|
||||||
);
|
);
|
||||||
|
|
||||||
let h = ShipHandle(r, c);
|
let h = ShipHandle(r, c);
|
||||||
self.ships.insert(c, objects::Ship::new(ct, outfits, h));
|
self.ships.insert(c, Ship::new(ct, outfits, h));
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +106,7 @@ impl Physics {
|
|||||||
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.physics.rigid_body_set[s.physics_handle.0];
|
||||||
res.push(s.tick(r, t));
|
res.push(s.tick(r, t));
|
||||||
}
|
}
|
||||||
for r in to_remove {
|
for r in to_remove {
|
||||||
@ -123,7 +119,7 @@ impl Physics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update physics
|
// Update physics
|
||||||
self.wrapper.step(t, &self.collision_handler);
|
self.physics.step(t, &self.collision_handler);
|
||||||
|
|
||||||
// Handle collision events
|
// Handle collision events
|
||||||
while let Ok(event) = &self.collision_queue.try_recv() {
|
while let Ok(event) = &self.collision_queue.try_recv() {
|
||||||
@ -163,22 +159,22 @@ impl Physics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rigid_body(&self, r: RigidBodyHandle) -> &RigidBody {
|
pub fn get_rigid_body(&self, r: RigidBodyHandle) -> &RigidBody {
|
||||||
&self.wrapper.rigid_body_set[r]
|
&self.physics.rigid_body_set[r]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ship_mut(&mut self, s: &ShipHandle) -> &mut objects::Ship {
|
pub fn get_ship_mut(&mut self, s: &ShipHandle) -> &mut Ship {
|
||||||
self.ships.get_mut(&s.1).unwrap()
|
self.ships.get_mut(&s.1).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ship_sprites(&self) -> impl Iterator<Item = Sprite> + '_ {
|
pub fn get_ship_sprites(&self) -> impl Iterator<Item = Sprite> + '_ {
|
||||||
self.ships
|
self.ships
|
||||||
.values()
|
.values()
|
||||||
.map(|x| x.get_sprite(&self.wrapper.rigid_body_set[x.physics_handle.0]))
|
.map(|x| x.get_sprite(&self.physics.rigid_body_set[x.physics_handle.0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_projectile_sprites(&self) -> impl Iterator<Item = Sprite> + '_ {
|
pub fn get_projectile_sprites(&self) -> impl Iterator<Item = Sprite> + '_ {
|
||||||
self.projectiles
|
self.projectiles
|
||||||
.values()
|
.values()
|
||||||
.map(|x| x.get_sprite(&self.wrapper.rigid_body_set[x.rigid_body]))
|
.map(|x| x.get_sprite(&self.physics.rigid_body_set[x.rigid_body]))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,10 @@
|
|||||||
mod consts;
|
mod consts;
|
||||||
|
mod content;
|
||||||
mod game;
|
mod game;
|
||||||
mod inputstatus;
|
|
||||||
mod objects;
|
|
||||||
mod physics;
|
|
||||||
mod render;
|
mod render;
|
||||||
|
mod util;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use galactica_content as content;
|
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{Event, KeyboardInput, WindowEvent},
|
event::{Event, KeyboardInput, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
//! This module contains game objects that may interact with the physics engine.
|
|
||||||
|
|
||||||
mod projectile;
|
|
||||||
mod ship;
|
|
||||||
|
|
||||||
pub use projectile::{Projectile, ProjectileBuilder};
|
|
||||||
pub use ship::Ship;
|
|
@ -1,10 +0,0 @@
|
|||||||
mod physics;
|
|
||||||
pub mod util;
|
|
||||||
mod wrapper;
|
|
||||||
|
|
||||||
pub use physics::Physics;
|
|
||||||
|
|
||||||
use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle};
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct ShipHandle(pub(super) RigidBodyHandle, ColliderHandle);
|
|
Loading…
x
Reference in New Issue
Block a user