gdritter repos wenaglia / master src / components.rs
master

Tree @master (Download .tar.gz)

components.rs @master

862a3d2
 
1382766
a3e0d9f
 
b1f4d62
1382766
 
 
 
 
 
 
b1f4d62
3435b15
 
1382766
 
b1f4d62
 
 
37af6c0
1382766
 
 
 
 
 
 
b1f4d62
adc9cc3
 
 
 
 
1382766
3435b15
 
862a3d2
3435b15
 
 
 
 
7899490
3435b15
 
1382766
 
b1f4d62
 
 
1382766
 
 
 
 
 
 
b1f4d62
 
1382766
 
 
 
 
 
 
 
b1f4d62
 
1382766
 
 
 
 
 
 
 
 
 
b1f4d62
 
1382766
 
 
 
b1f4d62
 
1382766
 
 
 
b1f4d62
 
1382766
 
 
 
b1f4d62
 
1382766
 
b1f4d62
 
 
 
 
 
 
862a3d2
b1f4d62
3435b15
e9b6b2f
 
37af6c0
 
 
86edfda
37af6c0
 
 
e9b6b2f
 
ad5e08d
 
e9b6b2f
86edfda
 
 
 
 
895328e
86edfda
ad5e08d
37af6c0
86edfda
e9b6b2f
895328e
ad5e08d
 
 
 
 
86edfda
 
e9b6b2f
895328e
e9b6b2f
86edfda
37af6c0
use specs::world::WorldExt;
use specs::{Component, NullStorage, VecStorage};

pub type World = ncollide2d::world::CollisionWorld<f32, specs::Entity>;

/// Register all the components with the world.
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::<Controlled>();
    world.register::<Collision>();
    world.register::<Blocking>();
}

/// The `Position` component represents (in world coordinates) a thing
/// that has a position in the world, measured from the top-left of
/// the thing.
#[derive(Component, Debug, Clone)]
#[storage(VecStorage)]
pub struct Position {
    pub x: f32,
    pub y: f32,
}

impl Position {
    /// Convert a `Position` to a screen point
    pub fn to_point(&self) -> mint::Point2<f32> {
        mint::Point2 {
            x: self.x * 3.0,
            y: 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.y + vel.dy,
        }
    }
}

/// The `Velocity` componenent is present on any entity that moves
/// through the world, and represents its rate of change per
/// time-unit.
#[derive(Component, Debug)]
#[storage(VecStorage)]
pub struct Velocity {
    pub dx: f32,
    pub dy: f32,
}

/// The `Sprite` components represents the current display location of
/// a sprite in the spritesheet.
#[derive(Component, Debug)]
#[storage(VecStorage)]
pub struct Sprite {
    pub u: u8,
    pub v: u8,
}

impl Sprite {
    /// Convert a `Sprite` into the rectangle that specifies the
    /// sprite location on the spritesheet
    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,
        }
    }
}

/// A drawing-phase component: represents tiles that appear in the
/// background of everything.
#[derive(Component, Default, Debug)]
#[storage(NullStorage)]
pub struct Background;

/// A drawing-phase component: represents tiles which appear in the
/// foreground, possibly entities.
#[derive(Component, Default, Debug)]
#[storage(NullStorage)]
pub struct Foreground;

/// A drawing-phase component: represents tiles which appear on top of
/// everything else, such as the tops of trees or roofs of houses.
#[derive(Component, Default, Debug)]
#[storage(NullStorage)]
pub struct Decoration;

/// A component that represents entities which are controlled by the
/// keyboard.
#[derive(Component, Default, Debug)]
#[storage(NullStorage)]
pub struct Controlled;

/// A component that represents entities which can collide with other
/// things.
#[derive(Component, Debug)]
#[storage(VecStorage)]
pub struct Collision {
    pub has_collision: bool,
}

/// A component which represents things which have a collision shape
/// in the world
#[derive(Component)]
#[storage(VecStorage)]
pub struct Blocking {
    pub handle: ncollide2d::pipeline::CollisionObjectSlabHandle,
}

impl Blocking {
    /// create a `Blocking` component for an entity given a specified shape
    pub fn new_shape<S>(e: specs::Entity, w: &mut World, volume: S) -> Blocking
    where
        S: ncollide2d::shape::Shape<f32>,
    {
        let (handle, _) = w.add(
            nalgebra::geometry::Isometry::identity(),
            ncollide2d::shape::ShapeHandle::new(volume),
            ncollide2d::pipeline::CollisionGroups::new(),
            ncollide2d::pipeline::object::GeometricQueryType::Proximity(0.0),
            e,
        );
        Blocking { handle }
    }

    /// create an 11pxx11px box for an entity
    pub fn new_box(e: specs::Entity, w: &mut World) -> Blocking {
        Blocking::new_shape(
            e,
            w,
            ncollide2d::shape::Cuboid::new(nalgebra::Vector2::new(11.0, 11.0)),
        )
    }

    /// create a 11px ball for an entity
    pub fn new_ball(e: specs::Entity, w: &mut World) -> Blocking {
        Blocking::new_shape(e, w, ncollide2d::shape::Ball::new(11.0))
    }
}