diff --git a/src/main.rs b/src/main.rs index cf0bac4..d24b423 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,8 +23,8 @@ async fn main() { struct OrbitsInstance { /// All objects being simulated. objects: Vec, - /// The current scale of the camera. - scale: f32, + /// The current camera. + camera: Camera2D, /// Selection of cached images. image_cache: Vec, } @@ -63,13 +63,13 @@ impl OrbitsInstance { SpaceObject::ship( Vec2::new(256.0, 0.0), Vec2::new(0.0, 0.6), - image_cache[0].clone(), + &image_cache[0], [KeyCode::W, KeyCode::A, KeyCode::D, KeyCode::S], ), SpaceObject::ship( Vec2::new(-256.0, 0.0), Vec2::new(0.0, -0.6), - image_cache[0].clone(), + &image_cache[0], [KeyCode::I, KeyCode::J, KeyCode::L, KeyCode::K], ), // Sun @@ -78,10 +78,10 @@ impl OrbitsInstance { Vec2::new(0.0, 0.0), 1024., 96., - image_cache[3].clone(), + &image_cache[3], ), ], - scale: 1.0, + camera: Camera2D::default(), image_cache, }) } @@ -154,8 +154,10 @@ impl OrbitsInstance { } // Delete all objects too far from the origin - self.objects - .retain(|object| object.get_position().length() <= 1000. && object.collisions_left()) + self.objects.retain(|object| { + (object.get_position().length() <= 1000. || object.is_ship()) + && object.collisions_left() + }) } /// Draws the current state to the screen. @@ -163,22 +165,29 @@ impl OrbitsInstance { // Clear the current frame clear_background(BLACK); + // Draw UI + + set_default_camera(); + draw_text("Ship 1", 0., 20., 12., WHITE); + + // Draw simulation + let (w, h) = (screen_width(), screen_height()); - self.scale = 0.5; + let mut scale: f32 = 0.5; for object in self.objects.iter().filter(|obj| obj.is_ship()) { - let w_scale = object.get_position().x.abs() / w * 2.0; - let h_scale = object.get_position().y.abs() / h * 2.0; + // 2.2 to leave some padding + let w_scale = object.get_position().x.abs() / w * 2.2; + let h_scale = object.get_position().y.abs() / h * 2.2; - self.scale = self.scale.max(w_scale).max(h_scale); + scale = scale.max(w_scale).max(h_scale); } - set_camera(&Camera2D { - target: Vec2::new(0.0, 0.0), - zoom: Vec2::new(1. / w, 1. / h) / self.scale * 1.5, - ..Default::default() - }); + // Camera is -1 to 1, so width and height 2. Correct by that and the reciprocal of screen width. + self.camera.zoom = Vec2::new(1. / w, 1. / h) / scale * 2.0; + + set_camera(&self.camera); for object in self.objects.iter() { object.draw(); diff --git a/src/space_object.rs b/src/space_object.rs index a6991b7..6396236 100644 --- a/src/space_object.rs +++ b/src/space_object.rs @@ -14,7 +14,7 @@ pub struct SpaceObject { /// The size of the object, determining its collision and appearance. size: f32, /// The image drawn to represent the object. - sprite: Image, + sprite: Texture2D, /// If the objects is a controllable space ship, this contains the ships special properties. ship: Option, /// Amount of collisions with other objects this one can survive @@ -34,14 +34,14 @@ impl SpaceObject { const ROT_ACCELERATION: f32 = 0.05; const LIN_ACCELARATION: f32 = 0.001; /// Creates a new space objects describing a ship - pub fn ship(position: Vec2, velocity: Vec2, ship_image: Image, keymap: [KeyCode; 4]) -> Self { + pub fn ship(position: Vec2, velocity: Vec2, ship_image: &Image, keymap: [KeyCode; 4]) -> Self { Self { position, velocity, angle: 0.0, mass: 1.0, size: 16.0, - sprite: ship_image, + sprite: Texture2D::from_image(ship_image), ship: Some(ShipInfo { shot_cd: 0.0, keymap, @@ -51,14 +51,14 @@ impl SpaceObject { } /// Creates a new space object describing a celestial body, non-controllable and not a ship. - pub fn body(position: Vec2, velocity: Vec2, mass: f32, size: f32, image: Image) -> Self { + pub fn body(position: Vec2, velocity: Vec2, mass: f32, size: f32, image: &Image) -> Self { Self { position, velocity, angle: 0.0, mass, size, - sprite: image, + sprite: Texture2D::from_image(image), ship: None, collisions: None, } @@ -83,9 +83,9 @@ impl SpaceObject { // Acceleration if is_key_down(ship_info.keymap[0]) { self.velocity += Vec2::new(self.angle.cos(), self.angle.sin()) * Self::LIN_ACCELARATION; - self.sprite = images[1].clone(); + self.sprite = Texture2D::from_image(&images[1]); } else { - self.sprite = images[0].clone(); + self.sprite = Texture2D::from_image(&images[0]); } // Turning if is_key_down(ship_info.keymap[1]) { @@ -104,7 +104,7 @@ impl SpaceObject { angle: self.angle, mass: 0.01, size: 4.0, - sprite: images[2].clone(), + sprite: Texture2D::from_image(&images[2]), ship: None, collisions: Some(1), }); @@ -118,8 +118,9 @@ impl SpaceObject { /// Draws the object to its position on the screen. pub fn draw(&self) { + self.sprite.set_filter(FilterMode::Nearest); draw_texture_ex( - &Texture2D::from_image(&self.sprite), + &self.sprite, self.position.x - self.size / 2., self.position.y - self.size / 2., WHITE,