123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #[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 input;
- pub mod messages;
- pub mod util;
- const WIDTH: f32 = 600.0;
- const HEIGHT: f32 = 400.0;
- struct Game {
- pub world: specs::World,
- }
- impl Game {
- fn setup(conn: messages::Connection) -> Game {
- let mut world = specs::World::new();
- world.register::<Pos>();
- world.register::<Vel>();
- world.register::<Solid>();
- world.register::<Controlled>();
- world.insert(input::Input::new());
- world.insert(conn);
- world
- .create_entity()
- .with(Pos { x: 200.0, y: 200.0 })
- .with(Vel { dx: 0.0, dy: 0.0 })
- .with(Controlled)
- .with(Solid)
- .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;
- #[derive(Component)]
- pub struct Solid;
- system! {
- Transmit(resource conn: messages::Connection, _c: Controlled, p: Pos) {
- conn.update(p.x, p.y);
- }
- }
- system! {
- Control(resource inp: input::Input, _c: Controlled, mut v: Vel) {
- const ACCEL: f32 = 0.5;
- v.dx = util::clamp(v.dx + inp.right * ACCEL, -20.0, 20.0);
- v.dy = util::clamp(v.dy + inp.up * ACCEL, -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! {
- Physics(mut pos: Pos, mut v: Vel, _s: Solid) {
- if pos.x < 0.0 {
- pos.x = 0.0;
- v.dx = v.dx.abs() * 0.5;
- } else if pos.x > WIDTH {
- pos.x = WIDTH;
- v.dx = -v.dx.abs() * 0.5;
- }
- if pos.y < 0.0 {
- v.dy = v.dy.abs();
- } else if pos.y > HEIGHT {
- v.dy = -v.dy.abs();
- }
- }
- }
- 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<()> {
- Control.run_now(&self.world);
- Physics.run_now(&self.world);
- Slowdown.run_now(&self.world);
- Move.run_now(&self.world);
- Transmit.run_now(&self.world);
- Ok(())
- }
- // to handle events, we modify the stored KeyState resource
- fn key_down_event(
- &mut self,
- ctx: &mut ggez::Context,
- keycode: winit::VirtualKeyCode,
- _keymod: ggez::event::KeyMods,
- _repeat: bool,
- ) {
- if keycode == winit::VirtualKeyCode::Escape {
- self.world.read_resource::<messages::Connection>().goodbye();
- ggez::event::quit(ctx);
- }
- input::Input::handle_down(&mut self.world.write_resource(), keycode);
- }
- fn key_up_event(
- &mut self,
- _ctx: &mut ggez::Context,
- keycode: winit::VirtualKeyCode,
- _keymod: ggez::event::KeyMods,
- ) {
- input::Input::handle_up(&mut self.world.write_resource(), keycode);
- }
- }
- fn main() -> ggez::GameResult<()> {
- let connection = messages::Connection::new("foo", "192.168.0.3", 9991);
- let (mut ctx, mut evloop) = ggez::ContextBuilder::new("game", "me")
- .window_mode(ggez::conf::WindowMode {
- width: WIDTH,
- height: HEIGHT,
- ..ggez::conf::WindowMode::default()
- })
- .build()?;
- let mut game = Game::setup(connection);
- let res = ggez::event::run(&mut ctx, &mut evloop, &mut game);
- res
- }
|