Compare commits
No commits in common. "0184418394de971be8437b0ec933f3f234687448" and "54a1a26a2ca81a79797026645480e0c51dec9314" have entirely different histories.
0184418394
...
54a1a26a2c
|
@ -9,7 +9,6 @@ use crate::{
|
||||||
inputstatus::InputStatus,
|
inputstatus::InputStatus,
|
||||||
physics::{util, Physics, ShipHandle},
|
physics::{util, Physics, ShipHandle},
|
||||||
render::Sprite,
|
render::Sprite,
|
||||||
shipbehavior::{self, ShipBehavior},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
|
@ -21,15 +20,14 @@ pub struct Game {
|
||||||
paused: bool,
|
paused: bool,
|
||||||
pub time_scale: f32,
|
pub time_scale: f32,
|
||||||
|
|
||||||
physics: Physics,
|
world: Physics,
|
||||||
shipbehaviors: Vec<Box<dyn ShipBehavior>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn new(ct: Content) -> Self {
|
pub fn new(ct: Content) -> Self {
|
||||||
let mut physics = Physics::new();
|
let mut world = Physics::new();
|
||||||
|
|
||||||
let h1 = physics.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)),
|
outfits::ShipOutfit::Gun(outfits::ShipGun::new(ct.guns[0].clone(), 1)),
|
||||||
|
@ -39,28 +37,20 @@ impl Game {
|
||||||
Point2 { x: 0.0, y: 0.0 },
|
Point2 { x: 0.0, y: 0.0 },
|
||||||
);
|
);
|
||||||
|
|
||||||
let h2 = physics.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 });
|
||||||
let h3 = physics.add_ship(
|
world.add_ship(
|
||||||
&ct.ships[0],
|
&ct.ships[0],
|
||||||
vec![outfits::ShipOutfit::Gun(outfits::ShipGun::new(
|
vec![],
|
||||||
ct.guns[0].clone(),
|
|
||||||
0,
|
|
||||||
))],
|
|
||||||
Point2 {
|
Point2 {
|
||||||
x: -300.0,
|
x: -300.0,
|
||||||
y: 300.0,
|
y: 300.0,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut shipbehaviors: Vec<Box<dyn ShipBehavior>> = Vec::new();
|
|
||||||
shipbehaviors.push(shipbehavior::Player::new(h1));
|
|
||||||
shipbehaviors.push(shipbehavior::Point::new(h3));
|
|
||||||
shipbehaviors.push(shipbehavior::Dummy::new(h2));
|
|
||||||
|
|
||||||
Game {
|
Game {
|
||||||
last_update: Instant::now(),
|
last_update: Instant::now(),
|
||||||
input: InputStatus::new(),
|
input: InputStatus::new(),
|
||||||
player: h1,
|
player: c,
|
||||||
|
|
||||||
camera: Camera {
|
camera: Camera {
|
||||||
pos: (0.0, 0.0).into(),
|
pos: (0.0, 0.0).into(),
|
||||||
|
@ -70,8 +60,7 @@ impl Game {
|
||||||
|
|
||||||
paused: false,
|
paused: false,
|
||||||
time_scale: 1.0,
|
time_scale: 1.0,
|
||||||
physics,
|
world,
|
||||||
shipbehaviors,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,11 +88,11 @@ impl Game {
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
|
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
|
||||||
|
|
||||||
for b in &mut self.shipbehaviors {
|
self.world
|
||||||
b.update_controls(&mut self.physics, &self.input, self.player);
|
.get_ship_mut(&self.player)
|
||||||
}
|
.update_controls(&self.input);
|
||||||
|
|
||||||
self.physics.step(t);
|
self.world.tick(t);
|
||||||
|
|
||||||
if self.input.v_scroll != 0.0 {
|
if self.input.v_scroll != 0.0 {
|
||||||
self.camera.zoom =
|
self.camera.zoom =
|
||||||
|
@ -112,8 +101,8 @@ impl Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Camera physics
|
// TODO: Camera physics
|
||||||
let r = self.physics.get_ship_mut(&self.player).physics_handle;
|
let r = self.world.get_ship_mut(&self.player).physics_handle;
|
||||||
let r = self.physics.get_rigid_body(r.0); // TODO: r.0 shouldn't be public
|
let r = self.world.get_rigid_body(r.0); // TODO: r.0 shouldn't be public
|
||||||
let ship_pos = util::rigidbody_position(r);
|
let ship_pos = util::rigidbody_position(r);
|
||||||
self.camera.pos = ship_pos;
|
self.camera.pos = ship_pos;
|
||||||
self.last_update = Instant::now();
|
self.last_update = Instant::now();
|
||||||
|
@ -123,7 +112,7 @@ impl Game {
|
||||||
let mut sprites: Vec<Sprite> = Vec::new();
|
let mut sprites: Vec<Sprite> = Vec::new();
|
||||||
|
|
||||||
sprites.append(&mut self.system.get_sprites());
|
sprites.append(&mut self.system.get_sprites());
|
||||||
sprites.extend(self.physics.get_ship_sprites());
|
sprites.extend(self.world.get_ship_sprites());
|
||||||
|
|
||||||
// Make sure sprites are drawn in the correct order
|
// Make sure sprites are drawn in the correct order
|
||||||
// (note the reversed a, b in the comparator)
|
// (note the reversed a, b in the comparator)
|
||||||
|
@ -133,7 +122,7 @@ impl Game {
|
||||||
sprites.sort_by(|a, b| b.pos.z.total_cmp(&a.pos.z));
|
sprites.sort_by(|a, b| b.pos.z.total_cmp(&a.pos.z));
|
||||||
|
|
||||||
// Don't waste time sorting these, they should always be on top.
|
// Don't waste time sorting these, they should always be on top.
|
||||||
sprites.extend(self.physics.get_projectile_sprites());
|
sprites.extend(self.world.get_projectile_sprites());
|
||||||
|
|
||||||
return sprites;
|
return sprites;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ mod inputstatus;
|
||||||
mod objects;
|
mod objects;
|
||||||
mod physics;
|
mod physics;
|
||||||
mod render;
|
mod render;
|
||||||
mod shipbehavior;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use galactica_content as content;
|
use galactica_content as content;
|
||||||
|
|
|
@ -11,14 +11,11 @@ use super::ProjectileBuilder;
|
||||||
use crate::{
|
use crate::{
|
||||||
content,
|
content,
|
||||||
game::outfits,
|
game::outfits,
|
||||||
|
inputstatus::InputStatus,
|
||||||
physics::{util, ShipHandle},
|
physics::{util, ShipHandle},
|
||||||
render::{Sprite, SpriteTexture},
|
render::{Sprite, SpriteTexture},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct ShipTickResult {
|
|
||||||
pub projectiles: Vec<ProjectileBuilder>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ShipControls {
|
pub struct ShipControls {
|
||||||
pub left: bool,
|
pub left: bool,
|
||||||
pub right: bool,
|
pub right: bool,
|
||||||
|
@ -37,6 +34,10 @@ impl ShipControls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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: outfits::ShipOutfits,
|
||||||
|
@ -44,6 +45,8 @@ pub struct Ship {
|
||||||
sprite: SpriteTexture,
|
sprite: SpriteTexture,
|
||||||
size: f32,
|
size: f32,
|
||||||
pub hull: f32,
|
pub hull: f32,
|
||||||
|
|
||||||
|
// TODO: replace with AI enum
|
||||||
pub controls: ShipControls,
|
pub controls: ShipControls,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +64,20 @@ impl Ship {
|
||||||
Ship {
|
Ship {
|
||||||
physics_handle,
|
physics_handle,
|
||||||
outfits: o,
|
outfits: o,
|
||||||
|
controls: ShipControls::new(),
|
||||||
sprite: SpriteTexture(c.sprite.clone()),
|
sprite: SpriteTexture(c.sprite.clone()),
|
||||||
size: c.size,
|
size: c.size,
|
||||||
hull: c.hull,
|
hull: c.hull,
|
||||||
controls: ShipControls::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_controls(&mut self, input: &InputStatus) {
|
||||||
|
self.controls.thrust = input.key_thrust;
|
||||||
|
self.controls.right = input.key_right;
|
||||||
|
self.controls.left = input.key_left;
|
||||||
|
self.controls.guns = input.key_guns;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fire_guns(&mut self, r: &RigidBody) -> Vec<ProjectileBuilder> {
|
pub fn fire_guns(&mut self, r: &RigidBody) -> Vec<ProjectileBuilder> {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
|
@ -120,11 +130,10 @@ impl Ship {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the effects of all active controls
|
pub fn tick(&mut self, r: &mut RigidBody, t: f32) -> ShipTickResult {
|
||||||
pub fn apply_controls(&mut self, r: &mut RigidBody, t: f32) -> ShipTickResult {
|
|
||||||
let ship_ang = util::rigidbody_angle(r);
|
let ship_ang = util::rigidbody_angle(r);
|
||||||
let engine_force = Matrix2::from_angle(ship_ang) * Vector2 { x: 0.0, y: 1.0 } * t;
|
|
||||||
|
|
||||||
|
let engine_force = Matrix2::from_angle(ship_ang) * Vector2 { x: 0.0, y: 1.0 } * t;
|
||||||
if self.controls.thrust {
|
if self.controls.thrust {
|
||||||
for e in self.outfits.iter_engines() {
|
for e in self.outfits.iter_engines() {
|
||||||
r.apply_impulse(vector![engine_force.x, engine_force.y] * e.thrust, true);
|
r.apply_impulse(vector![engine_force.x, engine_force.y] * e.thrust, true);
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl Physics {
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(&mut self, t: f32) {
|
pub fn tick(&mut self, t: f32) {
|
||||||
// Run ship updates
|
// Run ship updates
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
let mut to_remove = Vec::new();
|
let mut to_remove = Vec::new();
|
||||||
|
@ -111,7 +111,7 @@ impl Physics {
|
||||||
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];
|
||||||
res.push(s.apply_controls(r, t));
|
res.push(s.tick(r, t));
|
||||||
}
|
}
|
||||||
for r in to_remove {
|
for r in to_remove {
|
||||||
self.remove_ship(r);
|
self.remove_ship(r);
|
||||||
|
@ -170,14 +170,6 @@ impl Physics {
|
||||||
self.ships.get_mut(&s.1).unwrap()
|
self.ships.get_mut(&s.1).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ship_body(&self, s: &ShipHandle) -> (&objects::Ship, &RigidBody) {
|
|
||||||
// TODO: handle dead handles
|
|
||||||
(
|
|
||||||
self.ships.get(&s.1).unwrap(),
|
|
||||||
self.wrapper.rigid_body_set.get(s.0).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()
|
||||||
|
|
|
@ -18,13 +18,6 @@ pub fn rigidbody_angle(r: &RigidBody) -> Deg<f32> {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rigidbody_rotation(r: &RigidBody) -> Vector2<f32> {
|
|
||||||
Vector2 {
|
|
||||||
x: r.rotation().im,
|
|
||||||
y: r.rotation().re,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rigidbody_velocity(r: &RigidBody) -> cgmath::Vector2<f32> {
|
pub fn rigidbody_velocity(r: &RigidBody) -> cgmath::Vector2<f32> {
|
||||||
let v = r.velocity_at_point(&nalgebra::Point2::new(
|
let v = r.velocity_at_point(&nalgebra::Point2::new(
|
||||||
r.translation()[0],
|
r.translation()[0],
|
||||||
|
|
|
@ -220,17 +220,14 @@ impl GPUState {
|
||||||
// Game dimensions of this sprite post-scale.
|
// Game dimensions of this sprite post-scale.
|
||||||
// Don't divide by 2, we use this later.
|
// Don't divide by 2, we use this later.
|
||||||
let height = s.size / s.pos.z;
|
let height = s.size / s.pos.z;
|
||||||
|
let width = height * texture.aspect;
|
||||||
// Width or height, whichever is larger
|
|
||||||
// Accounts for sprite rotation.
|
|
||||||
let m = height * texture.aspect.max(1.0);
|
|
||||||
|
|
||||||
// Don't draw (or compute matrices for)
|
// Don't draw (or compute matrices for)
|
||||||
// sprites that are off the screen
|
// sprites that are off the screen
|
||||||
if pos.x < clip_ne.x - m
|
if pos.x < clip_ne.x - width
|
||||||
|| pos.y > clip_ne.y + m
|
|| pos.y > clip_ne.y + height
|
||||||
|| pos.x > clip_sw.x + m
|
|| pos.x > clip_sw.x + width
|
||||||
|| pos.y < clip_sw.y - m
|
|| pos.y < clip_sw.y - height
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
use cgmath::{Deg, InnerSpace};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
inputstatus::InputStatus,
|
|
||||||
physics::{util, Physics, ShipHandle},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait ShipBehavior
|
|
||||||
where
|
|
||||||
Self: Send,
|
|
||||||
{
|
|
||||||
fn update_controls(&mut self, physics: &mut Physics, input: &InputStatus, player: ShipHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Dummy {
|
|
||||||
_handle: ShipHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Dummy {
|
|
||||||
pub fn new(handle: ShipHandle) -> Box<Self> {
|
|
||||||
Box::new(Self { _handle: handle })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ShipBehavior for Dummy {
|
|
||||||
fn update_controls(
|
|
||||||
&mut self,
|
|
||||||
_physics: &mut Physics,
|
|
||||||
_input: &InputStatus,
|
|
||||||
_player: ShipHandle,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Player {
|
|
||||||
handle: ShipHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Player {
|
|
||||||
pub fn new(handle: ShipHandle) -> Box<Self> {
|
|
||||||
Box::new(Self { handle })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ShipBehavior for Player {
|
|
||||||
fn update_controls(&mut self, physics: &mut Physics, input: &InputStatus, _player: ShipHandle) {
|
|
||||||
let s = physics.get_ship_mut(&self.handle);
|
|
||||||
s.controls.left = input.key_left;
|
|
||||||
s.controls.right = input.key_right;
|
|
||||||
s.controls.guns = input.key_guns;
|
|
||||||
s.controls.thrust = input.key_thrust;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Point {
|
|
||||||
handle: ShipHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Point {
|
|
||||||
pub fn new(handle: ShipHandle) -> Box<Self> {
|
|
||||||
Box::new(Self { handle })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ShipBehavior for Point {
|
|
||||||
fn update_controls(&mut self, physics: &mut Physics, _input: &InputStatus, player: ShipHandle) {
|
|
||||||
let (_, r) = physics.get_ship_body(&player);
|
|
||||||
let p = util::rigidbody_position(r);
|
|
||||||
|
|
||||||
let (_, r) = physics.get_ship_body(&self.handle);
|
|
||||||
let t = util::rigidbody_position(r);
|
|
||||||
let pa = util::rigidbody_rotation(r);
|
|
||||||
let v = r.angvel();
|
|
||||||
|
|
||||||
let d: Deg<f32> = (t - p).angle(pa).into();
|
|
||||||
println!("{:?}", d);
|
|
||||||
|
|
||||||
let s = physics.get_ship_mut(&self.handle);
|
|
||||||
|
|
||||||
s.controls.left = false;
|
|
||||||
s.controls.right = false;
|
|
||||||
|
|
||||||
if d < Deg(0.0) && v < 0.1 {
|
|
||||||
s.controls.left = false;
|
|
||||||
s.controls.right = true;
|
|
||||||
println!("r")
|
|
||||||
} else if d > Deg(0.0) && v > -0.1 {
|
|
||||||
println!("l");
|
|
||||||
s.controls.left = true;
|
|
||||||
s.controls.right = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
s.controls.guns = true;
|
|
||||||
s.controls.thrust = false;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue