|
@@ -1,13 +1,26 @@
|
|
|
-#[macro_use] extern crate specs_derive;
|
|
|
-#[macro_use] extern crate specs_system_macro;
|
|
|
+#[macro_use]
|
|
|
+extern crate specs_derive;
|
|
|
+#[macro_use]
|
|
|
+extern crate specs_system_macro;
|
|
|
|
|
|
use ggez::graphics::Drawable;
|
|
|
use specs::prelude::*;
|
|
|
use specs::world::WorldExt;
|
|
|
|
|
|
-mod keys;
|
|
|
+mod input;
|
|
|
|
|
|
-use keys::Input;
|
|
|
+const WIDTH: f32 = 600.0;
|
|
|
+const HEIGHT: f32 = 400.0;
|
|
|
+
|
|
|
+fn clamp(x: f32, min: f32, max: f32) -> f32 {
|
|
|
+ if x < min {
|
|
|
+ min
|
|
|
+ } else if x > max {
|
|
|
+ max
|
|
|
+ } else {
|
|
|
+ x
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
struct Game {
|
|
|
pub world: specs::World,
|
|
@@ -16,19 +29,108 @@ struct Game {
|
|
|
impl Game {
|
|
|
fn setup() -> Game {
|
|
|
let mut world = specs::World::new();
|
|
|
- world.insert(Input::new());
|
|
|
+ world.register::<Pos>();
|
|
|
+ world.register::<Vel>();
|
|
|
+ world.register::<Controlled>();
|
|
|
+ world.insert(input::Input::new());
|
|
|
+ world
|
|
|
+ .create_entity()
|
|
|
+ .with(Pos { x: 200.0, y: 200.0 })
|
|
|
+ .with(Vel { dx: 0.0, dy: 0.0 })
|
|
|
+ .with(Controlled)
|
|
|
+ .build();
|
|
|
Game { world }
|
|
|
}
|
|
|
}
|
|
|
+//
|
|
|
+
|
|
|
+#[derive(Component, Copy, Clone, Debug)]
|
|
|
+pub struct Pos {
|
|
|
+ x: f32,
|
|
|
+ y: f32,
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Component, Debug)]
|
|
|
+pub struct Vel {
|
|
|
+ dx: f32,
|
|
|
+ dy: f32,
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Component)]
|
|
|
+pub struct Controlled;
|
|
|
+
|
|
|
+system! {
|
|
|
+ Control(resource inp: input::Input, _c: Controlled, mut v: Vel) {
|
|
|
+ v.dx = clamp(v.dx + inp.right, -20.0, 20.0);
|
|
|
+ v.dy = clamp(v.dy + inp.up, -20.0, 20.0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+system! {
|
|
|
+ Slowdown(mut v: Vel, _c: Controlled) {
|
|
|
+ const ROUNDING: f32 = 0.01;
|
|
|
+ const FRICTION: f32 = 0.95;
|
|
|
+
|
|
|
+ if v.dx.abs() < ROUNDING {
|
|
|
+ v.dx = 0.0;
|
|
|
+ } else {
|
|
|
+ v.dx *= FRICTION;
|
|
|
+ }
|
|
|
+
|
|
|
+ if v.dy.abs() < ROUNDING {
|
|
|
+ v.dy = 0.0;
|
|
|
+ } else {
|
|
|
+ v.dy *= FRICTION;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+system! {
|
|
|
+ Move(mut pos: Pos, v: Vel) {
|
|
|
+ pos.x += v.dx;
|
|
|
+ pos.y += v.dy;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+struct Draw<'t> {
|
|
|
+ pub ctx: &'t mut ggez::Context,
|
|
|
+}
|
|
|
+
|
|
|
+impl<'a, 't> specs::System<'a> for Draw<'t> {
|
|
|
+ type SystemData = (specs::ReadStorage<'a, Pos>,);
|
|
|
+
|
|
|
+ fn run(&mut self, (pos,): Self::SystemData) {
|
|
|
+ for (p,) in (&pos,).join() {
|
|
|
+ let param = ggez::graphics::DrawParam {
|
|
|
+ dest: [p.x, p.y].into(),
|
|
|
+ ..ggez::graphics::DrawParam::default()
|
|
|
+ };
|
|
|
+ let mesh = ggez::graphics::Mesh::new_circle(
|
|
|
+ self.ctx,
|
|
|
+ ggez::graphics::DrawMode::fill(),
|
|
|
+ [0.0, 0.0],
|
|
|
+ 10.0,
|
|
|
+ 0.1,
|
|
|
+ ggez::graphics::WHITE,
|
|
|
+ );
|
|
|
+ mesh.unwrap().draw(self.ctx, param).unwrap();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
impl ggez::event::EventHandler for Game {
|
|
|
fn draw(&mut self, ctx: &mut ggez::Context) -> ggez::GameResult<()> {
|
|
|
+ ggez::graphics::clear(ctx, ggez::graphics::BLACK);
|
|
|
+ Draw { ctx }.run_now(&self.world);
|
|
|
+ ggez::graphics::present(ctx).unwrap();
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
fn update(&mut self, _ctx: &mut ggez::Context) -> ggez::GameResult<()> {
|
|
|
- let input: &Input = &*self.world.read_resource();
|
|
|
- println!("{:?}", input);
|
|
|
+ Control.run_now(&self.world);
|
|
|
+ Slowdown.run_now(&self.world);
|
|
|
+ Move.run_now(&self.world);
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
@@ -43,8 +145,7 @@ impl ggez::event::EventHandler for Game {
|
|
|
if keycode == winit::VirtualKeyCode::Escape {
|
|
|
ggez::event::quit(ctx);
|
|
|
}
|
|
|
- Input::handle_down(&mut self.world.write_resource(),
|
|
|
- keycode);
|
|
|
+ input::Input::handle_down(&mut self.world.write_resource(), keycode);
|
|
|
}
|
|
|
|
|
|
fn key_up_event(
|
|
@@ -53,17 +154,15 @@ impl ggez::event::EventHandler for Game {
|
|
|
keycode: winit::VirtualKeyCode,
|
|
|
_keymod: ggez::event::KeyMods,
|
|
|
) {
|
|
|
- Input::handle_up(&mut self.world.write_resource(),
|
|
|
- keycode);
|
|
|
+ input::Input::handle_up(&mut self.world.write_resource(), keycode);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
fn main() -> ggez::GameResult<()> {
|
|
|
let (mut ctx, mut evloop) = ggez::ContextBuilder::new("game", "me")
|
|
|
.window_mode(ggez::conf::WindowMode {
|
|
|
- width: 800.0,
|
|
|
- height: 600.0,
|
|
|
+ width: WIDTH,
|
|
|
+ height: HEIGHT,
|
|
|
..ggez::conf::WindowMode::default()
|
|
|
})
|
|
|
.build()?;
|