diff --git a/src/doodad.rs b/src/doodad.rs index e5dabc0..36ebcd0 100644 --- a/src/doodad.rs +++ b/src/doodad.rs @@ -1,19 +1,19 @@ use cgmath::{Deg, Point2}; -use crate::{physics::Pfloat, Sprite, Spriteable}; +use crate::{physics::Pfloat, render::SpriteTexture, Sprite, Spriteable}; pub struct Doodad { - pub sprite: String, + pub sprite: SpriteTexture, pub pos: Point2, pub parallax: Pfloat, pub height: Pfloat, } impl Spriteable for Doodad { - fn sprite(&self) -> Sprite { + fn get_sprite(&self) -> Sprite { return Sprite { + texture: self.sprite.clone(), pos: self.pos, - name: self.sprite.clone(), angle: Deg { 0: 0.0 }, scale: 1.0, height: self.height, diff --git a/src/main.rs b/src/main.rs index 0e86499..ff516a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,10 @@ +mod doodad; +mod inputstatus; +mod physics; +mod render; +mod ship; +mod system; + use anyhow::Result; use cgmath::{Deg, Point2}; use winit::{ @@ -9,12 +16,14 @@ use winit::{ window::WindowBuilder, }; -mod doodad; -mod inputstatus; -mod physics; -mod render; -mod ship; -mod system; +use crate::{ + doodad::Doodad, + inputstatus::InputStatus, + physics::Pfloat, + render::{GPUState, SpriteTexture}, + ship::{Ship, ShipKind}, + system::System, +}; pub const ZOOM_MIN: Pfloat = 200.0; pub const ZOOM_MAX: Pfloat = 2000.0; @@ -34,15 +43,6 @@ pub const STARFIELD_DENSITY: f64 = 0.01; // Must fit inside an i32 pub const STARFIELD_COUNT: u64 = (STARFIELD_SIZE as f64 * STARFIELD_DENSITY) as u64; -use crate::{ - doodad::Doodad, - inputstatus::InputStatus, - physics::Pfloat, - render::GPUState, - ship::{Ship, ShipKind}, - system::System, -}; - #[derive(Debug, Clone, Copy)] struct Camera { /// Camera center @@ -54,12 +54,12 @@ struct Camera { } trait Spriteable { - fn sprite(&self) -> Sprite; + fn get_sprite(&self) -> Sprite; } struct Sprite { /// Name of the sprite to draw - name: String, + texture: SpriteTexture, /// This object's position, in world coordinates. pos: Point2, @@ -143,11 +143,11 @@ impl Game { self.last_update = Instant::now(); } - fn sprites(&self) -> Vec { + fn get_sprites(&self) -> Vec { let mut sprites: Vec = Vec::new(); - sprites.append(&mut self.system.sprites()); - sprites.push(self.player.sprite()); + sprites.append(&mut self.system.get_sprites()); + sprites.push(self.player.get_sprite()); // Make sure sprites are drawn in the correct order // (note the reversed a, b in the comparator) diff --git a/src/render/gpustate.rs b/src/render/gpustate.rs index 1baceac..e5682b6 100644 --- a/src/render/gpustate.rs +++ b/src/render/gpustate.rs @@ -215,11 +215,11 @@ impl GPUState { let clip_ne = Point2::from((-self.window_aspect, 1.0)) * game.camera.zoom; let clip_sw = Point2::from((self.window_aspect, -1.0)) * game.camera.zoom; - for s in game.sprites() { + for s in game.get_sprites() { // Parallax is computed here, so we can check if this sprite is visible. let pos = (s.pos - game.camera.pos.to_vec()) / (s.parallax + game.camera.zoom / ZOOM_MIN); - let texture = self.texture_array.get_texture(&s.name[..]); + let texture = self.texture_array.get_sprite_texture(s.texture); // Game dimensions of this sprite post-scale. // Don't divide by 2, we use this later. @@ -376,7 +376,7 @@ impl GPUState { self.window_size.height as f32, ], window_aspect: [self.window_aspect, 0.0], - starfield_texture: [self.texture_array.get_starfield().index, 0], + starfield_texture: [self.texture_array.get_starfield_texture().index, 0], starfield_tile_size: [STARFIELD_SIZE as f32, 0.0], }]), ); diff --git a/src/render/mod.rs b/src/render/mod.rs index 5e56cc4..6ca52e2 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -6,6 +6,12 @@ mod vertexbuffer; pub use gpustate::GPUState; +/// A handle to a sprite texture +#[derive(Debug, Clone, Copy)] +pub struct SpriteTexture { + pub name: &'static str, +} + // API correction matrix. // cgmath uses OpenGL's matrix format, which // needs to be converted to wgpu's matrix format. diff --git a/src/render/texturearray/array.rs b/src/render/texturearray/array.rs index e0ca703..f45edda 100644 --- a/src/render/texturearray/array.rs +++ b/src/render/texturearray/array.rs @@ -2,6 +2,8 @@ use anyhow::Result; use std::{collections::HashMap, num::NonZeroU32, path::PathBuf}; use wgpu::BindGroupLayout; +use crate::render::SpriteTexture; + use super::{loader::TextureLoader, Texture, TextureArrayConfig}; pub struct TextureArray { @@ -14,11 +16,15 @@ pub struct TextureArray { impl TextureArray { const INDEX_PATH: &'static str = "assets"; - pub fn get_starfield(&self) -> Texture { + pub fn get_starfield_texture(&self) -> Texture { return self.get_texture(&self.config.starfield); } - pub fn get_texture(&self, name: &str) -> Texture { + pub fn get_sprite_texture(&self, sprite: SpriteTexture) -> Texture { + return self.get_texture(sprite.name); + } + + fn get_texture(&self, name: &str) -> Texture { match self.textures.get(name) { Some(x) => *x, None => self.get_texture(&self.config.error), diff --git a/src/ship.rs b/src/ship.rs index f87c842..a44f6b6 100644 --- a/src/ship.rs +++ b/src/ship.rs @@ -1,16 +1,18 @@ use cgmath::Point2; -use crate::{physics::Pfloat, physics::PhysBody, Sprite, Spriteable}; +use crate::{physics::Pfloat, physics::PhysBody, render::SpriteTexture, Sprite, Spriteable}; pub enum ShipKind { Gypsum, } impl ShipKind { - fn sprite(&self) -> &'static str { - match self { + fn sprite(&self) -> SpriteTexture { + let name = match self { Self::Gypsum => "ship::gypsum", - } + }; + + return SpriteTexture { name }; } fn height(&self) -> Pfloat { @@ -35,10 +37,10 @@ impl Ship { } impl Spriteable for Ship { - fn sprite(&self) -> Sprite { + fn get_sprite(&self) -> Sprite { return Sprite { pos: self.body.pos, - name: self.kind.sprite().to_owned(), + texture: self.kind.sprite(), angle: self.body.angle, scale: 1.0, parallax: 1.0, diff --git a/src/system.rs b/src/system.rs index ce337f2..adf80f1 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,5 +1,6 @@ use crate::{ physics::{Pfloat, Polar}, + render::SpriteTexture, Doodad, Sprite, Spriteable, STARFIELD_COUNT, STARFIELD_PARALLAX_MAX, STARFIELD_PARALLAX_MIN, STARFIELD_SIZE, }; @@ -48,7 +49,7 @@ impl System { s.bodies.push(Doodad { pos: (0.0, 0.0).into(), - sprite: "star::star".to_owned(), + sprite: SpriteTexture { name: "star::star" }, parallax: 10.0, height: 80.0, }); @@ -60,7 +61,9 @@ impl System { angle: Deg { 0: 31.0 }, } .to_cartesian(), - sprite: "planet::earth".to_owned(), + sprite: SpriteTexture { + name: "planet::earth", + }, parallax: 5.0, height: 120.0, }); @@ -68,7 +71,7 @@ impl System { return s; } - pub fn sprites(&self) -> Vec { - return self.bodies.iter().map(|x| x.sprite()).collect(); + pub fn get_sprites(&self) -> Vec { + return self.bodies.iter().map(|x| x.get_sprite()).collect(); } }