diff --git a/crates/comet_app/Cargo.toml b/crates/comet_app/Cargo.toml index 59bd1f5..e12cf8a 100755 --- a/crates/comet_app/Cargo.toml +++ b/crates/comet_app/Cargo.toml @@ -11,7 +11,6 @@ comet_colors = { path = "../comet_colors" } comet_log = { path = "../comet_log" } comet_input = { path = "../comet_input" } comet_structs = { path = "../comet_structs" } -comet_sound = { path = "../comet_sound" } winit = { version = "0.29", features = ["rwh_05"] } pollster = "0.3" diff --git a/crates/comet_app/src/app.rs b/crates/comet_app/src/app.rs index 14998f5..ca08f30 100755 --- a/crates/comet_app/src/app.rs +++ b/crates/comet_app/src/app.rs @@ -3,7 +3,6 @@ use comet_ecs::{Camera2D, Component, Entity, Render2D, Scene, Text, Transform2D, use comet_input::keyboard::Key; use comet_log::*; use comet_renderer::renderer::Renderer; -use comet_sound::*; use std::any::{type_name, Any, TypeId}; use std::sync::Arc; use winit::dpi::LogicalSize; @@ -31,7 +30,6 @@ pub struct App { delta_time: f32, update_timer: f32, game_state: Option>, - audio: Box, scene: Scene, fullscreen: bool, should_quit: bool, @@ -49,7 +47,6 @@ impl App { delta_time: 0.0, update_timer: 0.0166667, game_state: None, - audio: Box::new(KiraAudio::new()), scene: Scene::new(), fullscreen: false, should_quit: false, @@ -139,11 +136,6 @@ impl App { &self.scene } - /// Retrieves a mutable reference to the current `Scene` in the `App` - pub fn scene_mut(&mut self) -> &mut Scene { - &mut self.scene - } - /// Retrieves a reference to the `InputManager`. pub fn input_manager(&self) -> &InputManager { &self.input_manager @@ -254,38 +246,6 @@ impl App { self.scene.has_prefab(name) } - pub fn load_audio(&mut self, name: &str, path: &str) { - self.audio.load(name, path); - } - - pub fn play_audio(&mut self, name: &str, looped: bool) { - self.audio.play(name, looped); - } - - pub fn pause_audio(&mut self, name: &str) { - self.audio.pause(name); - } - - pub fn stop_audio(&mut self, name: &str) { - self.audio.stop(name); - } - - pub fn stop_all_audio(&mut self) { - self.audio.stop_all(); - } - - pub fn update_audio(&mut self, dt: f32) { - self.audio.update(dt); - } - - pub fn is_playing(&self, name: &str) -> bool { - self.audio.is_playing(name) - } - - pub fn set_volume(&mut self, name: &str, volume: f32) { - self.audio.set_volume(name, volume); - } - /// Stops the event loop and with that quits the `App`. pub fn quit(&mut self) { self.should_quit = true; @@ -381,9 +341,6 @@ impl App { WindowEvent::Resized(physical_size) => { renderer.resize(*physical_size); } - WindowEvent::ScaleFactorChanged { scale_factor, .. } => { - renderer.set_scale_factor(*scale_factor); - } WindowEvent::RedrawRequested => { window.request_redraw(); match renderer.render() { diff --git a/crates/comet_ecs/src/component.rs b/crates/comet_ecs/src/component.rs index 53e958f..39b87c7 100755 --- a/crates/comet_ecs/src/component.rs +++ b/crates/comet_ecs/src/component.rs @@ -2,7 +2,6 @@ // You can use these components as is or as a reference to create your own components // Also just as a nomenclature: bundles are a component made up of multiple components, // so it's a collection of components bundled together (like Transform2D) -// They are intended to work with the base suite of systems provided by the engine. use crate::math::{v2, v3}; use crate::{Entity, Scene}; use comet_colors::Color as ColorTrait; @@ -46,7 +45,6 @@ pub struct Render2D { is_visible: bool, texture_name: &'static str, scale: v2, - draw_index: u32, } #[derive(Component)] @@ -63,7 +61,6 @@ pub struct Text { font_size: f32, color: Color, is_visible: bool, - bounds: v2, } #[derive(Component)] @@ -81,15 +78,6 @@ pub struct Timer { done: bool, } -#[derive(Component)] -pub struct AudioSource { - name: &'static str, - path: Option<&'static str>, - looped: bool, - volume: f32, - pitch: f32, -} - // ################################################## // # BUNDLES # // ################################################## @@ -276,39 +264,13 @@ impl Collider for Rectangle2D { } impl Render2D { - pub fn new(texture: &'static str, is_visible: bool, scale: v2, draw_index: u32) -> Self { - Self { - is_visible, - texture_name: texture, - scale, - draw_index, - } - } - pub fn with_texture(texture: &'static str) -> Self { Self { is_visible: true, texture_name: texture, scale: v2::new(1.0, 1.0), - draw_index: 0, } } - - pub fn scale(&self) -> v2 { - self.scale - } - - pub fn set_scale(&mut self, scale: v2) { - self.scale = scale; - } - - pub fn draw_index(&self) -> u32 { - self.draw_index - } - - pub fn set_draw_index(&mut self, index: u32) { - self.draw_index = index - } } impl Render for Render2D { @@ -469,7 +431,6 @@ impl Text { font_size, color: Color::from_wgpu_color(color.to_wgpu()), is_visible, - bounds: v2::ZERO, } } @@ -508,14 +469,6 @@ impl Text { pub fn is_visible(&self) -> bool { self.is_visible } - - pub fn bounds(&self) -> v2 { - self.bounds - } - - pub fn set_bounds(&mut self, bounds: v2) { - self.bounds = bounds - } } impl Color { @@ -595,47 +548,3 @@ impl Timer { self.done = false; } } - -impl AudioSource { - pub fn new(name: &'static str, path: Option<&'static str>) -> Self { - Self { - name, - path, - looped: false, - volume: 1.0, - pitch: 1.0, - } - } - - pub fn name(&self) -> &str { - self.name - } - - pub fn path(&self) -> Option<&str> { - self.path - } - - pub fn looped(&self) -> bool { - self.looped - } - - pub fn volume(&self) -> f32 { - self.volume - } - - pub fn pitch(&self) -> f32 { - self.pitch - } - - pub fn set_looped(&mut self, looped: bool) { - self.looped = looped; - } - - pub fn set_volume(&mut self, volume: f32) { - self.volume = volume.clamp(0.0, 1.0); - } - - pub fn set_pitch(&mut self, pitch: f32) { - self.pitch = pitch; - } -} diff --git a/crates/comet_renderer/src/renderer.rs b/crates/comet_renderer/src/renderer.rs index 6e3a4ad..a44b3c3 100644 --- a/crates/comet_renderer/src/renderer.rs +++ b/crates/comet_renderer/src/renderer.rs @@ -1,15 +1,12 @@ -use comet_colors::Color; use std::sync::Arc; use winit::dpi::PhysicalSize; use winit::window::Window; +use comet_colors::Color; pub trait Renderer: Sized + Send + Sync { - fn new(window: Arc, clear_color: Option) -> Self; - fn size(&self) -> PhysicalSize; - fn resize(&mut self, new_size: winit::dpi::PhysicalSize); - fn scale_factor(&self) -> f64; - fn set_scale_factor(&mut self, scale_factor: f64); - fn update(&mut self) -> f32; - fn render(&mut self) -> Result<(), wgpu::SurfaceError>; -} - + fn new(window: Arc, clear_color: Option) -> Self; + fn size(&self) -> PhysicalSize; + fn resize(&mut self, new_size: winit::dpi::PhysicalSize); + fn update(&mut self) -> f32; + fn render(&mut self) -> Result<(), wgpu::SurfaceError>; +} \ No newline at end of file diff --git a/crates/comet_renderer/src/renderer2d.rs b/crates/comet_renderer/src/renderer2d.rs index 93b78f5..2450d74 100755 --- a/crates/comet_renderer/src/renderer2d.rs +++ b/crates/comet_renderer/src/renderer2d.rs @@ -26,7 +26,6 @@ pub struct Renderer2D<'a> { queue: wgpu::Queue, config: wgpu::SurfaceConfiguration, size: PhysicalSize, - scale_factor: f64, universal_render_pipeline: wgpu::RenderPipeline, texture_bind_group_layout: wgpu::BindGroupLayout, texture_sampler: wgpu::Sampler, @@ -44,7 +43,6 @@ pub struct Renderer2D<'a> { impl<'a> Renderer2D<'a> { pub fn new(window: Arc, clear_color: Option) -> Renderer2D<'a> { let size = window.inner_size(); //PhysicalSize::::new(1920, 1080); - let scale_factor = window.scale_factor(); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::PRIMARY, @@ -260,7 +258,6 @@ impl<'a> Renderer2D<'a> { queue, config, size, - scale_factor, universal_render_pipeline, texture_bind_group_layout, texture_sampler, @@ -297,14 +294,6 @@ impl<'a> Renderer2D<'a> { } } - pub fn scale_factor(&self) -> f64 { - self.scale_factor - } - - pub fn set_scale_factor(&mut self, scale_factor: f64) { - self.scale_factor = scale_factor - } - pub fn add_draw_call(&mut self, draw_call: String, texture: Texture) { let draw_info = DrawInfo::new( draw_call, @@ -494,7 +483,6 @@ impl<'a> Renderer2D<'a> { size: f32, position: p2, color: wgpu::Color, - bounds: &mut v2, ) -> (Vec, Vec) { let vert_color = [ color.r as f32, @@ -507,18 +495,24 @@ impl<'a> Renderer2D<'a> { position.x() / self.config.width as f32, position.y() / self.config.height as f32, ); + let scale_factor = size + / self + .graphic_resource_manager + .fonts() + .iter() + .find(|f| f.name() == font) + .unwrap() + .size(); - let font_data = self + let line_height = (self .graphic_resource_manager .fonts() .iter() .find(|f| f.name() == font) - .unwrap(); - - let scale_factor = size / font_data.size(); - - let line_height = (font_data.line_height() / self.config.height as f32) * scale_factor; - + .unwrap() + .line_height() + / self.config.height as f32) + * scale_factor; let lines = text .split("\n") .map(|s| { @@ -531,27 +525,9 @@ impl<'a> Renderer2D<'a> { }) .collect::>(); - let mut max_line_width_px = 0.0; - let mut total_height_px = 0.0; - - for line in &lines { - let mut line_width_px = 0.0; - for c in line.chars() { - if let Some(region) = font_data.get_glyph(c) { - line_width_px += region.advance(); - } - } - if line_width_px > max_line_width_px { - max_line_width_px = line_width_px; - } - total_height_px += font_data.line_height(); - } - - bounds.set_x((max_line_width_px / self.config.width as f32) * scale_factor); - bounds.set_y((total_height_px / self.config.height as f32) * scale_factor); - let mut x_offset = 0.0; let mut y_offset = 0.0; + let mut vertex_data = Vec::new(); let mut index_data = Vec::new(); @@ -703,22 +679,14 @@ impl<'a> Renderer2D<'a> { /// A function to automatically render all the entities of the `Scene` struct. /// The entities must have the `Render2D` and `Transform2D` components to be rendered as well as set visible. - pub fn render_scene_2d(&mut self, scene: &mut Scene) { + pub fn render_scene_2d(&mut self, scene: &Scene) { let cameras = scene.get_entities_with(vec![Transform2D::type_id(), Camera2D::type_id()]); if cameras.is_empty() { return; } - let mut entities = - scene.get_entities_with(vec![Transform2D::type_id(), Render2D::type_id()]); - - entities.sort_by(|&a, &b| { - let ra = scene.get_component::(a).unwrap(); - let rb = scene.get_component::(b).unwrap(); - ra.draw_index().cmp(&rb.draw_index()) - }); - + let entities = scene.get_entities_with(vec![Transform2D::type_id(), Render2D::type_id()]); let texts = scene.get_entities_with(vec![Transform2D::type_id(), comet_ecs::Text::type_id()]); @@ -745,9 +713,8 @@ impl<'a> Renderer2D<'a> { let region = t_region.unwrap(); let (dim_x, dim_y) = region.dimensions(); - let scale = renderer_component.scale(); - let half_width = dim_x as f32 * 0.5 * scale.x(); - let half_height = dim_y as f32 * 0.5 * scale.y(); + let half_width = dim_x as f32 * 0.5; + let half_height = dim_y as f32 * 0.5; let buffer_size = vertex_buffer.len() as u16; @@ -813,36 +780,24 @@ impl<'a> Renderer2D<'a> { } for text in texts { - if let Some(component) = scene.get_component_mut::(text) { - if component.is_visible() { - let font = component.font().to_string(); - let size = component.font_size(); - let color = component.color().to_wgpu(); - let content = component.content().to_string(); + let component = scene.get_component::(text).unwrap(); + let transform = scene.get_component::(text).unwrap(); - let transform = scene.get_component::(text).unwrap(); - - let mut bounds = v2::ZERO; - let (vertices, indices) = self.add_text_to_buffers( - content, - font.clone(), - size, - p2::from_vec(transform.position().as_vec()), - color, - &mut bounds, - ); - - let component = scene.get_component_mut::(text).unwrap(); - component.set_bounds(bounds); - - let draw = self - .draw_info - .iter_mut() - .find(|d| d.name() == &format!("{}", font)) - .unwrap(); - draw.update_vertex_buffer(&self.device, &self.queue, vertices); - draw.update_index_buffer(&self.device, &self.queue, indices); - } + if component.is_visible() { + let (vertices, indices) = self.add_text_to_buffers( + component.content().to_string(), + component.font().to_string(), + component.font_size(), + p2::from_vec(transform.position().as_vec()), + component.color().to_wgpu(), + ); + let draw = self + .draw_info + .iter_mut() + .find(|d| d.name() == &format!("{}", component.font())) + .unwrap(); + draw.update_vertex_buffer(&self.device, &self.queue, vertices); + draw.update_index_buffer(&self.device, &self.queue, indices); } } @@ -930,14 +885,6 @@ impl<'a> Renderer for Renderer2D<'a> { self.resize(new_size) } - fn scale_factor(&self) -> f64 { - self.scale_factor() - } - - fn set_scale_factor(&mut self, scale_factor: f64) { - self.set_scale_factor(scale_factor); - } - fn update(&mut self) -> f32 { self.update() } diff --git a/crates/comet_sound/Cargo.toml b/crates/comet_sound/Cargo.toml index 5894411..a2d1566 100644 --- a/crates/comet_sound/Cargo.toml +++ b/crates/comet_sound/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -kira = "0.10.8" +rodio = "0.12.0" \ No newline at end of file diff --git a/crates/comet_sound/src/audio.rs b/crates/comet_sound/src/audio.rs deleted file mode 100644 index 772dff1..0000000 --- a/crates/comet_sound/src/audio.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub trait Audio { - fn new() -> Self - where - Self: Sized; - fn load(&mut self, name: &str, path: &str); - fn play(&mut self, name: &str, looped: bool); - fn pause(&mut self, name: &str); - fn stop(&mut self, name: &str); - fn stop_all(&mut self); - fn update(&mut self, dt: f32); - fn is_playing(&self, name: &str) -> bool; - fn set_volume(&mut self, name: &str, volume: f32); -} diff --git a/crates/comet_sound/src/kira.rs b/crates/comet_sound/src/kira.rs deleted file mode 100644 index bfbf09b..0000000 --- a/crates/comet_sound/src/kira.rs +++ /dev/null @@ -1,86 +0,0 @@ -use crate::audio::Audio; -use kira::{ - sound::static_sound::{StaticSoundData, StaticSoundHandle, StaticSoundSettings}, - AudioManager, AudioManagerSettings, Decibels, Tween, -}; -use std::{collections::HashMap, path::Path}; - -pub struct KiraAudio { - manager: AudioManager, - sounds: HashMap, - handles: HashMap, -} - -impl KiraAudio { - fn load_sound(path: &Path) -> Option { - StaticSoundData::from_file(path).ok() - } -} - -impl Audio for KiraAudio { - fn new() -> Self { - Self { - manager: AudioManager::new(AudioManagerSettings::default()).unwrap(), - sounds: HashMap::new(), - handles: HashMap::new(), - } - } - - fn load(&mut self, name: &str, path: &str) { - if let Some(sound) = Self::load_sound(Path::new(path)) { - self.sounds.insert(name.to_string(), sound); - } - } - - fn play(&mut self, name: &str, looped: bool) { - if let Some(sound) = self.sounds.get(name) { - let mut settings = StaticSoundSettings::default(); - - if looped { - settings = settings.loop_region(..); - } - - if let Ok(handle) = self.manager.play(sound.clone().with_settings(settings)) { - self.handles.insert(name.to_string(), handle); - } - } - } - - fn pause(&mut self, name: &str) { - if let Some(handle) = self.handles.get_mut(name) { - handle.pause(Tween::default()); - } - } - - fn stop(&mut self, name: &str) { - if let Some(handle) = self.handles.get_mut(name) { - handle.stop(Tween::default()); - } - } - - fn stop_all(&mut self) { - for handle in self.handles.values_mut() { - handle.stop(Tween::default()); - } - } - - // KiraAudio needs no updating function, it just exists to make the trait happy - fn update(&mut self, _dt: f32) {} - - fn is_playing(&self, name: &str) -> bool { - self.handles.contains_key(name) - } - - fn set_volume(&mut self, name: &str, volume: f32) { - let vol = volume.clamp(0.0, 1.0); - let db = if vol == 0.0 { - Decibels::from(-80.0) // effectively silent - } else { - Decibels::from(20.0 * vol.log10()) - }; - - if let Some(handle) = self.handles.get_mut(name) { - handle.set_volume(db, Tween::default()); - } - } -} diff --git a/crates/comet_sound/src/lib.rs b/crates/comet_sound/src/lib.rs deleted file mode 100644 index fc49c59..0000000 --- a/crates/comet_sound/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod audio; -mod kira; - -pub use audio::Audio; -pub use kira::KiraAudio; \ No newline at end of file diff --git a/crates/comet_sound/src/main.rs b/crates/comet_sound/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/crates/comet_sound/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/examples/simple_move_2d.rs b/examples/simple_move_2d.rs index ecf3c74..9aaa49b 100644 --- a/examples/simple_move_2d.rs +++ b/examples/simple_move_2d.rs @@ -14,7 +14,9 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) { app.add_component(e1, Transform2D::new()); - let mut renderer2d = Render2D::with_texture("res/textures/comet_icon.png"); + let mut renderer2d = Render2D::new(); + renderer2d.set_texture(r"res/textures/comet_icon.png"); + renderer2d.set_visibility(true); app.add_component(e1, renderer2d); } @@ -22,7 +24,7 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) { fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) { handle_input(app, dt); - renderer.render_scene_2d(app.scene_mut()); + renderer.render_scene_2d(app.scene()); } fn handle_input(app: &mut App, dt: f32) { diff --git a/examples/simple_text.rs b/examples/simple_text.rs index 4821ad8..fd88244 100644 --- a/examples/simple_text.rs +++ b/examples/simple_text.rs @@ -34,7 +34,7 @@ fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) { transform.position_mut().set_x(-((size.width - 50) as f32)); transform.position_mut().set_y((size.height - 100) as f32); - renderer.render_scene_2d(app.scene_mut()); + renderer.render_scene_2d(app.scene()); } fn main() { diff --git a/examples/textured_entity.rs b/examples/textured_entity.rs index e4bd86b..633ebe2 100644 --- a/examples/textured_entity.rs +++ b/examples/textured_entity.rs @@ -13,13 +13,15 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) { let e0 = app.new_entity(); app.add_component(e0, Transform2D::new()); - let render = Render2D::with_texture("res/textures/comet_icon.png"); + let mut render = Render2D::new(); + render.set_visibility(true); + render.set_texture("./res/textures/comet_icon.png"); app.add_component(e0, render); } fn update(app: &mut App, renderer: &mut Renderer2D, dt: f32) { - renderer.render_scene_2d(app.scene_mut()) + renderer.render_scene_2d(app.scene()) } fn main() { diff --git a/goals.md b/goals.md deleted file mode 100644 index 630f94c..0000000 --- a/goals.md +++ /dev/null @@ -1,31 +0,0 @@ -# Goals of the Comet Game Engine - -Comet should be an unopinionated game engine built in Rust that tries to -combine the simplicity of Raylib and modularity of Bevy without the user -needing to become a follower of a cult. - -The engine itself should be expandable and swappable in its components. -Don't like the standard 2D renderer? Just make your own, implement the -`Renderer` trait and use it instead of the provided one. - -If you really don't want to work with the ECS, just ignore it and add -your own custom `GameState` (or whatever you want to call it) struct -and work on it using the tools provided to you by the engine. - -These things should be provided for an official 1.0 version of Comet: - -- [x] 2D rendering -- [ ] 3D rendering -- [ ] UI system -- [ ] particle system -- [x] ECS -- [x] sound system -- [ ] simple physics engine -- [ ] multiple scenes (aka serialization and deserialization) -- [ ] extensive documentation - -Future endeavors might include: - -- [ ] project creation tool -- [ ] editor -- [ ] scripting using Rhai