diff --git a/crates/comet_app/Cargo.toml b/crates/comet_app/Cargo.toml index 3f4a110..6e0d8e0 100644 --- a/crates/comet_app/Cargo.toml +++ b/crates/comet_app/Cargo.toml @@ -8,6 +8,7 @@ comet_ecs = { path = "../comet_ecs" } comet_renderer = { path = "../comet_renderer" } comet_resources = { path = "../comet_resources" } comet_colors = { path = "../comet_colors" } +comet_log = { path = "../comet_log" } winit = { version = "0.29", features = ["rwh_05"] } env_logger = "0.10" @@ -16,6 +17,7 @@ wgpu = { version = "22.0"} log = "0.4.22" anyhow = "1.0.89" bytemuck = "1.18.0" +chrono = "0.4.0" [dependencies.image] version = "0.24" diff --git a/crates/comet_app/src/app.rs b/crates/comet_app/src/app.rs index 3778689..e795330 100644 --- a/crates/comet_app/src/app.rs +++ b/crates/comet_app/src/app.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use comet_ecs::World; -use comet_resources::ResourceManager; +use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D, World}; +use comet_resources::{ResourceManager, Vertex}; use comet_renderer::{Renderer}; use winit::{ @@ -11,7 +11,7 @@ use winit::{ }; use comet_colors::LinearRgba; use comet_ecs::math::Point3; -use log::warn; +use comet_log::*; use winit::dpi::{LogicalSize, PhysicalSize}; pub enum ApplicationType { @@ -74,6 +74,51 @@ impl<'a> App<'a> { Some(Icon::from_rgba(rgba_image.into_raw(), width, height).unwrap()) } + pub fn render_scene_2d(&self, renderer: &mut Renderer) { + let entities = self.world.get_entities_with(ComponentSet::from_ids(vec![Renderer2D::type_id()])); + let mut vertex_buffer: Vec = Vec::new(); + let mut index_buffer: Vec = Vec::new(); + + for entity in entities { + let renderer_component = self.world().get_component::(entity as usize); + let transform_component = self.world().get_component::(entity as usize); + + if renderer_component.is_visible() { + //renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(transform_component.position().x(), transform_component.position().y(), 0.0)); + let position = transform_component.position(); + let region = renderer.get_texture(renderer_component.get_texture().to_string()); + let (dim_x, dim_y) = region.dimensions(); + + let (bound_x, bound_y) = + ((dim_x as f32/ renderer.config().width as f32) * 0.5, (dim_y as f32/ renderer.config().height as f32) * 0.5); + + let buffer_size = vertex_buffer.len() as u16; + + vertex_buffer.append(&mut vec![ + Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0], [region.x0(), region.y0()] ), + Vertex :: new ( [-bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x0(), region.y1()] ), + Vertex :: new ( [ bound_x + position.x(), -bound_y + position.y(), 0.0], [region.x1(), region.y1()] ) , + Vertex :: new ( [ bound_x + position.x(), bound_y + position.y(), 0.0], [region.x1(), region.y0()] ) + ]); + + index_buffer.append(&mut vec![ + 0 + buffer_size, 1 + buffer_size, 3 + buffer_size, + 1 + buffer_size, 2 + buffer_size, 3 + buffer_size + ]); + } + } + + renderer.set_buffers(vertex_buffer, index_buffer); + + /*for entity in entities { + let renderer_component = self.world.get_component::(entity as usize); + let position_component = self.world.get_component::(entity as usize); + if renderer_component.is_visible() { + renderer.draw_texture_at(renderer_component.get_texture(), Point3::new(position_component.position().x(), position_component.position().y(), 0.0)); + } + }*/ + } + pub fn world(&self) -> &World { &self.world } @@ -116,12 +161,14 @@ impl<'a> App<'a> { window.set_maximized(true); + renderer.initialize_atlas(); + event_loop.run(|event, control_flow| { if self.should_quit { control_flow.exit() } - game_manager(&mut self.world, &mut renderer); + self.render_scene_2d(&mut renderer); match event { Event::WindowEvent { @@ -161,7 +208,9 @@ impl<'a> App<'a> { } } } - _ => { input_manager(event, &mut self, &mut renderer) } + _ => { + input_manager(event, &mut self, &mut renderer); + } } } _ => {} diff --git a/crates/comet_ecs/Cargo.toml b/crates/comet_ecs/Cargo.toml index 36cd445..b73c105 100644 --- a/crates/comet_ecs/Cargo.toml +++ b/crates/comet_ecs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "comet_ecs" -version = "0.1.0" +version = "0.2.0" edition = "2021" [dependencies] diff --git a/crates/comet_ecs/component_derive/src/lib.rs b/crates/comet_ecs/component_derive/src/lib.rs index fd9fa0a..cd4c2d3 100644 --- a/crates/comet_ecs/component_derive/src/lib.rs +++ b/crates/comet_ecs/component_derive/src/lib.rs @@ -12,6 +12,7 @@ pub fn my_trait_derive(input: TokenStream) -> TokenStream { // Get the name of the struct let name = &input.ident; + let name = &input.ident; let fields = if let Data::Struct(data) = &input.data { match &data.fields { diff --git a/crates/comet_ecs/src/component.rs b/crates/comet_ecs/src/component.rs index 9401547..3ac9e59 100644 --- a/crates/comet_ecs/src/component.rs +++ b/crates/comet_ecs/src/component.rs @@ -1,4 +1,4 @@ -use std::path::Path; +//use comet_resources::Vertex; use crate::math::{ Vec2, Vec3 @@ -23,15 +23,12 @@ pub trait Component: Send + Sync + PartialEq + Default + 'static { #[derive(Component)] pub struct Position2D { - x: f32, - y: f32 + position: Vec2 } #[derive(Component)] pub struct Position3D { - x: f32, - y: f32, - z: f32 + position: Vec3 } #[derive(Component)] @@ -50,83 +47,111 @@ pub struct Rotation3D { pub struct Renderer2D { is_visible: bool, texture: &'static str, - scale: f32 + scale: Vec2 } impl Position2D { pub fn from_vec(vec: Vec2) -> Self { Self { - x: vec.x(), - y: vec.y() + position: vec } } pub fn as_vec(&self) -> Vec2 { - Vec2::new( - self.x, - self.y - ) + self.position } - pub fn x(&self) -> &f32 { - &self.x + pub fn x(&self) -> f32 { + self.position.x() } - pub fn y(&self) -> &f32 { - &self.y + pub fn y(&self) -> f32 { + self.position.y() } pub fn set_x(&mut self, new_x: f32) { - self.x = new_x; + self.position.set_x(new_x); } pub fn set_y(&mut self, new_y: f32) { - self.y = new_y; + self.position.set_y(new_y); } } impl Position3D { pub fn from_vec(vec: Vec3) -> Self { Self { - x: vec.x(), - y: vec.y(), - z: vec.z() + position: vec } } pub fn as_vec(&self) -> Vec3 { - Vec3::new( - self.x, - self.y, - self.z - ) + self.position } - pub fn x(&self) -> &f32 { - &self.x + pub fn x(&self) -> f32 { + self.position.x() } - pub fn y(&self) -> &f32 { - &self.y + pub fn y(&self) -> f32 { + self.position.y() } - pub fn z(&self) -> &f32 { - &self.z + pub fn z(&self) -> f32 { + self.position.z() } pub fn set_x(&mut self, new_x: f32) { - self.x = new_x; + self.position.set_x(new_x); } pub fn set_y(&mut self, new_y: f32) { - self.y = new_y; + self.position.set_y(new_y); } pub fn set_z(&mut self, new_z: f32) { - self.z = new_z + self.position.set_z(new_z); } } +pub trait Render { + fn is_visible(&self) -> bool; + fn set_visibility(&mut self, is_visible: bool); + fn get_texture(&self) -> String; + fn set_texture(&mut self, texture: &'static str); + //fn get_vertex_data(&self) -> Vec; +} + +impl Render for Renderer2D { + fn is_visible(&self) -> bool { + self.is_visible + } + + fn set_visibility(&mut self, is_visible: bool) { + self.is_visible = is_visible; + } + + fn get_texture(&self) -> String { + self.texture.clone().parse().unwrap() + } + + /// Use the actual file name of the texture instead of the path + /// e.g. "comet_icon.png" instead of "resources/textures/comet_icon.png" + /// The resource manager will already look in the resources/textures folder + fn set_texture(&mut self, texture: &'static str) { + self.texture = texture; + } + + /*fn get_vertex_data(&self) -> Vec { + vec![ + Vertex::new([0.0, 0.0, 0.0], [0.0, 0.0]), + Vertex::new([1.0, 0.0, 0.0], [1.0, 0.0]), + Vertex::new([1.0, 1.0, 0.0], [1.0, 1.0]), + Vertex::new([0.0, 1.0, 0.0], [0.0, 1.0]) + ] + }*/ +} + // ################################################## // # BUNDLES # // ################################################## diff --git a/crates/comet_ecs/src/storage.rs b/crates/comet_ecs/src/storage.rs index cbf06e7..6cd707c 100644 --- a/crates/comet_ecs/src/storage.rs +++ b/crates/comet_ecs/src/storage.rs @@ -411,6 +411,17 @@ impl ComponentStorage { self.keys.contains(type_id) } + pub fn contains_components(&self, component_set: ComponentSet) -> bool { + let mut contains = true; + for type_id in component_set.set.iter() { + if !self.keys.contains(type_id) { + contains = false; + break; + } + } + contains + } + pub fn get(&self) -> Option<&SparseSet> { self.components.get(*self.index_map.get(&T::type_id()).unwrap()) } diff --git a/crates/comet_ecs/src/world.rs b/crates/comet_ecs/src/world.rs index 4da1a5e..edac407 100644 --- a/crates/comet_ecs/src/world.rs +++ b/crates/comet_ecs/src/world.rs @@ -125,6 +125,25 @@ impl World { self.archetypes.create_archetype(components); } + fn remove_archetype(&mut self, components: ComponentSet) { + self.archetypes.remove_archetype(&components); + } + + fn remove_archetype_subsets(&mut self, components: ComponentSet) { + let component_sets = self.archetypes.component_sets(); + let keys: Vec = component_sets.iter() + .enumerate() + .filter_map(|(i, &ref elem)| if elem.is_subset(&components) { Some(i) } else { None }) + .collect::>() + .iter() + .map(|index| component_sets[*index].clone()) + .collect::>(); + + for key in keys { + self.remove_archetype(key.clone()); + } + } + fn add_entity_to_archetype(&mut self, entity_id: u32, components: ComponentSet) { self.archetypes.add_entity_to_archetype(&components, entity_id); } @@ -159,6 +178,7 @@ impl World { pub fn register_component(&mut self) { self.components.register_component::(self.entities.len()); + self.create_archetype(ComponentSet::from_ids(vec![T::type_id()])); info!(format!("Registered component: {}", T::type_name())); } @@ -177,8 +197,10 @@ impl World { if !self.archetypes.contains_archetype(&self.get_component_set(entity_id)) { self.create_archetype(self.get_component_set(entity_id)); } - self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id)); - + self.add_entity_to_archetype(entity_id as u32, ComponentSet::from_ids(vec![T::type_id()])); + if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![T::type_id()]) { + self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id)); + } info!(format!("Added component {} to entity {}", T::type_name(), entity_id)); debug!(format!("{:?}", self.archetypes)); } @@ -191,7 +213,7 @@ impl World { pub fn get_component(&self, entity_id: usize) -> &T { assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id); - assert!(self.components.get_component::(entity_id) != None, "There is no component {} bound to the entity {} in the world!", T::type_name(), entity_id); + //assert_ne!(self.components.get_component::(entity_id), None, "There is no component {} bound to the entity {} in the world!", T::type_name(), entity_id); self.components.get_component::(entity_id).unwrap() } @@ -203,7 +225,7 @@ impl World { pub fn get_entities_with(&self, components: ComponentSet) -> Vec { assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components); - info!(format!("Querying entities with components: {:?}", components)); + //debug!(format!("Querying entities with components: {:?}", components)); self.archetypes.get_archetype(&components).unwrap().clone() } } diff --git a/crates/comet_math/src/vector.rs b/crates/comet_math/src/vector.rs index 68073c3..556bd0a 100644 --- a/crates/comet_math/src/vector.rs +++ b/crates/comet_math/src/vector.rs @@ -15,7 +15,7 @@ pub trait InnerSpace { /// Representation of a 2D Vector #[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Vec2 { x: f32, @@ -43,6 +43,14 @@ impl Vec2 { self.y } + pub fn set_x(&mut self, new_x: f32) { + self.x = new_x; + } + + pub fn set_y(&mut self, new_y: f32) { + self.y = new_y; + } + pub fn length(&self) -> f32 { (self.x * self.x + self.y * self.y).sqrt() } @@ -123,7 +131,7 @@ impl Mul for Vec2 { /// Representation of a 3D Vector #[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Vec3 { pub x: f32, @@ -161,6 +169,18 @@ impl Vec3 { self.z } + pub fn set_x(&mut self, new_x: f32) { + self.x = new_x; + } + + pub fn set_y(&mut self, new_y: f32) { + self.y = new_y; + } + + pub fn set_z(&mut self, new_z: f32) { + self.z = new_z; + } + pub fn into_quaternion(&self) -> Quat { Quat { s: 0.0, @@ -418,7 +438,7 @@ impl Mul for Vec3 { /// Representation of a 4D Vector #[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Vec4 { x: f32, @@ -469,6 +489,22 @@ impl Vec4 { self.w } + pub fn set_x(&mut self, new_x: f32) { + self.x = new_x; + } + + pub fn set_y(&mut self, new_y: f32) { + self.y = new_y; + } + + pub fn set_z(&mut self, new_z: f32) { + self.z = new_z; + } + + pub fn set_w(&mut self, new_w: f32) { + self.w = new_w; + } + pub fn xxxx(&self) -> Vec4 { Vec4 { x: self.x, diff --git a/crates/comet_renderer/Cargo.toml b/crates/comet_renderer/Cargo.toml index 8d7c855..dbefacd 100644 --- a/crates/comet_renderer/Cargo.toml +++ b/crates/comet_renderer/Cargo.toml @@ -20,6 +20,7 @@ tobj = { version = "3.2", default-features = false, features = ["async"]} wgpu = { version = "22.0"} winit = { version = "0.29", features = ["rwh_05"] } instant = "0.1" +chrono = "0.4.0" [dependencies.image] version = "0.24" diff --git a/crates/comet_renderer/src/lib.rs b/crates/comet_renderer/src/lib.rs index 0696fe5..d7a4df1 100644 --- a/crates/comet_renderer/src/lib.rs +++ b/crates/comet_renderer/src/lib.rs @@ -2,6 +2,7 @@ mod camera; use core::default::Default; use std::iter; +use std::path::PathBuf; use std::sync::Arc; use std::time::Instant; use cgmath::num_traits::FloatConst; @@ -13,67 +14,14 @@ use winit::{ dpi::PhysicalSize, window::Window }; +use winit::dpi::Position; use comet_colors::LinearRgba; +use comet_log::error; use comet_math; use comet_math::{Mat4, Point3, Vec3}; use comet_resources::{ResourceManager, texture, Vertex, Texture}; +use comet_resources::texture_atlas::TextureRegion; use crate::camera::{Camera, CameraUniform}; -// RAINBOW TRIANGLE -/*const VERTICES: &[Vertex] = &[ - Vertex :: new ( [0.0, 0.5, 0.0], [1.0, 0.0, 0.0] ), - Vertex :: new ( [-0.5, -0.5, 0.0], [0.0, 1.0, 0.0] ), - Vertex :: new ( [0.5, -0.5, 0.0], [0.0, 0.0, 1.0] ), -];*/ - -// RAW PENTAGON -/*const VERTICES: &[Vertex] = &[ - Vertex :: new ( [-0.0868241, 0.49240386, 0.0], [0.5, 0.0, 0.5] ), // A - Vertex :: new ( [-0.49513406, 0.06958647, 0.0], [0.5, 0.0, 0.5] ), // B - Vertex :: new ( [-0.21918549, -0.44939706, 0.0], [0.5, 0.0, 0.5] ), // C - Vertex :: new ( [0.35966998, -0.3473291, 0.0], [0.5, 0.0, 0.5] ), // D - Vertex :: new ( [0.44147372, 0.2347359, 0.0], [0.5, 0.0, 0.5] ), // E -];*/ - -// RAINBOW PENTAGON -/*const VERTICES: &[Vertex] = &[ - Vertex :: new ( [-0.0868241, 0.49240386, 0.0], [1.0, 0.0, 0.0] ), // A - Vertex :: new ( [-0.49513406, 0.06958647, 0.0], [0.0, 0.35, 1.0] ), // B - Vertex :: new ( [-0.21918549, -0.44939706, 0.0], [0.2, 1.0, 0.2] ), // C - Vertex :: new ( [0.35966998, -0.3473291, 0.0], [1.0, 0.85, 0.2] ), // D - Vertex :: new ( [0.44147372, 0.2347359, 0.0], [1.0, 0.2, 0.6] ), // E -]; - -const INDICES: &[u16] = &[ - 0, 1, 4, - 1, 2, 4, - 2, 3, 4, -];*/ - -// RAW QUAD -/*const VERTICES: &[Vertex] = &[ - Vertex :: new ( [-0.5, 0.5, 0.0], [0.0, 0.0, 1.0] ), - Vertex :: new ( [-0.5, -0.5, 0.0], [0.0, 1.0, 0.0] ), - Vertex :: new ( [0.5, -0.5, 0.0], [1.0, 0.0, 0.0] ), - Vertex :: new ( [0.5, 0.5, 0.0], [1.0, 0.0, 1.0] ) -]; - -const INDICES: &[u16] = &[ - 0, 1, 3, - 1, 2, 3 -];*/ - - -/* -vec![ - Vertex :: new ( [-0.1, 0.1, 0.0], [0.0, 0.0] ), - Vertex :: new ( [-0.1, -0.1, 0.0], [0.0, 1.0] ), - Vertex :: new ( [0.1, -0.1, 0.0], [1.0, 1.0] ), - Vertex :: new ( [0.1, 0.1, 0.0], [1.0, 0.0] ), - ], vec![ - 0, 1, 3, - 1, 2, 3 - ] -*/ pub struct Projection { aspect: f32, @@ -410,6 +358,10 @@ impl<'a> Renderer<'a> { self.deltatime } + pub fn config(&self) -> &wgpu::SurfaceConfiguration { + &self.config + } + fn vertex_data_mut(&mut self) -> &mut Vec { &mut self.vertex_data } @@ -418,6 +370,11 @@ impl<'a> Renderer<'a> { &mut self.index_data } + pub fn get_texture(&self, texture_path: String) -> &TextureRegion { + assert!(self.resource_manager.texture_atlas().textures().contains_key(&texture_path), "Texture not found in atlas"); + self.resource_manager.texture_atlas().textures().get(&texture_path).unwrap() + } + fn create_rectangle(&self, width: f32, height: f32) -> Vec { let (bound_x, bound_y) = ((width/ self.config.width as f32) * 0.5, (height/ self.config.height as f32) * 0.5); @@ -512,7 +469,37 @@ impl<'a> Renderer<'a> { self.diffuse_bind_group = diffuse_bind_group; } - pub(crate) fn set_buffers(&mut self, new_vertex_buffer: Vec, new_index_buffer: Vec) { + pub fn get_project_root() -> std::io::Result { + let path = std::env::current_dir()?; + let mut path_ancestors = path.as_path().ancestors(); + + while let Some(p) = path_ancestors.next() { + let has_cargo = + std::fs::read_dir(p)? + .into_iter() + .any(|p| p.unwrap().file_name() == std::ffi::OsString::from("Cargo.lock")); + if has_cargo { + return Ok(PathBuf::from(p)) + } + } + Err(std::io::Error::new(std::io::ErrorKind::NotFound, "Ran out of places to find Cargo.toml")) + + } + + pub fn initialize_atlas(&mut self) { + let texture_path = "resources/textures/".to_string(); + let mut paths: Vec = Vec::new(); + + for path in std::fs::read_dir(Self::get_project_root().unwrap().as_os_str().to_str().unwrap().to_string() + "\\resources\\textures").unwrap() { + paths.push(texture_path.clone() + path.unwrap().file_name().to_str().unwrap()); + } + + error!(format!("{:?}", paths)); + + self.set_texture_atlas(paths); + } + + pub fn set_buffers(&mut self, new_vertex_buffer: Vec, new_index_buffer: Vec) { match new_vertex_buffer == self.vertex_data { true => return, false => { @@ -539,7 +526,7 @@ impl<'a> Renderer<'a> { } } - pub(crate) fn push_to_buffers(&mut self, new_vertex_buffer: &mut Vec, new_index_buffer: &mut Vec) { + pub fn push_to_buffers(&mut self, new_vertex_buffer: &mut Vec, new_index_buffer: &mut Vec) { self.vertex_data.append(new_vertex_buffer); self.index_data.append(new_index_buffer); @@ -577,14 +564,12 @@ impl<'a> Renderer<'a> { self.num_indices = self.index_data.len() as u32; } - pub fn draw_texture_at(&mut self, texture_path: &str, position: Point3) { - let region = self.resource_manager.texture_locations().get(texture_path).unwrap(); + pub fn draw_texture_at(&mut self, texture_path: String, position: Point3) { + let region = self.resource_manager.texture_locations().get(&texture_path).unwrap(); let (dim_x, dim_y) = region.dimensions(); let (bound_x, bound_y) = ((dim_x as f32/ self.config.width as f32) * 0.5, (dim_y as f32/ self.config.height as f32) * 0.5); - /*let bound_x = dim_x as f32/ self.config.width as f32 * 0.5; - let bound_y = bound_x;*/ let vertices: &mut Vec = &mut vec![ Vertex :: new ( [-bound_x + position.x(), bound_y + position.y(), 0.0 + position.z()], [region.x0(), region.y0()] ), diff --git a/crates/comet_resources/src/texture_atlas.rs b/crates/comet_resources/src/texture_atlas.rs index d07ac8b..4e779f6 100644 --- a/crates/comet_resources/src/texture_atlas.rs +++ b/crates/comet_resources/src/texture_atlas.rs @@ -3,7 +3,7 @@ use std::path::Path; use chrono::Local; use std::time::Instant; use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat}; -use comet_log::info; +use comet_log::*; use wgpu::{Device, FilterMode, TextureFormat, TextureUsages}; use crate::Texture; @@ -165,6 +165,7 @@ impl TextureAtlas { //base.save_with_format(output_path, ImageFormat::Png).expect("Failed to save texture atlas"); info!("Texture atlas created!"); + debug!(format!("{:?}", regions)); /*let t1 = Instant::now(); let delta = t1.duration_since(t0); diff --git a/src/main.rs b/src/main.rs index eb84ee1..77461b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,30 +10,55 @@ use comet::{ log::* }; use winit::event::{WindowEvent}; -use comet_ecs::{Component, ComponentSet, Transform2D}; +use comet_ecs::{Component, ComponentSet, Render, Renderer2D, Transform2D}; use comet_input::mouse::{mouse_entered, mouse_pressed, Button}; -#[derive(Component)] -struct TestComponent { - position: f32 -} - fn input(event: &WindowEvent, app: &mut App, renderer: &mut Renderer) { match event { - _ if key_pressed(event, Key::KeyI) => app.world_mut().register_component::(), _ if key_pressed(event, Key::Escape) => app.quit(), + _ if key_pressed(event, Key::KeyC) => { renderer.clear_buffers() } _ if key_pressed(event, Key::KeyE) => { + let mut renderer2d = Renderer2D::new(); + renderer2d.set_texture(r"resources/textures/comet_icon.png"); + renderer2d.set_visibility(true); + let id = app.world_mut().new_entity(); - app.world_mut().add_component::(id as usize, TestComponent::new()) + app.world_mut().add_component(id as usize, renderer2d.clone()); + app.world_mut().add_component(0, renderer2d); + + let transform = app.world_mut().get_component_mut::(id as usize); + transform.position_mut().set_x(0.5); + + debug!(format!("{:?}", app.world().components().get_component::(0))); }, - _ if key_pressed(event, Key::KeyR) => { - debug!(format!("{:?}", app.world().get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), TestComponent::type_id()])))); + _ if key_pressed(event, Key::KeyW) => { + let transform = app.world_mut().get_component_mut::(0); + let y = transform.position().y(); + transform.position_mut().set_y(y + 0.1); }, + _ if key_pressed(event, Key::KeyA) => { + let transform = app.world_mut().get_component_mut::(0); + let x = transform.position().x(); + transform.position_mut().set_x(x - 0.1); + }, + _ if key_pressed(event, Key::KeyS) => { + let transform = app.world_mut().get_component_mut::(0); + let y = transform.position().y(); + transform.position_mut().set_y(y - 0.1); + }, + _ if key_pressed(event, Key::KeyD) => { + let transform = app.world_mut().get_component_mut::(0); + let x = transform.position().x(); + transform.position_mut().set_x(x + 0.1); + } _ => {} } } fn update(world: &mut World, renderer: &mut Renderer) { + if !world.components().contains_components(ComponentSet::from_ids(vec![Transform2D::type_id(), Renderer2D::type_id()])) { + world.register_component::(); + } if world.entities().len() == 0 { let id = world.new_entity(); }