Browse Source

Split apart into files and also add crappy interaction component

Getty Ritter 5 years ago
parent
commit
138276665b
11 changed files with 281 additions and 151 deletions
  1. 1 0
      .gitignore
  2. 1 0
      Cargo.lock
  3. 2 1
      Cargo.toml
  4. 72 0
      src/components.rs
  5. 14 0
      src/consts.rs
  6. 55 150
      src/main.rs
  7. 61 0
      src/res.rs
  8. 42 0
      src/sys/drawing.rs
  9. 28 0
      src/sys/input.rs
  10. 5 0
      src/sys/mod.rs
  11. 0 0
      src/sys/physics.rs

+ 1 - 0
.gitignore

@@ -1,2 +1,3 @@
 /target
 /target
 **/*.rs.bk*~
 **/*.rs.bk*~
+*~

+ 1 - 0
Cargo.lock

@@ -654,6 +654,7 @@ version = "0.1.0"
 dependencies = [
 dependencies = [
  "ggez 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ggez 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sdl2 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tiled 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tiled 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",

+ 2 - 1
Cargo.toml

@@ -9,4 +9,5 @@ ggez = "0.4.4"
 tiled = "0.8"
 tiled = "0.8"
 itertools = "0.8"
 itertools = "0.8"
 specs = "0.14"
 specs = "0.14"
-specs-derive = "0.4"
+specs-derive = "0.4"
+sdl2 = "0.31"

+ 72 - 0
src/components.rs

@@ -0,0 +1,72 @@
+use specs::{Component, VecStorage, NullStorage};
+
+pub fn register(world: &mut specs::World) {
+    world.register::<Position>();
+    world.register::<Velocity>();
+    world.register::<Sprite>();
+    world.register::<Background>();
+    world.register::<Foreground>();
+    world.register::<Decoration>();
+    world.register::<Movable>();
+}
+
+#[derive(Component, Debug)]
+#[storage(VecStorage)]
+pub struct Position {
+    pub x: f32,
+    pub y: f32,
+}
+
+impl Position {
+    pub fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
+        ggez::nalgebra::Point2::new(self.x * 3.0, self.y * 3.0)
+    }
+}
+
+#[derive(Component, Debug)]
+#[storage(VecStorage)]
+pub struct Velocity {
+    pub dx: f32,
+    pub dy: f32,
+}
+
+impl Velocity {
+    pub fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
+        ggez::nalgebra::Point2::new(self.dx * 3.0, self.dy * 3.0)
+    }
+}
+
+#[derive(Component, Debug)]
+#[storage(VecStorage)]
+pub struct Sprite {
+    pub u: u8,
+    pub v: u8,
+}
+
+impl Sprite {
+    pub fn to_rect(&self) -> ggez::graphics::Rect {
+        ggez::graphics::Rect {
+            x: (1.0 / 32.0) * self.u as f32,
+            y: (1.0 / 32.0) * self.v as f32,
+            w: 1.0 / 32.0,
+            h: 1.0 / 32.0,
+        }
+    }
+}
+
+
+#[derive(Component, Default, Debug)]
+#[storage(NullStorage)]
+pub struct Background;
+
+#[derive(Component, Default, Debug)]
+#[storage(NullStorage)]
+pub struct Foreground;
+
+#[derive(Component, Default, Debug)]
+#[storage(NullStorage)]
+pub struct Decoration;
+
+#[derive(Component, Default, Debug)]
+#[storage(NullStorage)]
+pub struct Movable;

+ 14 - 0
src/consts.rs

@@ -0,0 +1,14 @@
+#![allow(dead_code)]
+
+// constants used elsewhere
+pub const SPEED: u32 = 2;
+pub const TILE_SIZE: f32 = 24.0;
+pub const HALF_TILE: f32 = TILE_SIZE / 2.0;
+pub const QUARTER_TILE: f32 = TILE_SIZE / 4.0;
+pub const BOARD_WIDTH: usize = 16;
+pub const BOARD_HEIGHT: usize = 12;
+pub const WINDOW_WIDTH: u32 = BOARD_WIDTH as u32 * (TILE_SIZE * SCALE) as u32;
+pub const WINDOW_HEIGHT: u32 = BOARD_HEIGHT as u32 * (TILE_SIZE * SCALE) as u32;
+pub const SCALE: f32 = 3.0;
+pub const TILED_TRUE: tiled::PropertyValue =
+    tiled::PropertyValue::BoolValue(true);

+ 55 - 150
src/main.rs

