rename com to components
Getty Ritter
6 years ago
| 1 | use specs::world::WorldExt; | |
| 2 | use specs::{Component, NullStorage, VecStorage}; | |
| 3 | use crate::types::World; | |
| 4 | ||
| 5 | /// Register all the components with the world. | |
| 6 | pub fn register(world: &mut specs::World) { | |
| 7 | world.register::<Position>(); | |
| 8 | world.register::<Velocity>(); | |
| 9 | world.register::<Sprite>(); | |
| 10 | world.register::<Background>(); | |
| 11 | world.register::<Foreground>(); | |
| 12 | world.register::<Decoration>(); | |
| 13 | world.register::<Controlled>(); | |
| 14 | world.register::<Collision>(); | |
| 15 | world.register::<Blocking>(); | |
| 16 | } | |
| 17 | ||
| 18 | /// The `Position` component represents (in world coordinates) a thing | |
| 19 | /// that has a position in the world, measured from the top-left of | |
| 20 | /// the thing. | |
| 21 | #[derive(Component, Debug, Clone)] | |
| 22 | #[storage(VecStorage)] | |
| 23 | pub struct Position { | |
| 24 | pub x: f32, | |
| 25 | pub y: f32, | |
| 26 | } | |
| 27 | ||
| 28 | impl Position { | |
| 29 | /// Convert a `Position` to a screen point | |
| 30 | pub fn to_point(&self) -> mint::Point2<f32> { | |
| 31 | mint::Point2 { | |
| 32 | x: self.x * 3.0, | |
| 33 | y: self.y * 3.0, | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | pub fn to_grid(&self) -> (i32, i32) { | |
| 38 | ((self.x / 24.0) as i32, (self.y / 24.0) as i32) | |
| 39 | } | |
| 40 | ||
| 41 | pub fn moved(&self, vel: &Velocity) -> Position { | |
| 42 | Position { | |
| 43 | x: self.x + vel.dx, | |
| 44 | y: self.y + vel.dy, | |
| 45 | } | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | /// The `Velocity` componenent is present on any entity that moves | |
| 50 | /// through the world, and represents its rate of change per | |
| 51 | /// time-unit. | |
| 52 | #[derive(Component, Debug)] | |
| 53 | #[storage(VecStorage)] | |
| 54 | pub struct Velocity { | |
| 55 | pub dx: f32, | |
| 56 | pub dy: f32, | |
| 57 | } | |
| 58 | ||
| 59 | /// The `Sprite` components represents the current display location of | |
| 60 | /// a sprite in the spritesheet. | |
| 61 | #[derive(Component, Debug)] | |
| 62 | #[storage(VecStorage)] | |
| 63 | pub struct Sprite { | |
| 64 | pub u: u8, | |
| 65 | pub v: u8, | |
| 66 | } | |
| 67 | ||
| 68 | impl Sprite { | |
| 69 | /// Convert a `Sprite` into the rectangle that specifies the | |
| 70 | /// sprite location on the spritesheet | |
| 71 | pub fn to_rect(&self) -> ggez::graphics::Rect { | |
| 72 | ggez::graphics::Rect { | |
| 73 | x: (1.0 / 32.0) * self.u as f32, | |
| 74 | y: (1.0 / 32.0) * self.v as f32, | |
| 75 | w: 1.0 / 32.0, | |
| 76 | h: 1.0 / 32.0, | |
| 77 | } | |
| 78 | } | |
| 79 | } | |
| 80 | ||
| 81 | /// A drawing-phase component: represents tiles that appear in the | |
| 82 | /// background of everything. | |
| 83 | #[derive(Component, Default, Debug)] | |
| 84 | #[storage(NullStorage)] | |
| 85 | pub struct Background; | |
| 86 | ||
| 87 | /// A drawing-phase component: represents tiles which appear in the | |
| 88 | /// foreground, possibly entities. | |
| 89 | #[derive(Component, Default, Debug)] | |
| 90 | #[storage(NullStorage)] | |
| 91 | pub struct Foreground; | |
| 92 | ||
| 93 | /// A drawing-phase component: represents tiles which appear on top of | |
| 94 | /// everything else, such as the tops of trees or roofs of houses. | |
| 95 | #[derive(Component, Default, Debug)] | |
| 96 | #[storage(NullStorage)] | |
| 97 | pub struct Decoration; | |
| 98 | ||
| 99 | /// A component that represents entities which are controlled by the | |
| 100 | /// keyboard. | |
| 101 | #[derive(Component, Default, Debug)] | |
| 102 | #[storage(NullStorage)] | |
| 103 | pub struct Controlled; | |
| 104 | ||
| 105 | /// A component that represents entities which can collide with other | |
| 106 | /// things. | |
| 107 | #[derive(Component, Debug)] | |
| 108 | #[storage(VecStorage)] | |
| 109 | pub struct Collision { | |
| 110 | pub has_collision: bool, | |
| 111 | } | |
| 112 | ||
| 113 | #[derive(Component)] | |
| 114 | #[storage(VecStorage)] | |
| 115 | pub struct Blocking { | |
| 116 | pub handle: ncollide2d::pipeline::CollisionObjectSlabHandle, | |
| 117 | } | |
| 118 | ||
| 119 | impl Blocking { | |
| 120 | pub fn new_shape<S: ncollide2d::shape::Shape<f32>>(e: specs::Entity, w: &mut World, volume: S) -> Blocking { | |
| 121 | let (handle, _) = w.add( | |
| 122 | nalgebra::geometry::Isometry::identity(), | |
| 123 | ncollide2d::shape::ShapeHandle::new(volume), | |
| 124 | ncollide2d::pipeline::CollisionGroups::new(), | |
| 125 | ncollide2d::pipeline::object::GeometricQueryType::Proximity(0.0), | |
| 126 | e, | |
| 127 | ); | |
| 128 | Blocking { | |
| 129 | handle, | |
| 130 | } | |
| 131 | } | |
| 132 | ||
| 133 | pub fn new_box(e: specs::Entity, w: &mut World) -> Blocking { | |
| 134 | Blocking::new_shape(e, w, ncollide2d::shape::Cuboid::new(nalgebra::Vector2::new( | |
| 135 | 11.0, 11.0, | |
| 136 | ))) | |
| 137 | } | |
| 138 | ||
| 139 | pub fn new_ball(e: specs::Entity, w: &mut World) -> Blocking { | |
| 140 | Blocking::new_shape(e, w, ncollide2d::shape::Ball::new(8.0)) | |
| 141 | } | |
| 142 | } |
| 1 | use specs::world::WorldExt; | |
| 2 | use specs::{Component, NullStorage, VecStorage}; | |
| 3 | use crate::types::World; | |
| 4 | ||
| 5 | /// Register all the components with the world. | |
| 6 | pub fn register(world: &mut specs::World) { | |
| 7 | world.register::<Position>(); | |
| 8 | world.register::<Velocity>(); | |
| 9 | world.register::<Sprite>(); | |
| 10 | world.register::<Background>(); | |
| 11 | world.register::<Foreground>(); | |
| 12 | world.register::<Decoration>(); | |
| 13 | world.register::<Controlled>(); | |
| 14 | world.register::<Collision>(); | |
| 15 | world.register::<Blocking>(); | |
| 16 | } | |
| 17 | ||
| 18 | /// The `Position` component represents (in world coordinates) a thing | |
| 19 | /// that has a position in the world, measured from the top-left of | |
| 20 | /// the thing. | |
| 21 | #[derive(Component, Debug, Clone)] | |
| 22 | #[storage(VecStorage)] | |
| 23 | pub struct Position { | |
| 24 | pub x: f32, | |
| 25 | pub y: f32, | |
| 26 | } | |
| 27 | ||
| 28 | impl Position { | |
| 29 | /// Convert a `Position` to a screen point | |
| 30 | pub fn to_point(&self) -> mint::Point2<f32> { | |
| 31 | mint::Point2 { | |
| 32 | x: self.x * 3.0, | |
| 33 | y: self.y * 3.0, | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | pub fn to_grid(&self) -> (i32, i32) { | |
| 38 | ((self.x / 24.0) as i32, (self.y / 24.0) as i32) | |
| 39 | } | |
| 40 | ||
| 41 | pub fn moved(&self, vel: &Velocity) -> Position { | |
| 42 | Position { | |
| 43 | x: self.x + vel.dx, | |
| 44 | y: self.y + vel.dy, | |
| 45 | } | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | /// The `Velocity` componenent is present on any entity that moves | |
| 50 | /// through the world, and represents its rate of change per | |
| 51 | /// time-unit. | |
| 52 | #[derive(Component, Debug)] | |
| 53 | #[storage(VecStorage)] | |
| 54 | pub struct Velocity { | |
| 55 | pub dx: f32, | |
| 56 | pub dy: f32, | |
| 57 | } | |
| 58 | ||
| 59 | /// The `Sprite` components represents the current display location of | |
| 60 | /// a sprite in the spritesheet. | |
| 61 | #[derive(Component, Debug)] | |
| 62 | #[storage(VecStorage)] | |
| 63 | pub struct Sprite { | |
| 64 | pub u: u8, | |
| 65 | pub v: u8, | |
| 66 | } | |
| 67 | ||
| 68 | impl Sprite { | |
| 69 | /// Convert a `Sprite` into the rectangle that specifies the | |
| 70 | /// sprite location on the spritesheet | |
| 71 | pub fn to_rect(&self) -> ggez::graphics::Rect { | |
| 72 | ggez::graphics::Rect { | |
| 73 | x: (1.0 / 32.0) * self.u as f32, | |
| 74 | y: (1.0 / 32.0) * self.v as f32, | |
| 75 | w: 1.0 / 32.0, | |
| 76 | h: 1.0 / 32.0, | |
| 77 | } | |
| 78 | } | |
| 79 | } | |
| 80 | ||
| 81 | /// A drawing-phase component: represents tiles that appear in the | |
| 82 | /// background of everything. | |
| 83 | #[derive(Component, Default, Debug)] | |
| 84 | #[storage(NullStorage)] | |
| 85 | pub struct Background; | |
| 86 | ||
| 87 | /// A drawing-phase component: represents tiles which appear in the | |
| 88 | /// foreground, possibly entities. | |
| 89 | #[derive(Component, Default, Debug)] | |
| 90 | #[storage(NullStorage)] | |
| 91 | pub struct Foreground; | |
| 92 | ||
| 93 | /// A drawing-phase component: represents tiles which appear on top of | |
| 94 | /// everything else, such as the tops of trees or roofs of houses. | |
| 95 | #[derive(Component, Default, Debug)] | |
| 96 | #[storage(NullStorage)] | |
| 97 | pub struct Decoration; | |
| 98 | ||
| 99 | /// A component that represents entities which are controlled by the | |
| 100 | /// keyboard. | |
| 101 | #[derive(Component, Default, Debug)] | |
| 102 | #[storage(NullStorage)] | |
| 103 | pub struct Controlled; | |
| 104 | ||
| 105 | /// A component that represents entities which can collide with other | |
| 106 | /// things. | |
| 107 | #[derive(Component, Debug)] | |
| 108 | #[storage(VecStorage)] | |
| 109 | pub struct Collision { | |
| 110 | pub has_collision: bool, | |
| 111 | } | |
| 112 | ||
| 113 | #[derive(Component)] | |
| 114 | #[storage(VecStorage)] | |
| 115 | pub struct Blocking { | |
| 116 | pub handle: ncollide2d::pipeline::CollisionObjectSlabHandle, | |
| 117 | } | |
| 118 | ||
| 119 | impl Blocking { | |
| 120 | pub fn new_shape<S: ncollide2d::shape::Shape<f32>>(e: specs::Entity, w: &mut World, volume: S) -> Blocking { | |
| 121 | let (handle, _) = w.add( | |
| 122 | nalgebra::geometry::Isometry::identity(), | |
| 123 | ncollide2d::shape::ShapeHandle::new(volume), | |
| 124 | ncollide2d::pipeline::CollisionGroups::new(), | |
| 125 | ncollide2d::pipeline::object::GeometricQueryType::Proximity(0.0), | |
| 126 | e, | |
| 127 | ); | |
| 128 | Blocking { | |
| 129 | handle, | |
| 130 | } | |
| 131 | } | |
| 132 | ||
| 133 | pub fn new_box(e: specs::Entity, w: &mut World) -> Blocking { | |
| 134 | Blocking::new_shape(e, w, ncollide2d::shape::Cuboid::new(nalgebra::Vector2::new( | |
| 135 | 11.0, 11.0, | |
| 136 | ))) | |
| 137 | } | |
| 138 | ||
| 139 | pub fn new_ball(e: specs::Entity, w: &mut World) -> Blocking { | |
| 140 | Blocking::new_shape(e, w, ncollide2d::shape::Ball::new(8.0)) | |
| 141 | } | |
| 142 | } |
| 13 | 13 | } |
| 14 | 14 | use specs::world::WorldExt; |
| 15 | 15 | |
| 16 |
pub mod com |
|
| 16 | pub mod components; | |
| 17 | 17 | pub mod consts; |
| 18 | 18 | pub mod game; |
| 19 | 19 | pub mod res; |
| 58 | 58 | |
| 59 | 59 | fn main() -> Result<(), ggez::error::GameError> { |
| 60 | 60 | let mut world = specs::World::new(); |
| 61 |
com |
|
| 61 | components::register(&mut world); | |
| 62 | 62 | |
| 63 | 63 | world.insert(ncollide2d::world::CollisionWorld::<f32, specs::Entity>::new(0.1)); |
| 64 | 64 | res::world_from_file(&mut world, "assets/main.tmx"); |
| 1 |
use crate::com |
|
| 1 | use crate::components::*; | |
| 2 | 2 | use crate::consts; |
| 3 | 3 | use crate::types::World; |
| 4 | 4 |
| 1 |
use crate::com |
|
| 1 | use crate::components::{self, Position, Sprite}; | |
| 2 | 2 | use crate::consts; |
| 3 | 3 | use crate::game::MyGame; |
| 4 | 4 | |
| 47 | 47 | |
| 48 | 48 | Draw { |
| 49 | 49 | ctx, |
| 50 |
_phase: com |
|
| 50 | _phase: components::Background, | |
| 51 | 51 | } |
| 52 | 52 | .run_now(&game.world); |
| 53 | 53 | Draw { |
| 54 | 54 | ctx, |
| 55 |
_phase: com |
|
| 55 | _phase: components::Foreground, | |
| 56 | 56 | } |
| 57 | 57 | .run_now(&game.world); |
| 58 | 58 | Draw { |
| 59 | 59 | ctx, |
| 60 |
_phase: com |
|
| 60 | _phase: components::Decoration, | |
| 61 | 61 | } |
| 62 | 62 | .run_now(&game.world); |
| 63 | 63 | |