whaaaaaaaaaaaa

This commit is contained in:
SimonFJ20 2024-04-01 04:51:30 +02:00
parent 37fe2ea9b2
commit 9642194fac
5 changed files with 169 additions and 18 deletions

View File

@ -1,17 +1,16 @@
use std::time::Duration; use std::{path::Component, time::Duration};
use sdl2::{ use sdl2::{
event::Event, keyboard::Keycode, pixels::Color, render::Canvas, video::Window, Sdl, event::Event,
VideoSubsystem, image::{self, LoadTexture, Sdl2ImageContext},
keyboard::Keycode,
pixels::Color,
rect::Rect,
render::{Canvas, Texture, TextureCreator},
video::{Window, WindowBuildError, WindowContext},
IntegerOrSdlError, Sdl, VideoSubsystem,
}; };
pub struct Game {
sdl_context: Sdl,
video_subsystem: VideoSubsystem,
canvas: Canvas<Window>,
event_pump: sdl2::EventPump,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Error(String); pub struct Error(String);
@ -21,29 +20,143 @@ impl std::fmt::Display for Error {
} }
} }
impl<T: std::fmt::Display> From<T> for Error { macro_rules! impl_from_T_for_Error {
fn from(value: T) -> Self { ($t:ty) => {
impl From<$t> for Error {
fn from(value: $t) -> Self {
Self(value.to_string()) Self(value.to_string())
} }
}
};
($t:ty, $($ts:ty),+) => {
impl From<$t> for Error {
fn from(value: $t) -> Self {
Self(value.to_string())
}
}
impl_from_T_for_Error!($($ts),+);
};
}
impl_from_T_for_Error!(String, WindowBuildError, IntegerOrSdlError);
static RANDOM_U64_COUNTER: u64 = 0;
pub struct Entity(u64);
pub trait Component {}
pub struct Sprite<'a> {
texture: Texture<'a>,
}
pub struct Context<'a> {
id_counter: &'a mut u64,
canvas: &'a mut Canvas<Window>,
texture_creator: &'a TextureCreator<WindowContext>,
entities: &'a mut Vec<Entity>,
components: &'a mut Vec<(u64, Box<dyn Component>)>,
systems: &'a mut Vec<Box<dyn System>>,
}
impl<'a> Context<'a> {
pub fn load_sprite<'b, P>(&self, path: P) -> Result<Sprite<'b>, Error>
where
'a: 'b,
P: AsRef<std::path::Path>,
{
let texture = self.texture_creator.load_texture(path)?;
Ok(Sprite { texture })
}
pub fn draw_sprite<'b>(&mut self, sprite: &Sprite<'b>, x: i32, y: i32) -> Result<(), Error> {
self.canvas.copy(
&sprite.texture,
None,
Rect::new(
x * 4,
y * 4,
sprite.texture.query().width * 4,
sprite.texture.query().height * 4,
),
)?;
Ok(())
}
pub fn spawn(&mut self, components: Vec<Box<dyn Component>>) {
let id = *self.id_counter;
*self.id_counter += 1;
self.entities.push(Entity(id));
self.components
.extend(components.into_iter().map(|component| (id, component)));
}
pub fn add_system(&mut self, system: Box<dyn System>) {
system.on_add(self);
self.systems.push(system)
}
pub fn query<F: Fn(u64) -> bool>(&mut self, predicate: F) -> Vec<u64> {
let mut entities = Vec::<u64>::new();
for entity in &mut *self.entities {
if predicate(entity.0) {
entities.push(entity.0)
}
}
entities
}
pub fn has_component<T>(&mut self, entity_id: u64) -> bool {
for (id, component) in self.components {}
}
}
pub trait System {
fn on_add(&self, _ctx: &mut Context) {}
fn on_update(&self, _ctx: &mut Context) {}
}
pub struct Game {
id_counter: u64,
sdl_context: Sdl,
video_subsystem: VideoSubsystem,
image_context: Sdl2ImageContext,
canvas: Canvas<Window>,
texture_creator: TextureCreator<WindowContext>,
event_pump: sdl2::EventPump,
entities: Vec<Entity>,
components: Vec<(u64, Box<dyn Component>)>,
systems: Vec<Box<dyn System>>,
} }
impl Game { impl Game {
pub fn new() -> Result<Self, Error> { pub fn new() -> Result<Self, Error> {
let sdl_context = sdl2::init()?; let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?; let video_subsystem = sdl_context.video()?;
let image_context = image::init(image::InitFlag::PNG)?;
let window = video_subsystem let window = video_subsystem
.window("pvp-game-dilapidation", 1280, 720) .window("pvp-game-dilapidation", 1280, 720)
.position_centered() .position_centered()
.build()?; .build()?;
let mut canvas = window.into_canvas().build()?; let mut canvas = window.into_canvas().build()?;
let texture_creator = canvas.texture_creator();
canvas.set_draw_color(Color::RGB(60, 180, 180)); canvas.set_draw_color(Color::RGB(60, 180, 180));
canvas.clear(); canvas.clear();
canvas.present();
let event_pump = sdl_context.event_pump()?; let event_pump = sdl_context.event_pump()?;
Ok(Self { Ok(Self {
id_counter: 0,
sdl_context, sdl_context,
video_subsystem, video_subsystem,
image_context,
canvas, canvas,
texture_creator,
event_pump, event_pump,
entities: vec![],
components: vec![],
systems: vec![],
}) })
} }
@ -64,4 +177,15 @@ impl Game {
self.canvas.present(); self.canvas.present();
std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)) std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60))
} }
pub fn context<'a>(&'a mut self) -> Context<'a> {
Context {
id_counter: &mut self.id_counter,
canvas: &mut self.canvas,
texture_creator: &self.texture_creator,
entities: &mut self.entities,
components: &mut self.components,
systems: &mut self.systems,
}
}
} }

View File

@ -1,8 +1,35 @@
#[allow(dead_code)] #![allow(dead_code)]
use engine::{Component, Sprite, System};
mod engine; mod engine;
fn main() { struct Player<'a> {
let game = engine::Game::new().unwrap(); sprite: Option<Sprite<'a>>,
game.run(); }
println!("Hello, world!");
impl<'a> Component for Player<'a> {}
struct PlayerRenderer;
impl System for PlayerRenderer {
fn on_add(&self, ctx: &mut engine::Context) {
for entity in ctx.query(|id| ) {}
}
fn on_update(&self, _ctx: &mut engine::Context) {}
}
fn main() {
let mut game = engine::Game::new().unwrap();
{
let mut context = game.context();
context.add_system(Box::new(PlayerRenderer));
context.spawn(vec![Box::new(Player { sprite: None })]);
// let sprite = context.load_sprite("textures/player.png").unwrap();
// context.draw_sprite(&sprite, 16, 16).unwrap();
}
game.run();
} }

BIN
textures/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

BIN
textures/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

BIN
textures/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB