Browse Source

some tileset changes and some preliminary collision code

Getty Ritter 5 years ago
parent
commit
3435b15831
9 changed files with 94 additions and 27 deletions
  1. 2 2
      assets/animaltransiro.tsx
  2. 8 8
      assets/main.tmx
  3. BIN
      assets/spritesheet.png
  4. 19 0
      src/components.rs
  5. 2 3
      src/main.rs
  6. 10 1
      src/res.rs
  7. 4 4
      src/sys/drawing.rs
  8. 1 1
      src/sys/input.rs
  9. 48 8
      src/sys/physics.rs

+ 2 - 2
assets/animaltransiro.tsx

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tileset name="animaltransiro" tilewidth="24" tileheight="24" tilecount="1024" columns="32">
- <image source="../tiles/spritesheet.png" width="768" height="768"/>
+<tileset version="1.2" tiledversion="1.2.3" name="animaltransiro" tilewidth="24" tileheight="24" tilecount="1024" columns="32">
+ <image source="spritesheet.png" width="768" height="768"/>
  <terraintypes>
   <terrain name="Grass" tile="0"/>
   <terrain name="Dirt" tile="70"/>

+ 8 - 8
assets/main.tmx

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<map version="1.0.0" orientation="orthogonal" renderorder="right-down" width="16" height="12" tilewidth="24" tileheight="24" nextobjectid="10">
+<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="16" height="12" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="10">
  <properties>
   <property name="south" value="south"/>
   <property name="west" value="west"/>
  </properties>
  <tileset firstgid="1" source="animaltransiro.tsx"/>
- <layer name="tiles" width="16" height="12">
+ <layer id="1" name="tiles" width="16" height="12">
   <data encoding="csv">
 1,1,1,1,1,1,33,1,1,1,1,1,33,1,1,1,
 1,1,1,1,1,43,45,1,1,1,1,1,1,43,44,45,
@@ -15,13 +15,13 @@
 44,79,77,1,1,1,75,76,77,1,70,73,40,75,77,1,
 76,76,78,45,1,33,107,108,109,1,70,71,72,107,109,1,
 76,76,46,109,1,1,38,39,39,39,74,71,72,33,1,1,
-108,108,109,1,1,38,74,41,103,42,71,41,104,1,1,1,
-1,1,1,1,38,74,71,72,38,74,41,104,1,1,33,1,
-1,1,33,1,102,103,42,73,74,41,104,1,1,1,1,1,
+108,108,109,1,1,38,74,103,42,71,71,41,104,1,1,1,
+1,1,1,1,38,74,72,1,70,71,41,104,1,1,33,1,
+1,1,33,1,102,103,73,39,74,41,104,1,1,1,1,1,
 1,1,1,1,1,1,70,71,71,72,1,1,1,1,1,1
 </data>
  </layer>
- <layer name="entities" width="16" height="12">
+ <layer id="2" name="entities" width="16" height="12">
   <data encoding="csv">
 0,26,27,28,29,0,0,0,30,31,32,0,0,0,0,0,
 0,58,59,60,61,0,0,37,62,63,64,0,0,0,0,0,
@@ -37,7 +37,7 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 </data>
  </layer>
- <layer name="decoration" width="16" height="12">
+ <layer id="3" name="decoration" width="16" height="12">
   <data encoding="csv">
 0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -53,7 +53,7 @@
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 </data>
  </layer>
- <objectgroup name="meta">
+ <objectgroup id="4" name="meta">
   <object id="2" x="96" y="72" width="24" height="24">
    <properties>
     <property name="signText" value="Bonvenon al la kafejo!"/>

BIN
assets/spritesheet.png


+ 19 - 0
src/components.rs

@@ -9,6 +9,8 @@ pub fn register(world: &mut specs::World) {
     world.register::<Foreground>();
     world.register::<Decoration>();
     world.register::<Controlled>();
+    world.register::<Collision>();
+    world.register::<Blocking>();
 }
 
 /// The `Position` component represents (in world coordinates) a thing
@@ -26,6 +28,19 @@ impl Position {
     pub fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
         ggez::nalgebra::Point2::new(self.x * 3.0, self.y * 3.0)
     }
+
+    pub fn to_grid(&self) -> (i32, i32) {
+        ((self.x / 24.0) as i32,
+         (self.y / 24.0) as i32,
+        )
+    }
+
+    pub fn moved(&self, vel: &Velocity) -> Position {
+        Position {
+            x: self.x + vel.dx,
+            y: self.x + vel.dy,
+        }
+    }
 }
 
 /// The `Velocity` componenent is present on any entity that moves
@@ -92,3 +107,7 @@ pub struct Controlled;
 pub struct Collision {
     pub has_collision: bool
 }
+
+#[derive(Component, Default, Debug)]
+#[storage(NullStorage)]
+pub struct Blocking;

+ 2 - 3
src/main.rs

@@ -10,7 +10,7 @@ use ggez::{
 use sdl2::keyboard as sdl;
 
 pub mod consts;
-pub mod components;
+pub mod com;
 pub mod game;
 pub mod res;
 pub mod sys;
@@ -18,7 +18,6 @@ pub mod sys;
 use game::MyGame;
 
 impl EventHandler for MyGame {
-
     fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
         sys::input::systems(self);
         sys::physics::systems(self);
@@ -55,7 +54,7 @@ impl EventHandler for MyGame {
 
 fn main() -> Result<(), ggez::error::GameError> {
     let mut world = specs::World::new();
-    components::register(&mut world);
+    com::register(&mut world);
 
     res::world_from_file(&mut world, "assets/main.tmx");
 

+ 10 - 1
src/res.rs

@@ -1,5 +1,5 @@
 use crate::consts;
-use crate::components::*;
+use crate::com::*;
 
 use specs::world::Builder;
 use std::path::Path;
@@ -47,6 +47,7 @@ static DRAW_LAYERS: [DrawLayer;3] = [
 pub fn world_from_file<P: AsRef<Path>>(w: &mut specs::World, path: P) {
     let tiled::Map {
         layers,
+        tilesets,
         ..
     } = tiled::parse_file(path.as_ref()).unwrap();
 
@@ -66,6 +67,13 @@ pub fn world_from_file<P: AsRef<Path>>(w: &mut specs::World, path: P) {
                         DrawLayer::Foreground => e.with(Foreground),
                         DrawLayer::Decoration => e.with(Decoration),
                     };
+
+                    let e = if tilesets[0].tiles[n as usize].properties["pass"] ==
+                        tiled::PropertyValue::BoolValue(false) {
+                        e.with(Blocking)
+                        } else {
+                            e
+                        };
                     e.build();
                 }
             }
@@ -82,5 +90,6 @@ pub fn world_from_file<P: AsRef<Path>>(w: &mut specs::World, path: P) {
         .with(Velocity { dx: 0.0, dy: 0.0 })
         .with(Foreground)
         .with(Controlled)
+        .with(Collision { has_collision: false })
         .build();
 }

+ 4 - 4
src/sys/drawing.rs

@@ -1,5 +1,5 @@
 use crate::consts;
-use crate::components::{self,Position,Sprite};
+use crate::com::{self,Position,Sprite};
 use crate::game::MyGame;
 
 use ggez::{
@@ -53,15 +53,15 @@ pub fn systems(game: &mut MyGame, ctx: &mut Context) -> ggez::GameResult<()> {
 
     Draw {
         ctx,
-        _phase: components::Background,
+        _phase: com::Background,
     }.run_now(&game.world.res);
     Draw {
         ctx,
-        _phase: components::Foreground,
+        _phase: com::Foreground,
     }.run_now(&game.world.res);
     Draw {
         ctx,
-        _phase: components::Decoration,
+        _phase: com::Decoration,
     }.run_now(&game.world.res);
 
     graphics::present(ctx);

+ 1 - 1
src/sys/input.rs

@@ -1,4 +1,4 @@
-use crate::components::{Controlled, Velocity};
+use crate::com::{Controlled, Velocity};
 use crate::game::MyGame;
 use crate::res::KeySet;
 

+ 48 - 8
src/sys/physics.rs

@@ -1,27 +1,67 @@
-use crate::components::{Velocity, Position};
+use crate::com::{Blocking, Collision, Velocity, Position};
 use crate::game::MyGame;
 
-use specs::RunNow;
+use specs::{Join,RunNow};
+
+struct Intersection;
+
+impl<'a> specs::System<'a> for Intersection {
+    type SystemData = (
+        specs::Entities<'a>,
+        specs::ReadStorage<'a, Position>,
+        specs::ReadStorage<'a, Velocity>,
+        specs::ReadStorage<'a, Blocking>,
+        specs::WriteStorage<'a, Collision>,
+    );
+
+    fn run(&mut self, (entity, position, velocity, blocking, mut collision): Self::SystemData) {
+        let mut spacemap = std::collections::HashMap::new();
+        for (e, pos, _) in (&entity, &position, &blocking).join() {
+            spacemap.insert(pos.to_grid(), e);
+        }
+
+        for (pos, vel, col) in (&position, &velocity, &mut collision).join() {
+            if let Some(_) = spacemap.get(&pos.moved(vel).to_grid()) {
+                col.has_collision = true;
+            }
+        }
+    }
+}
 
 struct Physics;
 
 impl <'a> specs::System<'a> for Physics {
     type SystemData = (
         specs::ReadStorage<'a, Velocity>,
+        specs::ReadStorage<'a, Collision>,
         specs::WriteStorage<'a, Position>,
     );
 
-    fn run(&mut self, (velocity, mut position): Self::SystemData) {
-        use specs::Join;
-
-        for (vel, pos) in (&velocity, &mut position).join() {
-            pos.x += vel.dx;
-            pos.y += vel.dy;
+    fn run(&mut self, (velocity, collision, mut position): Self::SystemData) {
+        for (vel, col, pos) in (&velocity, &collision, &mut position).join() {
+            if !col.has_collision {
+                pos.x += vel.dx;
+                pos.y += vel.dy;
+            }
         }
     }
 }
 
+struct ResetCollision;
+
+impl<'a> specs::System<'a> for ResetCollision {
+    type SystemData =
+        specs::WriteStorage<'a, Collision>;
+
+    fn run(&mut self, mut collision: Self::SystemData) {
+        for mut e in (&mut collision).join() {
+            e.has_collision = false;
+        }
+    }
+}
 
 pub fn systems(game: &mut MyGame) {
+    Intersection.run_now(&game.world.res);
     Physics.run_now(&game.world.res);
+    ResetCollision.run_now(&game.world.res);
 }