mirror of
https://github.com/lisk77/comet.git
synced 2025-12-12 17:18:50 +00:00
Compare commits
6 commits
dfdffed745
...
d83c780ce7
| Author | SHA1 | Date | |
|---|---|---|---|
| d83c780ce7 | |||
| 67dcee0a9b | |||
| 87f0233066 | |||
| dd89d71565 | |||
| ca47efba42 | |||
| dab38c1e32 |
14 changed files with 374 additions and 55 deletions
|
|
@ -11,6 +11,7 @@ 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"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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;
|
||||
|
|
@ -30,6 +31,7 @@ pub struct App {
|
|||
delta_time: f32,
|
||||
update_timer: f32,
|
||||
game_state: Option<Box<dyn Any>>,
|
||||
audio: Box<dyn Audio>,
|
||||
scene: Scene,
|
||||
fullscreen: bool,
|
||||
should_quit: bool,
|
||||
|
|
@ -47,6 +49,7 @@ 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,
|
||||
|
|
@ -136,6 +139,11 @@ 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
|
||||
|
|
@ -246,6 +254,38 @@ 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;
|
||||
|
|
@ -341,6 +381,9 @@ 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() {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// 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;
|
||||
|
|
@ -45,6 +46,7 @@ pub struct Render2D {
|
|||
is_visible: bool,
|
||||
texture_name: &'static str,
|
||||
scale: v2,
|
||||
draw_index: u32,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
|
|
@ -61,6 +63,7 @@ pub struct Text {
|
|||
font_size: f32,
|
||||
color: Color,
|
||||
is_visible: bool,
|
||||
bounds: v2,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
|
|
@ -78,6 +81,15 @@ pub struct Timer {
|
|||
done: bool,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct AudioSource {
|
||||
name: &'static str,
|
||||
path: Option<&'static str>,
|
||||
looped: bool,
|
||||
volume: f32,
|
||||
pitch: f32,
|
||||
}
|
||||
|
||||
// ##################################################
|
||||
// # BUNDLES #
|
||||
// ##################################################
|
||||
|
|
@ -264,13 +276,39 @@ 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 {
|
||||
|
|
@ -431,6 +469,7 @@ impl Text {
|
|||
font_size,
|
||||
color: Color::from_wgpu_color(color.to_wgpu()),
|
||||
is_visible,
|
||||
bounds: v2::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -469,6 +508,14 @@ 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 {
|
||||
|
|
@ -548,3 +595,47 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
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<Window>, clear_color: Option<impl Color>) -> Self;
|
||||
fn size(&self) -> PhysicalSize<u32>;
|
||||
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>);
|
||||
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>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ pub struct Renderer2D<'a> {
|
|||
queue: wgpu::Queue,
|
||||
config: wgpu::SurfaceConfiguration,
|
||||
size: PhysicalSize<u32>,
|
||||
scale_factor: f64,
|
||||
universal_render_pipeline: wgpu::RenderPipeline,
|
||||
texture_bind_group_layout: wgpu::BindGroupLayout,
|
||||
texture_sampler: wgpu::Sampler,
|
||||
|
|
@ -43,6 +44,7 @@ pub struct Renderer2D<'a> {
|
|||
impl<'a> Renderer2D<'a> {
|
||||
pub fn new(window: Arc<Window>, clear_color: Option<impl Color>) -> Renderer2D<'a> {
|
||||
let size = window.inner_size(); //PhysicalSize::<u32>::new(1920, 1080);
|
||||
let scale_factor = window.scale_factor();
|
||||
|
||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||
backends: wgpu::Backends::PRIMARY,
|
||||
|
|
@ -258,6 +260,7 @@ impl<'a> Renderer2D<'a> {
|
|||
queue,
|
||||
config,
|
||||
size,
|
||||
scale_factor,
|
||||
universal_render_pipeline,
|
||||
texture_bind_group_layout,
|
||||
texture_sampler,
|
||||
|
|
@ -294,6 +297,14 @@ 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,
|
||||
|
|
@ -483,6 +494,7 @@ impl<'a> Renderer2D<'a> {
|
|||
size: f32,
|
||||
position: p2,
|
||||
color: wgpu::Color,
|
||||
bounds: &mut v2,
|
||||
) -> (Vec<Vertex>, Vec<u16>) {
|
||||
let vert_color = [
|
||||
color.r as f32,
|
||||
|
|
@ -495,24 +507,18 @@ 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 line_height = (self
|
||||
let font_data = self
|
||||
.graphic_resource_manager
|
||||
.fonts()
|
||||
.iter()
|
||||
.find(|f| f.name() == font)
|
||||
.unwrap()
|
||||
.line_height()
|
||||
/ self.config.height as f32)
|
||||
* scale_factor;
|
||||
.unwrap();
|
||||
|
||||
let scale_factor = size / font_data.size();
|
||||
|
||||
let line_height = (font_data.line_height() / self.config.height as f32) * scale_factor;
|
||||
|
||||
let lines = text
|
||||
.split("\n")
|
||||
.map(|s| {
|
||||
|
|
@ -525,9 +531,27 @@ impl<'a> Renderer2D<'a> {
|
|||
})
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
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();
|
||||
|
||||
|
|
@ -679,14 +703,22 @@ 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: &Scene) {
|
||||
pub fn render_scene_2d(&mut self, scene: &mut Scene) {
|
||||
let cameras = scene.get_entities_with(vec![Transform2D::type_id(), Camera2D::type_id()]);
|
||||
|
||||
if cameras.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let entities = scene.get_entities_with(vec![Transform2D::type_id(), Render2D::type_id()]);
|
||||
let mut entities =
|
||||
scene.get_entities_with(vec![Transform2D::type_id(), Render2D::type_id()]);
|
||||
|
||||
entities.sort_by(|&a, &b| {
|
||||
let ra = scene.get_component::<Render2D>(a).unwrap();
|
||||
let rb = scene.get_component::<Render2D>(b).unwrap();
|
||||
ra.draw_index().cmp(&rb.draw_index())
|
||||
});
|
||||
|
||||
let texts =
|
||||
scene.get_entities_with(vec![Transform2D::type_id(), comet_ecs::Text::type_id()]);
|
||||
|
||||
|
|
@ -713,8 +745,9 @@ impl<'a> Renderer2D<'a> {
|
|||
let region = t_region.unwrap();
|
||||
let (dim_x, dim_y) = region.dimensions();
|
||||
|
||||
let half_width = dim_x as f32 * 0.5;
|
||||
let half_height = dim_y as f32 * 0.5;
|
||||
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 buffer_size = vertex_buffer.len() as u16;
|
||||
|
||||
|
|
@ -780,26 +813,38 @@ impl<'a> Renderer2D<'a> {
|
|||
}
|
||||
|
||||
for text in texts {
|
||||
let component = scene.get_component::<Text>(text).unwrap();
|
||||
if let Some(component) = scene.get_component_mut::<Text>(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 transform = scene.get_component::<Transform2D>(text).unwrap();
|
||||
|
||||
if component.is_visible() {
|
||||
let mut bounds = v2::ZERO;
|
||||
let (vertices, indices) = self.add_text_to_buffers(
|
||||
component.content().to_string(),
|
||||
component.font().to_string(),
|
||||
component.font_size(),
|
||||
content,
|
||||
font.clone(),
|
||||
size,
|
||||
p2::from_vec(transform.position().as_vec()),
|
||||
component.color().to_wgpu(),
|
||||
color,
|
||||
&mut bounds,
|
||||
);
|
||||
|
||||
let component = scene.get_component_mut::<Text>(text).unwrap();
|
||||
component.set_bounds(bounds);
|
||||
|
||||
let draw = self
|
||||
.draw_info
|
||||
.iter_mut()
|
||||
.find(|d| d.name() == &format!("{}", component.font()))
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.set_buffers(vertex_buffer, index_buffer);
|
||||
}
|
||||
|
|
@ -885,6 +930,14 @@ 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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rodio = "0.12.0"
|
||||
kira = "0.10.8"
|
||||
|
|
|
|||
13
crates/comet_sound/src/audio.rs
Normal file
13
crates/comet_sound/src/audio.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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);
|
||||
}
|
||||
86
crates/comet_sound/src/kira.rs
Normal file
86
crates/comet_sound/src/kira.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
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<String, StaticSoundData>,
|
||||
handles: HashMap<String, StaticSoundHandle>,
|
||||
}
|
||||
|
||||
impl KiraAudio {
|
||||
fn load_sound(path: &Path) -> Option<StaticSoundData> {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
5
crates/comet_sound/src/lib.rs
Normal file
5
crates/comet_sound/src/lib.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
mod audio;
|
||||
mod kira;
|
||||
|
||||
pub use audio::Audio;
|
||||
pub use kira::KiraAudio;
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
|
@ -14,9 +14,7 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
|||
|
||||
app.add_component(e1, Transform2D::new());
|
||||
|
||||
let mut renderer2d = Render2D::new();
|
||||
renderer2d.set_texture(r"res/textures/comet_icon.png");
|
||||
renderer2d.set_visibility(true);
|
||||
let mut renderer2d = Render2D::with_texture("res/textures/comet_icon.png");
|
||||
|
||||
app.add_component(e1, renderer2d);
|
||||
}
|
||||
|
|
@ -24,7 +22,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());
|
||||
renderer.render_scene_2d(app.scene_mut());
|
||||
}
|
||||
|
||||
fn handle_input(app: &mut App, dt: f32) {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
renderer.render_scene_2d(app.scene_mut());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -13,15 +13,13 @@ fn setup(app: &mut App, renderer: &mut Renderer2D) {
|
|||
let e0 = app.new_entity();
|
||||
app.add_component(e0, Transform2D::new());
|
||||
|
||||
let mut render = Render2D::new();
|
||||
render.set_visibility(true);
|
||||
render.set_texture("./res/textures/comet_icon.png");
|
||||
let render = Render2D::with_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())
|
||||
renderer.render_scene_2d(app.scene_mut())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
31
goals.md
Normal file
31
goals.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue