Unified position & added star prototype

master
Mark 2023-12-20 20:06:54 -08:00
parent f5f52e7e75
commit d3c0aab55a
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
8 changed files with 137 additions and 42 deletions

View File

@ -3,29 +3,21 @@ use sdl2::render::Canvas;
use sdl2::video::Window; use sdl2::video::Window;
use crate::physics::PhysVec; use crate::physics::PhysVec;
use crate::physics::Position;
use crate::Camera; use crate::Camera;
use crate::Drawable; use crate::Drawable;
use crate::SpriteAtlas; use crate::SpriteAtlas;
pub struct Doodad { pub struct Doodad {
sprite: String, pub sprite: String,
pos: PhysVec, pub pos: Position,
scale: u32, pub scale: u32,
} pub angle: f64,
impl Doodad {
pub fn new(pos: PhysVec) -> Self {
Doodad {
sprite: "a0.png".to_owned(),
pos,
scale: 1,
}
}
} }
impl Drawable for Doodad { impl Drawable for Doodad {
fn position(&self) -> PhysVec { fn position(&self) -> PhysVec {
self.pos self.pos.to_cartesian().into()
} }
fn draw( fn draw(
@ -48,10 +40,15 @@ impl Drawable for Doodad {
let sprite = sa.get(&self.sprite); let sprite = sa.get(&self.sprite);
let mut dest_rect_0 = Rect::new(0, 0, 112 / self.scale, 112 / self.scale); let mut dest_rect_0 = Rect::new(
0,
0,
sprite.rect.width() / self.scale,
sprite.rect.height() / self.scale,
);
dest_rect_0.center_on(Point::new( dest_rect_0.center_on(Point::new(
112 / (2 * self.scale) as i32, sprite.rect.width() as i32 / (2 * self.scale) as i32,
112 / (2 * self.scale) as i32, sprite.rect.height() as i32 / (2 * self.scale) as i32,
)); ));
// set the current frame for time // set the current frame for time
@ -63,8 +60,11 @@ impl Drawable for Doodad {
&sprite.texture, &sprite.texture,
Some(sprite.rect), Some(sprite.rect),
Some(dest_rect_0), Some(dest_rect_0),
0.0, // angle self.angle.to_degrees(), // angle
Point::new(120 / (2 * self.scale) as i32, 270 / (2 * self.scale) as i32), // center Point::new(
sprite.rect.width() as i32 / (2 * self.scale) as i32,
sprite.rect.width() as i32 / (2 * self.scale) as i32,
), // center
false, false,
false, false,
)?; )?;

View File

@ -1,3 +1,4 @@
use rand::Rng;
use sdl2::{event::Event, keyboard::Keycode, render::Canvas, video::Window}; use sdl2::{event::Event, keyboard::Keycode, render::Canvas, video::Window};
use std::{time::Duration, time::Instant}; use std::{time::Duration, time::Instant};
@ -7,11 +8,10 @@ mod physics;
mod ship; mod ship;
mod spriteatlas; mod spriteatlas;
use crate::doodad::Doodad; use crate::{
use crate::inputstatus::InputStatus; doodad::Doodad, inputstatus::InputStatus, physics::PhysVec, physics::Position, ship::Ship,
use crate::physics::PhysVec; spriteatlas::SpriteAtlas,
use crate::ship::Ship; };
use crate::spriteatlas::SpriteAtlas;
trait Drawable { trait Drawable {
/// Return the world position of this object /// Return the world position of this object
@ -51,38 +51,67 @@ struct Camera {
impl Camera { impl Camera {
fn new() -> Self { fn new() -> Self {
Camera { Camera {
pos: PhysVec::zero(), pos: PhysVec { x: 0.0, y: 0.0 },
} }
} }
} }
static FTL: f64 = 1.0 / 140.0; // frame time limit static FTL: f64 = 1.0 / 200.0; // frame time limit
struct System { struct System {
decor: Vec<Box<dyn Drawable>>, bodies: Vec<Box<dyn Drawable>>,
} }
impl System { impl System {
fn new() -> Self { fn new() -> Self {
let mut s = System { decor: Vec::new() }; let mut s = System { bodies: Vec::new() };
s.decor.push(Box::new(Doodad::new(PhysVec::zero()))); let mut num = rand::thread_rng();
s.decor for _ in 0..25 {
.push(Box::new(Doodad::new(PhysVec { x: 100.0, y: 23.0 }))); s.bodies.push(Box::new(Doodad {
sprite: "small.png".to_owned(),
pos: Position::new_cartesian(
num.gen_range(-500.0..500.0),
num.gen_range(-500.0..500.0),
),
scale: 1,
angle: num.gen_range(-3.0..3.0),
}));
}
s.bodies.push(Box::new(Doodad {
pos: Position::new_polar(PhysVec { x: 0.0, y: 0.0 }, 0.0, 0.0),
sprite: "a0.png".to_owned(),
scale: 1,
angle: 0.0,
}));
s.bodies.push(Box::new(Doodad {
pos: Position::new_polar(PhysVec { x: 0.0, y: 0.0 }, 300.0, 31.0),
sprite: "earth.png".to_owned(),
scale: 1,
angle: 180.0,
}));
return s; return s;
} }
/// Calculate the state of this body after t seconds.
pub fn tick(&mut self, _t: f64) {
//let body = &mut self.bodies[1];
//body.pos.angle += 0.1 * t;
//body.angle -= 0.1 * t;
}
fn draw( fn draw(
&self, &self,
canvas: &mut Canvas<Window>, canvas: &mut Canvas<Window>,
sa: &SpriteAtlas, sa: &SpriteAtlas,
c: &Camera, c: &Camera,
) -> Result<(), String> { ) -> Result<(), String> {
for d in &self.decor { for body in &self.bodies {
d.draw(canvas, sa, c)? body.draw(canvas, sa, c)?;
} }
return Ok(()); return Ok(());
} }
} }
@ -108,7 +137,7 @@ fn main() -> Result<(), String> {
let sa = SpriteAtlas::new(&texture_creator)?; let sa = SpriteAtlas::new(&texture_creator)?;
let mut event_pump = sdl_context.event_pump()?; let mut event_pump = sdl_context.event_pump()?;
let system = System::new(); let mut system = System::new();
let mut i = InputStatus::new(); let mut i = InputStatus::new();
let mut c = Camera::new(); let mut c = Camera::new();
@ -157,6 +186,7 @@ fn main() -> Result<(), String> {
//last_frame_time = frame_time; //last_frame_time = frame_time;
s.body.tick(frame_time); s.body.tick(frame_time);
system.tick(frame_time);
if i.key_thrust { if i.key_thrust {
s.body.thrust(50.0 * frame_time); s.body.thrust(50.0 * frame_time);

View File

@ -12,7 +12,7 @@ impl PhysBody {
pub fn new() -> Self { pub fn new() -> Self {
return PhysBody { return PhysBody {
pos: PhysVec { x: 200.0, y: 200.0 }, pos: PhysVec { x: 200.0, y: 200.0 },
vel: PhysVec::zero(), vel: PhysVec { x: 0.0, y: 0.0 },
mass: 1.0, mass: 1.0,
angle: 0.0, angle: 0.0,
}; };

View File

@ -1,5 +1,9 @@
mod body; mod body;
mod physpol;
mod physvec; mod physvec;
mod position;
pub use body::PhysBody; pub use body::PhysBody;
pub use physpol::PhysPol;
pub use physvec::PhysVec; pub use physvec::PhysVec;
pub use position::Position;

17
src/physics/physpol.rs Normal file
View File

@ -0,0 +1,17 @@
use super::PhysVec;
#[derive(Debug, Clone, Copy)]
pub struct PhysPol {
pub center: PhysVec,
pub radius: f64,
pub angle: f64,
}
impl PhysPol {
pub fn to_cartesian(&self) -> PhysVec {
return PhysVec {
x: self.radius * self.angle.sin(),
y: self.radius * self.angle.cos(),
} + self.center;
}
}

View File

@ -6,12 +6,6 @@ pub struct PhysVec {
pub y: f64, pub y: f64,
} }
impl PhysVec {
pub fn zero() -> Self {
return PhysVec { x: 0f64, y: 0f64 };
}
}
impl From<(u32, u32)> for PhysVec { impl From<(u32, u32)> for PhysVec {
fn from(value: (u32, u32)) -> Self { fn from(value: (u32, u32)) -> Self {
PhysVec { PhysVec {

48
src/physics/position.rs Normal file
View File

@ -0,0 +1,48 @@
use super::PhysPol;
use super::PhysVec;
#[derive(Debug, Clone, Copy)]
pub enum Position {
Cartesian(PhysVec),
Polar(PhysPol),
}
impl Position {
pub fn new_cartesian(x: f64, y: f64) -> Self {
return Self::Cartesian(PhysVec { x, y });
}
pub fn new_polar(center: PhysVec, radius: f64, angle: f64) -> Self {
return Self::Polar(PhysPol {
center,
radius,
angle,
});
}
/*
pub fn to_polar(&self) -> Self {
match self {
Self::Cartesian(pv) => Self::Polar(pv.to_polar()),
Self::Polar(_) => self.clone(),
}
}
*/
pub fn to_cartesian(&self) -> Self {
match self {
Self::Cartesian(_) => self.clone(),
Self::Polar(pp) => Self::Cartesian(pp.to_cartesian()),
}
}
}
impl Into<PhysVec> for Position {
fn into(self) -> PhysVec {
let c = self.to_cartesian();
match c {
Self::Cartesian(pv) => pv,
_ => unreachable!(),
}
}
}

View File

@ -28,6 +28,8 @@ impl<'a> SpriteAtlas<'a> {
b.load_one(texture_creator, "gypsum.png")?; b.load_one(texture_creator, "gypsum.png")?;
b.load_one(texture_creator, "a0.png")?; b.load_one(texture_creator, "a0.png")?;
b.load_one(texture_creator, "small.png")?;
b.load_one(texture_creator, "earth.png")?;
return Ok(b); return Ok(b);
} }