@@ -4,177 +4,76 @@ use ggez::{Context, ContextBuilder, GameResult};
 use ggez::event::{self, EventHandler};
 use ggez::event::{self, EventHandler};
 use ggez::graphics;
 use ggez::graphics;
 
 
-use std::path::Path;
-use specs::{Component, RunNow, System, NullStorage, VecStorage};
-use specs::world::Builder;
-
-#[allow(dead_code)]
-mod consts {
-    pub const SPEED: u32 = 2;
-    pub const TILE_SIZE: u32 = 24;
-    pub const HALF_TILE: u32 = TILE_SIZE / 2;
-    pub const QUARTER_TILE: u32 = TILE_SIZE / 4;
-    pub const BOARD_WIDTH: usize = 16;
-    pub const BOARD_HEIGHT: usize = 12;
-    pub const SCALE: u32 = 3;
-    pub const TILED_TRUE: tiled::PropertyValue =
-        tiled::PropertyValue::BoolValue(true);
-}
-
-#[derive(Component, Debug)]
-#[storage(VecStorage)]
-struct Position {
-    x: f32,
-    y: f32,
-}
-
-impl Position {
-    fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
-        ggez::nalgebra::Point2::new(self.x, self.y)
-    }
-}
+use specs::RunNow;
 
 
-#[derive(Component, Debug)]
-#[storage(VecStorage)]
-struct Sprite {
-    u: u8,
-    v: u8,
-}
+use sdl2::keyboard as sdl;
 
 
-impl Sprite {
-    fn to_rect(&self) -> graphics::Rect {
-        graphics::Rect {
-            x: (1.0 / 32.0) * self.u as f32,
-            y: (1.0 / 32.0) * self.v as f32,
-            w: 1.0 / 32.0,
-            h: 1.0 / 32.0,
-        }
-    }
-}
-
-#[derive(Debug, Copy, Clone)]
-enum DrawLayer {
-    Background,
-    Foreground,
-    Decoration,
-}
-
-static DRAW_LAYERS: [DrawLayer;3] = [
-    DrawLayer::Background,
-    DrawLayer::Foreground,
-    DrawLayer::Decoration,
-];
-
-#[derive(Component, Default, Debug)]
-#[storage(NullStorage)]
-struct Background;
-
-#[derive(Component, Default, Debug)]
-#[storage(NullStorage)]
-struct Foreground;
-
-#[derive(Component, Default, Debug)]
-#[storage(NullStorage)]
-struct Decoration;
-
-fn world_from_file(w: &mut specs::World, path: &Path) {
-    let tiled::Map {
-        layers,
-        ..
-    } = tiled::parse_file(path).unwrap();
-
-    for (phase, layer) in DRAW_LAYERS.iter().zip(layers) {
-        for (row, y) in layer.tiles.iter().zip(0..) {
-            for (&n, x) in row.iter().zip(0..) {
-                if n != 0 {
-                    let x = x as f32 * 24.0;
-                    let y = y as f32 * 24.0;
-                    let u = ((n - 1) % 32) as u8;
-                    let v = ((n - u as u32 - 1) / 32) as u8;
-                    let mut e = w.create_entity()
-                        .with(Position { x, y })
-                        .with(Sprite { u, v });
-                    e = match phase {
-                        DrawLayer::Background => e.with(Background),
-                        DrawLayer::Foreground => e.with(Foreground),
-                        DrawLayer::Decoration => e.with(Decoration),
-                    };
-                    e.build();
-            }
-        }
-    }
-    }
-}
+pub mod consts;
+pub mod components;
+pub mod res;
+pub mod sys;
 
 
 struct MyGame {
 struct MyGame {
     world: specs::World,
     world: specs::World,
     sprites: graphics::spritebatch::SpriteBatch,
     sprites: graphics::spritebatch::SpriteBatch,
 }
 }
 
 
-struct Draw<'t, Phase> {
-    ctx: &'t mut Context,
-    sprites: &'t mut graphics::spritebatch::SpriteBatch,
-    _phase: Phase,
-}
-
-impl<'a, 't, Phase: Component> System<'a> for Draw<'t, Phase> {
-    type SystemData = (
-        specs::ReadStorage<'a, Position>,
-        specs::ReadStorage<'a, Sprite>,
-        specs::ReadStorage<'a, Phase>,
-    );
-
-    fn run(&mut self, (positions, sprites, phase): Self::SystemData) {
-        use specs::Join;
-
-        for (pos, spr, _) in (&positions, &sprites, &phase).join() {
-            let param = graphics::DrawParam {
-                src: spr.to_rect(),
-                dest: pos.to_point(),
-                ..Default::default()
-            };
-            self.sprites.add(param);
-            graphics::draw(
-                self.ctx,
-                self.sprites,
-                ggez::nalgebra::Point2::new(0.0, 0.0),
-                0.0).unwrap();
-            self.sprites.clear();
-        }
-    }
-}
-
 impl EventHandler for MyGame {
 impl EventHandler for MyGame {
+
     fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
     fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
         Ok(())
         Ok(())
     }
     }
 
 
     fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
     fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
-        use ggez::graphics as g;
-        use ggez::nalgebra as n;
-        g::set_background_color(ctx, g::BLACK);
-        g::clear(ctx);
-
-        Draw { ctx, sprites: &mut self.sprites, _phase: Background }.run_now(&self.world.res);
-        Draw { ctx, sprites: &mut self.sprites, _phase: Foreground }.run_now(&self.world.res);
-        Draw { ctx, sprites: &mut self.sprites, _phase: Decoration }.run_now(&self.world.res);
-
-        g::draw(ctx, &self.sprites, n::Point2::new(0.0, 0.0), 0.0)?;
+        ggez::graphics::set_background_color(ctx, ggez::graphics::BLACK);
+        ggez::graphics::clear(ctx);
+
+        sys::Draw {
+            ctx,
+            sprites: &mut self.sprites,
+            _phase: components::Background,
+        }.run_now(&self.world.res);
+        sys::Draw {
+            ctx,
+            sprites: &mut self.sprites,
+            _phase: components::Foreground,
+        }.run_now(&self.world.res);
+        sys::Draw {
+            ctx,
+            sprites: &mut self.sprites,
+            _phase: components::Decoration,
+        }.run_now(&self.world.res);
+
+        ggez::graphics::draw(
+            ctx,
+            &self.sprites,
+            ggez::nalgebra::Point2::new(0.0, 0.0),
+            0.0
+        )?;
         self.sprites.clear();
         self.sprites.clear();
-        g::present(ctx);
+        ggez::graphics::present(ctx);
         Ok(())
         Ok(())
     }
     }
+
+    fn key_down_event(
+        &mut self,
+        ctx: &mut Context,
+        keycode: sdl::Keycode,
+        _keymod: sdl::Mod,
+        _repeat: bool,
+    ) {
+        if keycode == sdl::Keycode::Escape {
+            ctx.quit().expect("Should never fail");
+        }
+        sys::Move { keycode }.run_now(&self.world.res);
+    }
 }
 }
 
 
 fn main() -> Result<(), ggez::error::GameError> {
 fn main() -> Result<(), ggez::error::GameError> {
     let mut world = specs::World::new();
     let mut world = specs::World::new();
-    world.register::<Position>();
-    world.register::<Sprite>();
-    world.register::<Background>();
-    world.register::<Foreground>();
-    world.register::<Decoration>();
+    components::register(&mut world);
 
 
-    world_from_file(&mut world, &Path::new("assets/main.tmx"));
+    res::world_from_file(&mut world, "assets/main.tmx");
 
 
     // Make a Context and an EventLoop.
     // Make a Context and an EventLoop.
     let mut ctx = ContextBuilder::new("game", "me")
     let mut ctx = ContextBuilder::new("game", "me")
@@ -184,9 +83,15 @@ fn main() -> Result<(), ggez::error::GameError> {
             path.push("assets");
             path.push("assets");
             path
             path
         })
         })
+        .window_mode(ggez::conf::WindowMode {
+            width: consts::WINDOW_WIDTH,
+            height: consts::WINDOW_HEIGHT,
+            ..Default::default()
+        })
         .build()?;
         .build()?;
     let image = graphics::Image::new(&mut ctx, "/spritesheet.png")?;
     let image = graphics::Image::new(&mut ctx, "/spritesheet.png")?;
