components.rs 4.2 KB

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