gdritter repos wenaglia / b77725a
Refactor input usage into two separate systems, barebones physics Getty Ritter 5 years ago
8 changed file(s) with 141 addition(s) and 70 deletion(s). Collapse all Expand all
649649 ]
650650
651651 [[package]]
652 name = "jeffersonia"
653 version = "0.1.0"
654 dependencies = [
655 "ggez 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
656 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
657 "sdl2 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
658 "specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
659 "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
660 "tiled 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
661 ]
662
663 [[package]]
664652 name = "jpeg-decoder"
665653 version = "0.1.15"
666654 source = "registry+https://github.com/rust-lang/crates.io-index"
16611649 name = "void"
16621650 version = "1.0.2"
16631651 source = "registry+https://github.com/rust-lang/crates.io-index"
1652
1653 [[package]]
1654 name = "wenaglia"
1655 version = "0.1.0"
1656 dependencies = [
1657 "ggez 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1658 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1659 "sdl2 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
1660 "specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
1661 "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1662 "tiled 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1663 ]
16641664
16651665 [[package]]
16661666 name = "which"
5454 }
5555 }
5656
57
5857 #[derive(Component, Default, Debug)]
5958 #[storage(NullStorage)]
6059 pub struct Background;
1 use sdl2::keyboard as sdl;
2
3 /// The shared values that the game state needs, mostly contained in
4 /// the specs ECS world
5 pub struct MyGame {
6 pub world: specs::World,
7 pub sprites: ggez::graphics::spritebatch::SpriteBatch,
8 pub keys: std::collections::HashSet<sdl::Keycode>,
9 }
11 #[macro_use] extern crate specs_derive;
22
3 use ggez::{Context, ContextBuilder, GameResult};
4 use ggez::event::{self, EventHandler};
5 use ggez::graphics;
6
7 use specs::RunNow;
3 use ggez::{
4 Context,
5 ContextBuilder,
6 GameResult,
7 event::{self, EventHandler},
8 };
89
910 use sdl2::keyboard as sdl;
1011
1112 pub mod consts;
1213 pub mod components;
14 pub mod game;
1315 pub mod res;
1416 pub mod sys;
1517
16 struct MyGame {
17 world: specs::World,
18 sprites: graphics::spritebatch::SpriteBatch,
19 }
18 use game::MyGame;
2019
2120 impl EventHandler for MyGame {
2221
2322 fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
23 sys::input::systems(self);
24 sys::physics::systems(self);
2425 Ok(())
2526 }
2627
2728 fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
28 ggez::graphics::set_background_color(ctx, ggez::graphics::BLACK);
29 ggez::graphics::clear(ctx);
30
31 sys::Draw {
32 ctx,
33 sprites: &mut self.sprites,
34 _phase: components::Background,
35 }.run_now(&self.world.res);
36 sys::Draw {
37 ctx,
38 sprites: &mut self.sprites,
39 _phase: components::Foreground,
40 }.run_now(&self.world.res);
41 sys::Draw {
42 ctx,
43 sprites: &mut self.sprites,
44 _phase: components::Decoration,
45 }.run_now(&self.world.res);
46
47 ggez::graphics::draw(
48 ctx,
49 &self.sprites,
50 ggez::nalgebra::Point2::new(0.0, 0.0),
51 0.0
52 )?;
53 self.sprites.clear();
54 ggez::graphics::present(ctx);
55 Ok(())
29 sys::drawing::systems(self, ctx)
5630 }
5731
5832 fn key_down_event(
6539 if keycode == sdl::Keycode::Escape {
6640 ctx.quit().expect("Should never fail");
6741 }
68 sys::Move { keycode }.run_now(&self.world.res);
42 self.keys.insert(keycode);
43 }
44
45 fn key_up_event(
46 &mut self,
47 _ctx: &mut Context,
48 keycode: sdl::Keycode,
49 _keymod: sdl::Mod,
50 _repeat: bool,
51 ) {
52 self.keys.remove(&keycode);
6953 }
7054 }
7155
8973 ..Default::default()
9074 })
9175 .build()?;
92 let image = graphics::Image::new(&mut ctx, "/spritesheet.png")?;
93 let mut sprites = graphics::spritebatch::SpriteBatch::new(image);
76 let image = ggez::graphics::Image::new(&mut ctx, "/spritesheet.png")?;
77 let mut sprites = ggez::graphics::spritebatch::SpriteBatch::new(image);
9478 sprites.set_filter(ggez::graphics::FilterMode::Nearest);
79 let keys = std::collections::HashSet::new();
9580
9681 let mut my_game = MyGame {
9782 world,
9883 sprites,
84 keys,
9985 };
10086
10187 event::run(&mut ctx, &mut my_game)
1717 DrawLayer::Foreground,
1818 DrawLayer::Decoration,
1919 ];
20
2120
2221 pub fn world_from_file<P: AsRef<Path>>(w: &mut specs::World, path: P) {
2322 let tiled::Map {
11 use crate::consts;
2 use crate::components::{Position,Sprite};
2 use crate::components::{self,Position,Sprite};
3 use crate::game::MyGame;
34
45 use ggez::{
56 Context,
7 graphics,
68 graphics::spritebatch::SpriteBatch,
79 };
8 use ggez::graphics;
10 use specs::RunNow;
911
12 /// The `Draw` system is parameterized by which phase we want to draw
13 /// in.
1014 pub struct Draw<'t, Phase> {
1115 pub ctx: &'t mut Context,
1216 pub sprites: &'t mut SpriteBatch,
1317 pub _phase: Phase,
1418 }
1519
16 impl<'a, 't, Phase: specs::Component> specs::System<'a> for Draw<'t, Phase> {
20 impl<'a, 't, Phase : specs::Component> specs::System<'a> for Draw<'t, Phase> {
1721 type SystemData = (
1822 specs::ReadStorage<'a, Position>,
1923 specs::ReadStorage<'a, Sprite>,
4044 }
4145 }
4246 }
47
48
49 pub fn systems(game: &mut MyGame, ctx: &mut Context) -> ggez::GameResult<()> {
50 graphics::set_background_color(ctx, graphics::BLACK);
51 graphics::clear(ctx);
52
53 Draw {
54 ctx,
55 sprites: &mut game.sprites,
56 _phase: components::Background,
57 }.run_now(&game.world.res);
58 Draw {
59 ctx,
60 sprites: &mut game.sprites,
61 _phase: components::Foreground,
62 }.run_now(&game.world.res);
63 Draw {
64 ctx,
65 sprites: &mut game.sprites,
66 _phase: components::Decoration,
67 }.run_now(&game.world.res);
68
69 graphics::draw(
70 ctx,
71 &game.sprites,
72 ggez::nalgebra::Point2::new(0.0, 0.0),
73 0.0
74 )?;
75 game.sprites.clear();
76 graphics::present(ctx);
77 Ok(())
78 }
1 use crate::components::{Movable, Position};
1 use crate::components::{Movable, Velocity};
2 use crate::game::MyGame;
23
34 use sdl2::keyboard as sdl;
5 use specs::RunNow;
46
5 pub struct Move {
6 pub keycode: sdl::Keycode,
7 pub struct Move<'t> {
8 keys: &'t std::collections::HashSet<sdl::Keycode>,
79 }
810
9 impl<'a> specs::System<'a> for Move {
11 impl<'a, 't> specs::System<'a> for Move<'t> {
1012 type SystemData = (
1113 specs::ReadStorage<'a, Movable>,
12 specs::WriteStorage<'a, Position>,
14 specs::WriteStorage<'a, Velocity>,
1315 );
1416
15 fn run(&mut self, (movable, mut position): Self::SystemData) {
17 fn run(&mut self, (movable, mut velocity): Self::SystemData) {
1618 use specs::Join;
1719
18 for (_, pos) in (&movable, &mut position).join() {
19 match self.keycode {
20 sdl::Keycode::W => pos.y -= 1.0,
21 sdl::Keycode::A => pos.x -= 1.0,
22 sdl::Keycode::S => pos.y += 1.0,
23 sdl::Keycode::D => pos.x += 1.0,
24 _ => (),
20 for (_, vel) in (&movable, &mut velocity).join() {
21 vel.dx = 0.0;
22 vel.dy = 0.0;
23
24 if self.keys.contains(&sdl::Keycode::W) {
25 vel.dy -= 2.0;
26 }
27 if self.keys.contains(&sdl::Keycode::A) {
28 vel.dx -= 2.0;
29 }
30 if self.keys.contains(&sdl::Keycode::S) {
31 vel.dy += 2.0;
32 }
33 if self.keys.contains(&sdl::Keycode::D) {
34 vel.dx += 2.0;
2535 }
2636 }
2737 }
2838 }
39
40
41 pub fn systems(game: &mut MyGame) {
42 Move { keys: &game.keys }.run_now(&game.world.res);
43 }
1 use crate::components::{Velocity, Position};
2 use crate::game::MyGame;
3
4 use specs::RunNow;
5
6 struct Physics;
7
8 impl <'a> specs::System<'a> for Physics {
9 type SystemData = (
10 specs::ReadStorage<'a, Velocity>,
11 specs::WriteStorage<'a, Position>,
12 );
13
14 fn run(&mut self, (velocity, mut position): Self::SystemData) {
15 use specs::Join;
16
17 for (vel, pos) in (&velocity, &mut position).join() {
18 pos.x += vel.dx;
19 pos.y += vel.dy;
20 }
21 }
22 }
23
24
25 pub fn systems(game: &mut MyGame) {
26 Physics.run_now(&game.world.res);
27 }