-    let sprites = graphics::spritebatch::SpriteBatch::new(image);
+    let mut sprites = graphics::spritebatch::SpriteBatch::new(image);
+    sprites.set_filter(ggez::graphics::FilterMode::Nearest);
 
 
     let mut my_game = MyGame {
     let mut my_game = MyGame {
         world,
         world,

+ 61 - 0
src/res.rs

@@ -0,0 +1,61 @@
+use crate::consts;
+use crate::components::*;
+
+use specs::world::Builder;
+use std::path::Path;
+
+
+#[derive(Debug, Copy, Clone)]
+enum DrawLayer {
+    Background,
+    Foreground,
+    Decoration,
+}
+
+static DRAW_LAYERS: [DrawLayer;3] = [
+    DrawLayer::Background,
+    DrawLayer::Foreground,
+    DrawLayer::Decoration,
+];
+
+
+pub fn world_from_file<P: AsRef<Path>>(w: &mut specs::World, path: P) {
+    let tiled::Map {
+        layers,
+        ..
+    } = tiled::parse_file(path.as_ref()).unwrap();
+
+    for (phase, layer) in DRAW_LAYERS.iter().zip(layers) {
+        for (row, y) in layer.tiles.iter().zip(0..) {
+            for (&n, x) in row.iter().zip(0..) {
+                if n != 0 {
+                    let x = x as f32 * consts::TILE_SIZE;
+                    let y = y as f32 * consts::TILE_SIZE;
+                    let u = ((n - 1) % 32) as u8;
+                    let v = ((n - u as u32 - 1) / 32) as u8;
+                    let mut e = w.create_entity()
+                        .with(Position { x, y })
+                        .with(Sprite { u, v });
+                    e = match phase {
+                        DrawLayer::Background => e.with(Background),
+                        DrawLayer::Foreground => e.with(Foreground),
+                        DrawLayer::Decoration => e.with(Decoration),
+                    };
+                    e.build();
+                }
+            }
+        }
+    }
+
+    // create the player
+    w.create_entity()
+        .with(Position {
+            x: 3.0 * consts::TILE_SIZE,
+            y: 3.0 * consts::TILE_SIZE,
+        })
+        .with(Sprite { u: 8, v: 0 })
+        .with(Velocity { dx: 0.0, dy: 0.0 })
+        .with(Foreground)
+        .with(Movable)
+        .build();
+}

+ 42 - 0
src/sys/drawing.rs

@@ -0,0 +1,42 @@
+use crate::consts;
+use crate::components::{Position,Sprite};
+
+use ggez::{
+    Context,
+    graphics::spritebatch::SpriteBatch,
+};
+use ggez::graphics;
+
+pub struct Draw<'t, Phase> {
+    pub ctx: &'t mut Context,
+    pub sprites: &'t mut SpriteBatch,
+    pub _phase: Phase,
+}
+
+impl<'a, 't, Phase: specs::Component> specs::System<'a> for Draw<'t, Phase> {
+    type SystemData = (
+        specs::ReadStorage<'a, Position>,
+        specs::ReadStorage<'a, Sprite>,
+        specs::ReadStorage<'a, Phase>,
+    );
+
+    fn run(&mut self, (positions, sprites, phase): Self::SystemData) {
+        use specs::Join;
+
+        for (pos, spr, _) in (&positions, &sprites, &phase).join() {
+            let param = graphics::DrawParam {
+                src: spr.to_rect(),
+                dest: pos.to_point(),
+                scale: ggez::nalgebra::Point2::new(consts::SCALE, consts::SCALE),
+                ..Default::default()
+            };
+            self.sprites.add(param);
+            graphics::draw(
+                self.ctx,
+                self.sprites,
+                ggez::nalgebra::Point2::new(0.0, 0.0),
+                0.0).unwrap();
+            self.sprites.clear();
+        }
+    }
+}

+ 28 - 0
src/sys/input.rs

@@ -0,0 +1,28 @@
+use crate::components::{Movable, Position};
+
+use sdl2::keyboard as sdl;
+
+pub struct Move {
+    pub keycode: sdl::Keycode,
+}
+
+impl<'a> specs::System<'a> for Move {
+    type SystemData = (
+        specs::ReadStorage<'a, Movable>,
+        specs::WriteStorage<'a, Position>,
+    );
+
+    fn run(&mut self, (movable, mut position): Self::SystemData) {
+        use specs::Join;
+
+        for (_, pos) in (&movable, &mut position).join() {
+            match self.keycode {
+                sdl::Keycode::W => pos.y -= 1.0,
+                sdl::Keycode::A => pos.x -= 1.0,
+                sdl::Keycode::S => pos.y += 1.0,
+                sdl::Keycode::D => pos.x += 1.0,
+                _ => (),
+            }
+        }
+    }
+}

+ 5 - 0
src/sys/mod.rs

@@ -0,0 +1,5 @@
+pub mod physics;
+pub mod input;
+pub mod drawing;
+pub use input::*;
+pub use drawing::*;

+ 0 - 0
src/sys/physics.rs