Skip to content

Commit

Permalink
Changed position changes from method to actor message
Browse files Browse the repository at this point in the history
  • Loading branch information
DarinM223 committed May 13, 2016
1 parent 5932ec7 commit ed03c03
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 59 deletions.
2 changes: 0 additions & 2 deletions src/engine/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ macro_rules! block {
actor_type: $actor_type::Block,
}
}

fn change_pos(&mut self, _: &::engine::PositionChange) {}
}
)*
}
Expand Down
41 changes: 17 additions & 24 deletions src/engine/collision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,46 @@ use sdl2::rect::Rect;
use sprite::SpriteRectangle;
use std::ops::{BitAnd, BitOr};
use vector::PositionChange;
use view::{Actor, ActorData, MessageHandler};
use view::{Actor, ActorData, CreateMessageHandler, MessageHandler, MessageType};
use viewport::Viewport;

/// Handler for creating a collision message from an actor's data and the collision side
pub type CreateCollisionMsg<Type, Message> = Box<Fn(&ActorData<Type>, &ActorData<Type>, u8)
-> Message>;

/// Moves actor away from collided actor and sends collision messages to
/// both of the collided actors
#[inline]
pub fn handle_collision<Type, Message>(actor: &mut Box<Actor<Type, Message>>,
other: &ActorData<Type>,
direction: CollisionSide,
handler: MessageHandler<Type, Message>,
create_collision_message: CreateCollisionMsg<Type, Message>,
create_msg: CreateMessageHandler<Type, Message>,
actors: &mut ActorManager<Type, Message>,
viewport: &mut Viewport,
context: &mut Context) {
context: &mut Context)
where Type: Clone
{
let data = actor.data();
if data.resolves_collisions {
while actor.collides_with(other) == Some(direction) {
match direction {
CollisionSide::Top => {
actor.change_pos(&PositionChange::new().down(1));
}
CollisionSide::Bottom => {
actor.change_pos(&PositionChange::new().up(1));
}
CollisionSide::Left => {
actor.change_pos(&PositionChange::new().right(1));
}
CollisionSide::Right => {
actor.change_pos(&PositionChange::new().left(1));
}
}
let change = match direction {
CollisionSide::Top => PositionChange::new().down(1),
CollisionSide::Bottom => PositionChange::new().up(1),
CollisionSide::Left => PositionChange::new().right(1),
CollisionSide::Right => PositionChange::new().left(1),
};

actor.handle_message(&create_msg(MessageType::ChangePosition(change)));
}

if direction == CollisionSide::Bottom {
actor.change_pos(&PositionChange::new().down(1));
let down_change = PositionChange::new().down(1);
actor.handle_message(&create_msg(MessageType::ChangePosition(down_change)));
}
}

let direction = direction & other.collision_filter;
let rev_dir = CollisionSide::reverse_u8(direction);

let response = create_collision_message(&other, &data, direction);
let other_msg = create_collision_message(&data, &other, rev_dir);
let response = create_msg(MessageType::Collision(other.clone(), data.clone(), direction));
let other_msg = create_msg(MessageType::Collision(data.clone(), other.clone(), rev_dir));

(handler)(actor, actors, viewport, context, &response);
(handler)(actor, actors, viewport, context, &other_msg);
Expand Down
3 changes: 2 additions & 1 deletion src/engine/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,6 @@ pub use score::Score;
pub use sprite::{AnimatedSprite, Animation, AnimationData, AnimationManager, Direction,
Renderable, Sprite, SpriteRectangle};
pub use vector::{PositionChange, Vector2D};
pub use view::{Actor, ActorData, MessageHandler, View, ViewAction};
pub use view::{Actor, ActorData, CreateMessageHandler, MessageHandler, MessageType, View,
ViewAction};
pub use viewport::Viewport;
15 changes: 12 additions & 3 deletions src/engine/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ pub type MessageHandler<Type, Message> = Box<Fn(&mut Box<Actor<Type, Message>>,
&mut Context,
&Message)>;

/// Message types required by the engine
/// to be implemented by CreateMessageHandler
pub enum MessageType<Type> {
Collision(ActorData<Type>, ActorData<Type>, u8),
ChangePosition(PositionChange),
}

/// Handler for creating a message for a message type
/// that is used by the engine
/// like a collision message or a position changed message
pub type CreateMessageHandler<Type, Message> = Box<Fn(MessageType<Type>) -> Message>;

/// Actions that the view would want the event loop to do
pub enum ViewAction {
Quit,
Expand Down Expand Up @@ -64,7 +76,4 @@ pub trait Actor<Type, Message> {

/// Gets the actor data
fn data(&mut self) -> ActorData<Type>;

/// Change position
fn change_pos(&mut self, change: &PositionChange);
}
29 changes: 19 additions & 10 deletions src/game/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ use actors::block::{GroundBlockMid, GroundBlockTop, StartBlock, StoneBlock};
use actors::coin::Coin;
use actors::koopa::Koopa;
use actors::player::Player;
use engine::{Actor, ActorData, ActorManager, Viewport, Context};
use engine::{Actor, ActorManager, MessageType, PositionChange, Viewport, Context};
use sdl2::render::Renderer;

/// Actions for an actor to process
#[derive(Clone, Debug, PartialEq)]
pub enum ActorAction {
DamageActor(i32),
ChangePosition(PositionChange),
Collision(ActorType, u8),
}

Expand Down Expand Up @@ -93,13 +94,21 @@ pub fn handle_message(curr_actor: &mut Box<Actor<ActorType, ActorMessage>>,
}

#[inline]
pub fn create_collision_message(sending_actor: &ActorData<ActorType>,
receiving_actor: &ActorData<ActorType>,
side: u8)
-> ActorMessage {
return ActorMessage::ActorAction {
send_id: sending_actor.id,
recv_id: receiving_actor.id,
action: ActorAction::Collision(sending_actor.actor_type, side),
};
pub fn create_msg(message: MessageType<ActorType>) -> ActorMessage {
match message {
MessageType::Collision(sender, receiver, direction) => {
ActorMessage::ActorAction {
send_id: sender.id,
recv_id: receiver.id,
action: ActorAction::Collision(sender.actor_type, direction),
}
}
MessageType::ChangePosition(change) => {
ActorMessage::ActorAction {
send_id: -1,
recv_id: -1,
action: ActorAction::ChangePosition(change),
}
}
}
}
4 changes: 0 additions & 4 deletions src/game/actors/coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,4 @@ impl Actor<ActorType, ActorMessage> for Coin {
actor_type: ActorType::Item,
}
}

fn change_pos(&mut self, change: &PositionChange) {
self.rect.apply_change(&change);
}
}
10 changes: 5 additions & 5 deletions src/game/actors/koopa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ impl Actor<ActorType, ActorMessage> for Koopa {

if let ActorMessage::ActorAction { send_id, ref action, .. } = *message {
match *action {
ChangePosition(ref change) => {
self.rect.apply_change(change);
self.anims.map_bbox_mut(|bbox| bbox.apply_change(&change));
ActorMessage::None
}
Collision(actor_type, side) if actor_type == ActorType::Block &&
side & CollisionSide::Bottom != 0 => {
if self.curr_state == KoopaState::Jumping {
Expand Down Expand Up @@ -189,9 +194,4 @@ impl Actor<ActorType, ActorMessage> for Koopa {
actor_type: ActorType::Enemy,
}
}

fn change_pos(&mut self, change: &PositionChange) {
self.rect.apply_change(&change);
self.anims.map_bbox_mut(|bbox| bbox.apply_change(&change));
}
}
10 changes: 5 additions & 5 deletions src/game/actors/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ impl Actor<ActorType, ActorMessage> for Player {
PlayerSize::Small => ActorMessage::PlayerDied,
}
}
ActorAction::ChangePosition(ref change) => {
self.rect.apply_change(change);
self.anims.map_bbox_mut(|bbox| bbox.apply_change(&change));
ActorMessage::None
}
ActorAction::Collision(_, side) if side == CollisionSide::Top => ActorMessage::None,
ActorAction::Collision(_, side) if side == CollisionSide::Bottom => {
if self.curr_state == PlayerState::Jumping {
Expand Down Expand Up @@ -262,9 +267,4 @@ impl Actor<ActorType, ActorMessage> for Player {
actor_type: ActorType::Player,
}
}

fn change_pos(&mut self, change: &PositionChange) {
self.rect.apply_change(&change);
self.anims.map_bbox_mut(|bbox| bbox.apply_change(&change));
}
}
14 changes: 9 additions & 5 deletions src/game/views/game_view.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use actions::{ActorMessage, ActorType};
use actions::{actor_from_token, create_collision_message, handle_message};
use actions::{ActorAction, ActorMessage, ActorType};
use actions::{actor_from_token, create_msg, handle_message};
use engine::collision::handle_collision;
use engine::font;
use engine::level;
Expand Down Expand Up @@ -94,8 +94,12 @@ impl View for GameView {
let data = actor.data();

// update the actor
let position_change = actor.update(context, elapsed);
actor.change_pos(&position_change);
let pos_change = actor.update(context, elapsed);
actor.handle_message(&ActorMessage::ActorAction {
send_id: data.id,
recv_id: data.id,
action: ActorAction::ChangePosition(pos_change),
});

if data.collision_filter != 0 && data.actor_type != ActorType::Block {
// only check collisions for nearby actors
Expand All @@ -109,7 +113,7 @@ impl View for GameView {
&other,
direction,
Box::new(handle_message),
Box::new(create_collision_message),
Box::new(create_msg),
&mut self.actors,
&mut self.viewport,
context);
Expand Down

0 comments on commit ed03c03

Please sign in to comment.