Unified position & added star prototype
parent
f5f52e7e75
commit
d3c0aab55a
|
@ -3,29 +3,21 @@ use sdl2::render::Canvas;
|
|||
use sdl2::video::Window;
|
||||
|
||||
use crate::physics::PhysVec;
|
||||
use crate::physics::Position;
|
||||
use crate::Camera;
|
||||
use crate::Drawable;
|
||||
use crate::SpriteAtlas;
|
||||
|
||||
pub struct Doodad {
|
||||
sprite: String,
|
||||
pos: PhysVec,
|
||||
scale: u32,
|
||||
}
|
||||
|
||||
impl Doodad {
|
||||
pub fn new(pos: PhysVec) -> Self {
|
||||
Doodad {
|
||||
sprite: "a0.png".to_owned(),
|
||||
pos,
|
||||
scale: 1,
|
||||
}
|
||||
}
|
||||
pub sprite: String,
|
||||
pub pos: Position,
|
||||
pub scale: u32,
|
||||
pub angle: f64,
|
||||
}
|
||||
|
||||
impl Drawable for Doodad {
|
||||
fn position(&self) -> PhysVec {
|
||||
self.pos
|
||||
self.pos.to_cartesian().into()
|
||||
}
|
||||
|
||||
fn draw(
|
||||
|
@ -48,10 +40,15 @@ impl Drawable for Doodad {
|
|||
|
||||
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(
|
||||
112 / (2 * self.scale) as i32,
|
||||
112 / (2 * self.scale) as i32,
|
||||
sprite.rect.width() as i32 / (2 * self.scale) as i32,
|
||||
sprite.rect.height() as i32 / (2 * self.scale) as i32,
|
||||
));
|
||||
|
||||
// set the current frame for time
|
||||
|
@ -63,8 +60,11 @@ impl Drawable for Doodad {
|
|||
&sprite.texture,
|
||||
Some(sprite.rect),
|
||||
Some(dest_rect_0),
|
||||
0.0, // angle
|
||||
Point::new(120 / (2 * self.scale) as i32, 270 / (2 * self.scale) as i32), // center
|
||||
self.angle.to_degrees(), // angle
|
||||
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,
|
||||
)?;
|
||||
|
|
62
src/main.rs
62
src/main.rs
|
@ -1,3 +1,4 @@
|
|||
use rand::Rng;
|
||||
use sdl2::{event::Event, keyboard::Keycode, render::Canvas, video::Window};
|
||||
use std::{time::Duration, time::Instant};
|
||||
|
||||
|
@ -7,11 +8,10 @@ mod physics;
|
|||
mod ship;
|
||||
mod spriteatlas;
|
||||
|
||||
use crate::doodad::Doodad;
|
||||
use crate::inputstatus::InputStatus;
|
||||
use crate::physics::PhysVec;
|
||||
use crate::ship::Ship;
|
||||
use crate::spriteatlas::SpriteAtlas;
|
||||
use crate::{
|
||||
doodad::Doodad, inputstatus::InputStatus, physics::PhysVec, physics::Position, ship::Ship,
|
||||
spriteatlas::SpriteAtlas,
|
||||
};
|
||||
|
||||
trait Drawable {
|
||||
/// Return the world position of this object
|
||||
|
@ -51,38 +51,67 @@ struct Camera {
|
|||
impl Camera {
|
||||
fn new() -> Self {
|
||||
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 {
|
||||
decor: Vec<Box<dyn Drawable>>,
|
||||
bodies: Vec<Box<dyn Drawable>>,
|
||||
}
|
||||
|
||||
impl System {
|
||||
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())));
|
||||
s.decor
|
||||
.push(Box::new(Doodad::new(PhysVec { x: 100.0, y: 23.0 })));
|
||||
let mut num = rand::thread_rng();
|
||||
for _ in 0..25 {
|
||||
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;
|
||||
}
|
||||
|
||||
/// 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(
|
||||
&self,
|
||||
canvas: &mut Canvas<Window>,
|
||||
sa: &SpriteAtlas,
|
||||
c: &Camera,
|
||||
) -> Result<(), String> {
|
||||
for d in &self.decor {
|
||||
d.draw(canvas, sa, c)?
|
||||
for body in &self.bodies {
|
||||
body.draw(canvas, sa, c)?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +137,7 @@ fn main() -> Result<(), String> {
|
|||
let sa = SpriteAtlas::new(&texture_creator)?;
|
||||
let mut event_pump = sdl_context.event_pump()?;
|
||||
|
||||
let system = System::new();
|
||||
let mut system = System::new();
|
||||
|
||||
let mut i = InputStatus::new();
|
||||
let mut c = Camera::new();
|
||||
|
@ -157,6 +186,7 @@ fn main() -> Result<(), String> {
|
|||
//last_frame_time = frame_time;
|
||||
|
||||
s.body.tick(frame_time);
|
||||
system.tick(frame_time);
|
||||
|
||||
if i.key_thrust {
|
||||
s.body.thrust(50.0 * frame_time);
|
||||
|
|
|
@ -12,7 +12,7 @@ impl PhysBody {
|
|||
pub fn new() -> Self {
|
||||
return PhysBody {
|
||||
pos: PhysVec { x: 200.0, y: 200.0 },
|
||||
vel: PhysVec::zero(),
|
||||
vel: PhysVec { x: 0.0, y: 0.0 },
|
||||
mass: 1.0,
|
||||
angle: 0.0,
|
||||
};
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
mod body;
|
||||
mod physpol;
|
||||
mod physvec;
|
||||
mod position;
|
||||
|
||||
pub use body::PhysBody;
|
||||
pub use physpol::PhysPol;
|
||||
pub use physvec::PhysVec;
|
||||
pub use position::Position;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -6,12 +6,6 @@ pub struct PhysVec {
|
|||
pub y: f64,
|
||||
}
|
||||
|
||||
impl PhysVec {
|
||||
pub fn zero() -> Self {
|
||||
return PhysVec { x: 0f64, y: 0f64 };
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u32, u32)> for PhysVec {
|
||||
fn from(value: (u32, u32)) -> Self {
|
||||
PhysVec {
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,8 @@ impl<'a> SpriteAtlas<'a> {
|
|||
|
||||
b.load_one(texture_creator, "gypsum.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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue