gdritter repos wenaglia / 1382766
Split apart into files and also add crappy interaction component Getty Ritter 5 years ago
11 changed file(s) with 279 addition(s) and 149 deletion(s). Collapse all Expand all
11 /target
22 **/*.rs.bk*~
3 *~
654654 dependencies = [
655655 "ggez 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
656656 "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)",
657658 "specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
658659 "specs-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
659660 "tiled 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
99 tiled = "0.8"
1010 itertools = "0.8"
1111 specs = "0.14"
12 specs-derive = "0.4"
12 specs-derive = "0.4"
13 sdl2 = "0.31"
1 use specs::{Component, VecStorage, NullStorage};
2
3 pub fn register(world: &mut specs::World) {
4 world.register::<Position>();
5 world.register::<Velocity>();
6 world.register::<Sprite>();
7 world.register::<Background>();
8 world.register::<Foreground>();
9 world.register::<Decoration>();
10 world.register::<Movable>();
11 }
12
13 #[derive(Component, Debug)]
14 #[storage(VecStorage)]
15 pub struct Position {
16 pub x: f32,
17 pub y: f32,
18 }
19
20 impl Position {
21 pub fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
22 ggez::nalgebra::Point2::new(self.x * 3.0, self.y * 3.0)
23 }
24 }
25
26 #[derive(Component, Debug)]
27 #[storage(VecStorage)]
28 pub struct Velocity {
29 pub dx: f32,
30 pub dy: f32,
31 }
32
33 impl Velocity {
34 pub fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
35 ggez::nalgebra::Point2::new(self.dx * 3.0, self.dy * 3.0)
36 }
37 }
38
39 #[derive(Component, Debug)]
40 #[storage(VecStorage)]
41 pub struct Sprite {
42 pub u: u8,
43 pub v: u8,
44 }
45
46 impl Sprite {
47 pub fn to_rect(&self) -> ggez::graphics::Rect {
48 ggez::graphics::Rect {
49 x: (1.0 / 32.0) * self.u as f32,
50 y: (1.0 / 32.0) * self.v as f32,
51 w: 1.0 / 32.0,
52 h: 1.0 / 32.0,
53 }
54 }
55 }
56
57
58 #[derive(Component, Default, Debug)]
59 #[storage(NullStorage)]
60 pub struct Background;
61
62 #[derive(Component, Default, Debug)]
63 #[storage(NullStorage)]
64 pub struct Foreground;
65
66 #[derive(Component, Default, Debug)]
67 #[storage(NullStorage)]
68 pub struct Decoration;
69
70 #[derive(Component, Default, Debug)]
71 #[storage(NullStorage)]
72 pub struct Movable;
1 #![allow(dead_code)]
2
3 // constants used elsewhere
4 pub const SPEED: u32 = 2;
5 pub const TILE_SIZE: f32 = 24.0;
6 pub const HALF_TILE: f32 = TILE_SIZE / 2.0;
7 pub const QUARTER_TILE: f32 = TILE_SIZE / 4.0;
8 pub const BOARD_WIDTH: usize = 16;
9 pub const BOARD_HEIGHT: usize = 12;
10 pub const WINDOW_WIDTH: u32 = BOARD_WIDTH as u32 * (TILE_SIZE * SCALE) as u32;
11 pub const WINDOW_HEIGHT: u32 = BOARD_HEIGHT as u32 * (TILE_SIZE * SCALE) as u32;
12 pub const SCALE: f32 = 3.0;
13 pub const TILED_TRUE: tiled::PropertyValue =
14 tiled::PropertyValue::BoolValue(true);
44 use ggez::event::{self, EventHandler};
55 use ggez::graphics;
66
7 use std::path::Path;
8 use specs::{Component, RunNow, System, NullStorage, VecStorage};
9 use specs::world::Builder;
7 use specs::RunNow;
108
11 #[allow(dead_code)]
12 mod consts {
13 pub const SPEED: u32 = 2;
14 pub const TILE_SIZE: u32 = 24;
15 pub const HALF_TILE: u32 = TILE_SIZE / 2;
16 pub const QUARTER_TILE: u32 = TILE_SIZE / 4;
17 pub const BOARD_WIDTH: usize = 16;
18 pub const BOARD_HEIGHT: usize = 12;
19 pub const SCALE: u32 = 3;
20 pub const TILED_TRUE: tiled::PropertyValue =
21 tiled::PropertyValue::BoolValue(true);
22 }
9 use sdl2::keyboard as sdl;
2310
24 #[derive(Component, Debug)]
25 #[storage(VecStorage)]
26 struct Position {
27 x: f32,
28 y: f32,
29 }
30
31 impl Position {
32 fn to_point(&self) -> ggez::nalgebra::Point2<f32> {
33 ggez::nalgebra::Point2::new(self.x, self.y)
34 }
35 }
36
37 #[derive(Component, Debug)]
38 #[storage(VecStorage)]
39 struct Sprite {
40 u: u8,
41 v: u8,
42 }
43
44 impl Sprite {
45 fn to_rect(&self) -> graphics::Rect {
46 graphics::Rect {
47 x: (1.0 / 32.0) * self.u as f32,
48 y: (1.0 / 32.0) * self.v as f32,
49 w: 1.0 / 32.0,
50 h: 1.0 / 32.0,
51 }
52 }
53 }
54
55 #[derive(Debug, Copy, Clone)]
56 enum DrawLayer {
57 Background,
58 Foreground,
59 Decoration,
60 }
61
62 static DRAW_LAYERS: [DrawLayer;3] = [
63 DrawLayer::Background,
64 DrawLayer::Foreground,
65 DrawLayer::Decoration,
66 ];
67
68 #[derive(Component, Default, Debug)]
69 #[storage(NullStorage)]
70 struct Background;
71
72 #[derive(Component, Default, Debug)]
73 #[storage(NullStorage)]
74 struct Foreground;
75
76 #[derive(Component, Default, Debug)]
77 #[storage(NullStorage)]
78 struct Decoration;
79
80 fn world_from_file(w: &mut specs::World, path: &Path) {
81 let tiled::Map {
82 layers,
83 ..
84 } = tiled::parse_file(path).unwrap();
85
86 for (phase, layer) in DRAW_LAYERS.iter().zip(layers) {
87 for (row, y) in layer.tiles.iter().zip(0..) {
88 for (&n, x) in row.iter().zip(0..) {
89 if n != 0 {
90 let x = x as f32 * 24.0;
91 let y = y as f32 * 24.0;
92 let u = ((n - 1) % 32) as u8;
93 let v = ((n - u as u32 - 1) / 32) as u8;
94 let mut e = w.create_entity()
95 .with(Position { x, y })
96 .with(Sprite { u, v });
97 e = match phase {
98 DrawLayer::Background => e.with(Background),
99 DrawLayer::Foreground => e.with(Foreground),
100 DrawLayer::Decoration => e.with(Decoration),
101 };
102 e.build();
103 }
104 }
105 }
106 }
107 }
11 pub mod consts;
12 pub mod components;
13 pub mod res;
14 pub mod sys;
10815
10916 struct MyGame {
11017 world: specs::World,
11118 sprites: graphics::spritebatch::SpriteBatch,
11219 }
11320
114 struct Draw<'t, Phase> {
115 ctx: &'t mut Context,
116 sprites: &'t mut graphics::spritebatch::SpriteBatch,
117 _phase: Phase,
118 }
21 impl EventHandler for MyGame {
11922
120 impl<'a, 't, Phase: Component> System<'a> for Draw<'t, Phase> {
121 type SystemData = (
122 specs::ReadStorage<'a, Position>,
123 specs::ReadStorage<'a, Sprite>,
124 specs::ReadStorage<'a, Phase>,
125 );
126
127 fn run(&mut self, (positions, sprites, phase): Self::SystemData) {
128 use specs::Join;
129
130 for (pos, spr, _) in (&positions, &sprites, &phase).join() {
131 let param = graphics::DrawParam {
132 src: spr.to_rect(),
133 dest: pos.to_point(),
134 ..Default::default()
135 };
136 self.sprites.add(param);
137 graphics::draw(
138 self.ctx,
139 self.sprites,
140 ggez::nalgebra::Point2::new(0.0, 0.0),
141 0.0).unwrap();
142 self.sprites.clear();
143 }
144 }
145 }
146
147 impl EventHandler for MyGame {
14823 fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
14924 Ok(())
15025 }
15126
15227 fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
153 use ggez::graphics as g;
154 use ggez::nalgebra as n;
155 g::set_background_color(ctx, g::BLACK);
156 g::clear(ctx);
28 ggez::graphics::set_background_color(ctx, ggez::graphics::BLACK);
29 ggez::graphics::clear(ctx);
15730
158 Draw { ctx, sprites: &mut self.sprites, _phase: Background }.run_now(&self.world.res);
159 Draw { ctx, sprites: &mut self.sprites, _phase: Foreground }.run_now(&self.world.res);
160 Draw { ctx, sprites: &mut self.sprites, _phase: Decoration }.run_now(&self.world.res);
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);
16146
162 g::draw(ctx, &self.sprites, n::Point2::new(0.0, 0.0), 0.0)?;
47 ggez::graphics::draw(
48 ctx,
49 &self.sprites,
50 ggez::nalgebra::Point2::new(0.0, 0.0),
51 0.0
52 )?;
16353 self.sprites.clear();
164 g::present(ctx);
54 ggez::graphics::present(ctx);
16555 Ok(())
56 }
57
58 fn key_down_event(
59 &mut self,
60 ctx: &mut Context,
61 keycode: sdl::Keycode,
62 _keymod: sdl::Mod,
63 _repeat: bool,
64 ) {
65 if keycode == sdl::Keycode::Escape {
66 ctx.quit().expect("Should never fail");
67 }
68 sys::Move { keycode }.run_now(&self.world.res);
16669 }
16770 }
16871
16972 fn main() -> Result<(), ggez::error::GameError> {
17073 let mut world = specs::World::new();
171 world.register::<Position>();
172 world.register::<Sprite>();
173 world.register::<Background>();
174 world.register::<Foreground>();
175 world.register::<Decoration>();
74 components::register(&mut world);
17675
177 world_from_file(&mut world, &Path::new("assets/main.tmx"));
76 res::world_from_file(&mut world, "assets/main.tmx");
17877
17978 // Make a Context and an EventLoop.
18079 let mut ctx = ContextBuilder::new("game", "me")
18483 path.push("assets");
18584 path
18685 })
86 .window_mode(ggez::conf::WindowMode {
87 width: consts::WINDOW_WIDTH,
88 height: consts::WINDOW_HEIGHT,
89 ..Default::default()
90 })
18791 .build()?;
18892 let image = graphics::Image::new(&mut ctx, "/spritesheet.png")?;
189 let sprites = graphics::spritebatch::SpriteBatch::new(image);
93 let mut sprites = graphics::spritebatch::SpriteBatch::new(image);
94 sprites.set_filter(ggez::graphics::FilterMode::Nearest);
19095
19196 let mut my_game = MyGame {
19297 world,
1 use crate::consts;
2 use crate::components::*;
3
4 use specs::world::Builder;
5 use std::path::Path;
6
7
8 #[derive(Debug, Copy, Clone)]
9 enum DrawLayer {
10 Background,
11 Foreground,
12 Decoration,
13 }
14
15 static DRAW_LAYERS: [DrawLayer;3] = [
16 DrawLayer::Background,
17 DrawLayer::Foreground,
18 DrawLayer::Decoration,
19 ];
20
21
22 pub fn world_from_file<P: AsRef<Path>>(w: &mut specs::World, path: P) {
23 let tiled::Map {
24 layers,
25 ..
26 } = tiled::parse_file(path.as_ref()).unwrap();
27
28 for (phase, layer) in DRAW_LAYERS.iter().zip(layers) {
29 for (row, y) in layer.tiles.iter().zip(0..) {
30 for (&n, x) in row.iter().zip(0..) {
31 if n != 0 {
32 let x = x as f32 * consts::TILE_SIZE;
33 let y = y as f32 * consts::TILE_SIZE;
34 let u = ((n - 1) % 32) as u8;
35 let v = ((n - u as u32 - 1) / 32) as u8;
36 let mut e = w.create_entity()
37 .with(Position { x, y })
38 .with(Sprite { u, v });
39 e = match phase {
40 DrawLayer::Background => e.with(Background),
41 DrawLayer::Foreground => e.with(Foreground),
42 DrawLayer::Decoration => e.with(Decoration),
43 };
44 e.build();
45 }
46 }
47 }
48 }
49
50 // create the player
51 w.create_entity()
52 .with(Position {
53 x: 3.0 * consts::TILE_SIZE,
54 y: 3.0 * consts::TILE_SIZE,
55 })
56 .with(Sprite { u: 8, v: 0 })
57 .with(Velocity { dx: 0.0, dy: 0.0 })
58 .with(Foreground)
59 .with(Movable)
60 .build();
61 }
1 use crate::consts;
2 use crate::components::{Position,Sprite};
3
4 use ggez::{
5 Context,
6 graphics::spritebatch::SpriteBatch,
7 };
8 use ggez::graphics;
9
10 pub struct Draw<'t, Phase> {
11 pub ctx: &'t mut Context,
12 pub sprites: &'t mut SpriteBatch,
13 pub _phase: Phase,
14 }
15
16 impl<'a, 't, Phase: specs::Component> specs::System<'a> for Draw<'t, Phase> {
17 type SystemData = (
18 specs::ReadStorage<'a, Position>,
19 specs::ReadStorage<'a, Sprite>,
20 specs::ReadStorage<'a, Phase>,
21 );
22
23 fn run(&mut self, (positions, sprites, phase): Self::SystemData) {
24 use specs::Join;
25
26 for (pos, spr, _) in (&positions, &sprites, &phase).join() {
27 let param = graphics::DrawParam {
28 src: spr.to_rect(),
29 dest: pos.to_point(),
30 scale: ggez::nalgebra::Point2::new(consts::SCALE, consts::SCALE),
31 ..Default::default()
32 };
33 self.sprites.add(param);
34 graphics::draw(
35 self.ctx,
36 self.sprites,
37 ggez::nalgebra::Point2::new(0.0, 0.0),
38 0.0).unwrap();
39 self.sprites.clear();
40 }
41 }
42 }
1 use crate::components::{Movable, Position};
2
3 use sdl2::keyboard as sdl;
4
5 pub struct Move {
6 pub keycode: sdl::Keycode,
7 }
8
9 impl<'a> specs::System<'a> for Move {
10 type SystemData = (
11 specs::ReadStorage<'a, Movable>,
12 specs::WriteStorage<'a, Position>,
13 );
14
15 fn run(&mut self, (movable, mut position): Self::SystemData) {
16 use specs::Join;
17
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 _ => (),
25 }
26 }
27 }
28 }
1 pub mod physics;
2 pub mod input;
3 pub mod drawing;
4 pub use input::*;
5 pub use drawing::*;
(New empty file)