Compare commits
No commits in common. "62571655ae858d939cd9144f952ff87f505286a8" and "11f9fecba1a19875f91d95fe85efc819e0c9c4c4" have entirely different histories.
62571655ae
...
11f9fecba1
6 changed files with 48 additions and 238 deletions
122
src/engine.rs
122
src/engine.rs
|
@ -1,8 +1,5 @@
|
||||||
use crate::{BG, GAME_SIZE};
|
|
||||||
|
|
||||||
use self::objs::{obj_traits::MovingObject, World};
|
use self::objs::{obj_traits::MovingObject, World};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
process,
|
process,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
@ -12,7 +9,7 @@ use winit::{
|
||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
event::{Event, KeyEvent, StartCause, WindowEvent},
|
event::{Event, KeyEvent, StartCause, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
keyboard::{Key, KeyCode, NamedKey, PhysicalKey},
|
keyboard::{Key, NamedKey},
|
||||||
raw_window_handle::{HasDisplayHandle, HasWindowHandle},
|
raw_window_handle::{HasDisplayHandle, HasWindowHandle},
|
||||||
window::WindowBuilder,
|
window::WindowBuilder,
|
||||||
};
|
};
|
||||||
|
@ -21,26 +18,19 @@ pub mod objs;
|
||||||
mod render;
|
mod render;
|
||||||
mod timer;
|
mod timer;
|
||||||
|
|
||||||
type RenderFn = fn(&mut render::RenderCtx<'_, '_>, &mut World, &timer::GameTimer);
|
const GAME_SIZE: (u32, u32) = (1200, 800);
|
||||||
type KeyHandlerFn = fn(&mut World, &timer::GameTimer);
|
const BORDER_WIDTH: u32 = 10;
|
||||||
|
const FG: u32 = 0xebdbb2;
|
||||||
|
const BG: u32 = 0x282828;
|
||||||
|
|
||||||
|
type RenderFn = fn(&mut render::RenderCtx<'_, '_>, &mut World, &timer::GameTimer);
|
||||||
// core game engine struct
|
// core game engine struct
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
event_loop: EventLoop<()>,
|
event_loop: EventLoop<()>,
|
||||||
render_fn: RenderFn,
|
render_fn: RenderFn,
|
||||||
resize_fn: RenderFn,
|
|
||||||
kb_handlers: HashMap<KeyEventType, KeyHandlerFn>,
|
|
||||||
down_keys: HashSet<KeyCode>,
|
|
||||||
world: World,
|
world: World,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash)]
|
|
||||||
pub enum KeyEventType {
|
|
||||||
KeyDown(KeyCode),
|
|
||||||
KeyDownFrameUpdate(KeyCode),
|
|
||||||
KeyUp(KeyCode),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let event_loop = EventLoop::new().unwrap();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
@ -48,9 +38,6 @@ impl Engine {
|
||||||
Self {
|
Self {
|
||||||
event_loop,
|
event_loop,
|
||||||
render_fn: |_, _, _| {},
|
render_fn: |_, _, _| {},
|
||||||
resize_fn: |_, _, _| {},
|
|
||||||
kb_handlers: HashMap::new(),
|
|
||||||
down_keys: HashSet::new(),
|
|
||||||
world: World::new(),
|
world: World::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,26 +52,12 @@ impl Engine {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets the resize render function for the game
|
|
||||||
pub fn set_resize_fn(mut self, f: RenderFn) -> Self {
|
|
||||||
self.resize_fn = f;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_handler(mut self, ev_type: KeyEventType, f: KeyHandlerFn) -> Self {
|
|
||||||
self.kb_handlers.insert(ev_type, f);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
// runs the game and consumes self, this will finish the process
|
// runs the game and consumes self, this will finish the process
|
||||||
pub fn run(self) -> ! {
|
pub fn run(self) -> ! {
|
||||||
let Self {
|
let Self {
|
||||||
event_loop,
|
event_loop,
|
||||||
mut world,
|
mut world,
|
||||||
render_fn,
|
render_fn,
|
||||||
resize_fn,
|
|
||||||
kb_handlers,
|
|
||||||
mut down_keys,
|
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
// set up window
|
// set up window
|
||||||
|
@ -102,17 +75,16 @@ impl Engine {
|
||||||
|
|
||||||
event_loop
|
event_loop
|
||||||
.run(|event, elwt| {
|
.run(|event, elwt| {
|
||||||
|
// shoddy vsync
|
||||||
|
elwt.set_control_flow(ControlFlow::WaitUntil(
|
||||||
|
Instant::now() + Duration::from_millis(1000 / 60),
|
||||||
|
));
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
// redraw
|
// redraw
|
||||||
Event::NewEvents(StartCause::ResumeTimeReached { .. }) => {
|
Event::NewEvents(StartCause::ResumeTimeReached { .. }) => {
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
Event::NewEvents(StartCause::WaitCancelled {
|
|
||||||
start,
|
|
||||||
requested_resume,
|
|
||||||
}) => {
|
|
||||||
elwt.set_control_flow(ControlFlow::WaitUntil(requested_resume.unwrap()));
|
|
||||||
}
|
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::Resized(PhysicalSize { width, height }),
|
event: WindowEvent::Resized(PhysicalSize { width, height }),
|
||||||
|
@ -127,7 +99,27 @@ impl Engine {
|
||||||
|
|
||||||
let mut ctx =
|
let mut ctx =
|
||||||
render::RenderCtx::new(buffer, (width, height), GAME_SIZE);
|
render::RenderCtx::new(buffer, (width, height), GAME_SIZE);
|
||||||
resize_fn(&mut ctx, &mut world, &timer);
|
|
||||||
|
// top
|
||||||
|
ctx.rect(0, 0, GAME_SIZE.0, BORDER_WIDTH, FG);
|
||||||
|
// left
|
||||||
|
ctx.rect(
|
||||||
|
0,
|
||||||
|
BORDER_WIDTH,
|
||||||
|
BORDER_WIDTH,
|
||||||
|
GAME_SIZE.1 - BORDER_WIDTH * 2,
|
||||||
|
FG,
|
||||||
|
);
|
||||||
|
// right
|
||||||
|
ctx.rect(
|
||||||
|
GAME_SIZE.0 - BORDER_WIDTH,
|
||||||
|
BORDER_WIDTH,
|
||||||
|
BORDER_WIDTH,
|
||||||
|
GAME_SIZE.1 - BORDER_WIDTH * 2,
|
||||||
|
FG,
|
||||||
|
);
|
||||||
|
// bottom
|
||||||
|
ctx.rect(0, GAME_SIZE.1 - BORDER_WIDTH, GAME_SIZE.0, 10, FG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,30 +127,11 @@ impl Engine {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::RedrawRequested,
|
event: WindowEvent::RedrawRequested,
|
||||||
} => {
|
} => {
|
||||||
// shoddy vsync
|
|
||||||
elwt.set_control_flow(ControlFlow::WaitUntil(
|
|
||||||
Instant::now() + Duration::from_millis(1000 / 60),
|
|
||||||
));
|
|
||||||
if window_id == window.id() {
|
if window_id == window.id() {
|
||||||
if let (Some(width), Some(height)) = {
|
if let (Some(width), Some(height)) = {
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
(NonZeroU32::new(size.width), NonZeroU32::new(size.height))
|
(NonZeroU32::new(size.width), NonZeroU32::new(size.height))
|
||||||
} {
|
} {
|
||||||
for frame_handler in
|
|
||||||
kb_handlers.iter().filter_map(|(ev, handler)| {
|
|
||||||
if let KeyEventType::KeyDownFrameUpdate(keycode) = ev {
|
|
||||||
if down_keys.contains(keycode) {
|
|
||||||
Some(handler)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
{
|
|
||||||
frame_handler(&mut world, &timer)
|
|
||||||
}
|
|
||||||
surface.resize(width, height).unwrap();
|
surface.resize(width, height).unwrap();
|
||||||
let buffer = surface.buffer_mut().unwrap();
|
let buffer = surface.buffer_mut().unwrap();
|
||||||
|
|
||||||
|
@ -188,39 +161,14 @@ impl Engine {
|
||||||
} => todo!(),
|
} => todo!(),
|
||||||
// potential future keyboard handling
|
// potential future keyboard handling
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
window_id: window_id,
|
window_id: _window_id,
|
||||||
event:
|
event:
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
device_id: _device_id,
|
device_id: _device_id,
|
||||||
event:
|
event: _event,
|
||||||
KeyEvent {
|
|
||||||
physical_key,
|
|
||||||
state,
|
|
||||||
repeat,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
is_synthetic: _is_synthetic,
|
is_synthetic: _is_synthetic,
|
||||||
},
|
},
|
||||||
} => {
|
} => {}
|
||||||
if !repeat {
|
|
||||||
if let PhysicalKey::Code(keycode) = physical_key {
|
|
||||||
let ev_type = match state {
|
|
||||||
winit::event::ElementState::Pressed => {
|
|
||||||
down_keys.insert(keycode);
|
|
||||||
KeyEventType::KeyDown(keycode)
|
|
||||||
}
|
|
||||||
winit::event::ElementState::Released => {
|
|
||||||
down_keys.remove(&keycode);
|
|
||||||
KeyEventType::KeyUp(keycode)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(handler) = kb_handlers.get(&ev_type) {
|
|
||||||
handler(&mut world, &timer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use self::obj_traits::MovingObject;
|
use self::obj_traits::MovingObject;
|
||||||
|
|
||||||
use super::render::RenderCtx;
|
use super::{render::RenderCtx, BG, FG};
|
||||||
|
|
||||||
pub mod geometry;
|
pub mod geometry;
|
||||||
pub mod obj_traits;
|
pub mod obj_traits;
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub struct Position {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Position {
|
impl Position {
|
||||||
pub const fn new(x: u32, y: u32) -> Self {
|
pub fn new(x: u32, y: u32) -> Self {
|
||||||
Self { x, y }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::engine::{render::RenderCtx, BG, FG};
|
||||||
engine::{render::RenderCtx, BG},
|
|
||||||
FG,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::geometry::{Position, Size};
|
use super::geometry::{Position, Size};
|
||||||
|
|
||||||
|
@ -38,32 +35,4 @@ pub trait MovingObject: Object {
|
||||||
ctx.rect(prev_x, prev_y, width, height, BG);
|
ctx.rect(prev_x, prev_y, width, height, BG);
|
||||||
self.display(ctx);
|
self.display(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_constrained(
|
|
||||||
&mut self,
|
|
||||||
x: i32,
|
|
||||||
y: i32,
|
|
||||||
constraint_start: Position,
|
|
||||||
constraint_end: Position,
|
|
||||||
) {
|
|
||||||
let Position { x: cur_x, y: cur_y } = self.position();
|
|
||||||
let Size { width, height } = self.size();
|
|
||||||
|
|
||||||
let new_x = if cur_x.saturating_add_signed(x) <= constraint_start.x {
|
|
||||||
constraint_start.x
|
|
||||||
} else if (cur_x + width.saturating_add_signed(y)) > constraint_end.x {
|
|
||||||
constraint_end.x - width
|
|
||||||
} else {
|
|
||||||
cur_x.saturating_add_signed(x)
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_y = if cur_y.saturating_add_signed(y) < constraint_start.y {
|
|
||||||
constraint_start.y
|
|
||||||
} else if (cur_y + height.saturating_add_signed(y)) >= constraint_end.y {
|
|
||||||
constraint_end.y - height
|
|
||||||
} else {
|
|
||||||
cur_y.saturating_add_signed(y)
|
|
||||||
};
|
|
||||||
self.update_pos(new_x, new_y)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct Rect {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rect {
|
impl Rect {
|
||||||
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
|
pub fn new(x: u32, y: u32, height: u32, width: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pos: Position::new(x, y),
|
pos: Position::new(x, y),
|
||||||
size: Size::new(width, height),
|
size: Size::new(width, height),
|
||||||
|
@ -42,10 +42,10 @@ pub struct MovingRect {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MovingRect {
|
impl MovingRect {
|
||||||
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
|
pub fn new(x: u32, y: u32, height: u32, width: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
prev_pos: Position::new(x, y),
|
prev_pos: Position::new(x, y),
|
||||||
current: Rect::new(x, y, width, height),
|
current: Rect::new(x, y, height, width),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
121
src/main.rs
121
src/main.rs
|
@ -1,124 +1,17 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use engine::{
|
use engine::Engine;
|
||||||
objs::{geometry::Position, primitive_shapes::MovingRect},
|
|
||||||
Engine,
|
|
||||||
};
|
|
||||||
use winit::{
|
|
||||||
event::KeyEvent,
|
|
||||||
keyboard::{Key, KeyCode, NamedKey, PhysicalKey, SmolStr},
|
|
||||||
};
|
|
||||||
|
|
||||||
const GAME_SIZE: (u32, u32) = (1200, 800);
|
|
||||||
const BORDER_WIDTH: u32 = 10;
|
|
||||||
const PADDLE_SIZE: (u32, u32) = (BORDER_WIDTH, 100);
|
|
||||||
const PADDLE_OFFSET: u32 = 20;
|
|
||||||
const PADDLE_SPEED: i32 = 10;
|
|
||||||
const FG: u32 = 0xebdbb2;
|
|
||||||
const BG: u32 = 0x282828;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
// let _ = engine.insert_into_world(Rc::new(MovingRect::new(0, 0, 50, 100)));
|
||||||
// left paddle
|
|
||||||
let _left_paddle_id = engine.insert_into_world(Rc::new(MovingRect::new(
|
|
||||||
BORDER_WIDTH + PADDLE_OFFSET,
|
|
||||||
GAME_SIZE.1 / 2 - PADDLE_SIZE.1 / 2,
|
|
||||||
PADDLE_SIZE.0,
|
|
||||||
PADDLE_SIZE.1,
|
|
||||||
)));
|
|
||||||
let _right_paddle_id = engine.insert_into_world(Rc::new(MovingRect::new(
|
|
||||||
GAME_SIZE.0 - (BORDER_WIDTH + PADDLE_OFFSET + PADDLE_SIZE.0),
|
|
||||||
GAME_SIZE.1 / 2 - PADDLE_SIZE.1 / 2,
|
|
||||||
PADDLE_SIZE.0,
|
|
||||||
PADDLE_SIZE.1,
|
|
||||||
)));
|
|
||||||
|
|
||||||
const LEFT_PADDLE_CONSTRAINTS: (Position, Position) = (
|
|
||||||
Position::new(BORDER_WIDTH + PADDLE_OFFSET, BORDER_WIDTH),
|
|
||||||
Position::new(BORDER_WIDTH * 2 + PADDLE_OFFSET, GAME_SIZE.1 - BORDER_WIDTH),
|
|
||||||
);
|
|
||||||
const RIGHT_PADDLE_CONSTRAINTS: (Position, Position) = (
|
|
||||||
Position::new(
|
|
||||||
GAME_SIZE.0 - (BORDER_WIDTH + PADDLE_OFFSET + PADDLE_SIZE.0),
|
|
||||||
BORDER_WIDTH,
|
|
||||||
),
|
|
||||||
Position::new(
|
|
||||||
GAME_SIZE.0 - (BORDER_WIDTH + PADDLE_OFFSET),
|
|
||||||
GAME_SIZE.1 - BORDER_WIDTH,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
engine
|
engine
|
||||||
.register_handler(
|
|
||||||
engine::KeyEventType::KeyDownFrameUpdate(KeyCode::KeyW),
|
|
||||||
|world, timer| {
|
|
||||||
Rc::get_mut(world.get_mut(0)).unwrap().move_constrained(
|
|
||||||
0,
|
|
||||||
-PADDLE_SPEED,
|
|
||||||
LEFT_PADDLE_CONSTRAINTS.0,
|
|
||||||
LEFT_PADDLE_CONSTRAINTS.1,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.register_handler(
|
|
||||||
engine::KeyEventType::KeyDownFrameUpdate(KeyCode::KeyS),
|
|
||||||
|world, timer| {
|
|
||||||
Rc::get_mut(world.get_mut(0)).unwrap().move_constrained(
|
|
||||||
0,
|
|
||||||
PADDLE_SPEED,
|
|
||||||
LEFT_PADDLE_CONSTRAINTS.0,
|
|
||||||
LEFT_PADDLE_CONSTRAINTS.1,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.register_handler(
|
|
||||||
engine::KeyEventType::KeyDownFrameUpdate(KeyCode::KeyK),
|
|
||||||
|world, timer| {
|
|
||||||
Rc::get_mut(world.get_mut(1)).unwrap().move_constrained(
|
|
||||||
0,
|
|
||||||
-PADDLE_SPEED,
|
|
||||||
RIGHT_PADDLE_CONSTRAINTS.0,
|
|
||||||
RIGHT_PADDLE_CONSTRAINTS.1,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.register_handler(
|
|
||||||
engine::KeyEventType::KeyDownFrameUpdate(KeyCode::KeyJ),
|
|
||||||
|world, timer| {
|
|
||||||
Rc::get_mut(world.get_mut(1)).unwrap().move_constrained(
|
|
||||||
0,
|
|
||||||
PADDLE_SPEED,
|
|
||||||
RIGHT_PADDLE_CONSTRAINTS.0,
|
|
||||||
RIGHT_PADDLE_CONSTRAINTS.1,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.set_resize_fn(|ctx, world, timer| {
|
|
||||||
// top
|
|
||||||
ctx.rect(0, 0, GAME_SIZE.0, BORDER_WIDTH, FG);
|
|
||||||
// left
|
|
||||||
ctx.rect(
|
|
||||||
0,
|
|
||||||
BORDER_WIDTH,
|
|
||||||
BORDER_WIDTH,
|
|
||||||
GAME_SIZE.1 - BORDER_WIDTH * 2,
|
|
||||||
FG,
|
|
||||||
);
|
|
||||||
// right
|
|
||||||
ctx.rect(
|
|
||||||
GAME_SIZE.0 - BORDER_WIDTH,
|
|
||||||
BORDER_WIDTH,
|
|
||||||
BORDER_WIDTH,
|
|
||||||
GAME_SIZE.1 - BORDER_WIDTH * 2,
|
|
||||||
FG,
|
|
||||||
);
|
|
||||||
// bottom
|
|
||||||
ctx.rect(0, GAME_SIZE.1 - BORDER_WIDTH, GAME_SIZE.0, 10, FG);
|
|
||||||
})
|
|
||||||
.set_render_fn(|ctx, world, timer| {
|
.set_render_fn(|ctx, world, timer| {
|
||||||
Rc::get_mut(world.get_mut(0)).unwrap().draw_move(ctx);
|
// println!("t: {}", timer.game_time_passed());
|
||||||
Rc::get_mut(world.get_mut(1)).unwrap().draw_move(ctx);
|
// let obj = Rc::get_mut(world.get_mut(0)).unwrap();
|
||||||
|
// obj.move_obj(1, 0);
|
||||||
|
// obj.draw_move(ctx)
|
||||||
|
// Rect::square((timer.game_time_passed() * 20.) as u32, 0, 200).display(ctx);
|
||||||
})
|
})
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue