From 6b1dcc5df51df4a2d8b724187eb1bcdb4fd9df8b Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 14 Mar 2015 19:25:23 -0400 Subject: Added sound when you hit the ground Also split up components.cpp into files for each class, fixed a bug concerning falling off the screen when you change maps, and converted collision data into doubles. --- src/components/map_collision.cpp | 211 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 src/components/map_collision.cpp (limited to 'src/components/map_collision.cpp') diff --git a/src/components/map_collision.cpp b/src/components/map_collision.cpp new file mode 100644 index 0000000..f385320 --- /dev/null +++ b/src/components/map_collision.cpp @@ -0,0 +1,211 @@ +#include "map_collision.h" +#include "map.h" +#include "game.h" + +MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map) +{ + addCollision(-6, 0, GAME_WIDTH, Direction::left, (map.getLeftMap() == nullptr) ? Collision::Type::wrap : Collision::Type::teleport); + addCollision(GAME_WIDTH+6, 0, GAME_WIDTH, Direction::right, (map.getRightMap() == nullptr) ? Collision::Type::reverse : Collision::Type::teleport); + + for (int i=0; i 0) && (tile < 28) && (!((tile >= 5) && (tile <= 7)))) + { + addCollision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::right, Collision::Type::wall); + addCollision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::left, Collision::Type::wall); + addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, Collision::Type::wall); + addCollision((y+1)*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::up, Collision::Type::wall); + } else if ((tile >= 5) && (tile <= 7)) + { + addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, Collision::Type::platform); + } else if (tile == 42) + { + addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, Collision::Type::danger); + } + } +} + +void MapCollisionComponent::addCollision(double axis, double lower, double + upper, Direction dir, Collision::Type type) +{ + std::list::iterator it; + + switch (dir) + { + case Direction::up: + it = up_collisions.begin(); + for (; it!=up_collisions.end(); it++) + { + if (it->axis < axis) break; + } + + up_collisions.insert(it, {axis, lower, upper, type}); + + break; + case Direction::down: + it = down_collisions.begin(); + for (; it!=down_collisions.end(); it++) + { + if (it->axis > axis) break; + } + + down_collisions.insert(it, {axis, lower, upper, type}); + + break; + case Direction::left: + it = left_collisions.begin(); + for (; it!=left_collisions.end(); it++) + { + if (it->axis < axis) break; + } + + left_collisions.insert(it, {axis, lower, upper, type}); + + break; + case Direction::right: + it = right_collisions.begin(); + for (; it!=right_collisions.end(); it++) + { + if (it->axis > axis) break; + } + + right_collisions.insert(it, {axis, lower, upper, type}); + + break; + } +} + +void MapCollisionComponent::detectCollision(Game& game, Entity&, Entity& collider, std::pair old_position) +{ + if (collider.position.first < old_position.first) + { + for (auto collision : left_collisions) + { + if (collision.axis > old_position.first) continue; + if (collision.axis < collider.position.first) break; + + if ((old_position.second+collider.size.second > collision.lower) && (old_position.second < collision.upper)) + { + // We have a collision! + processCollision(game, collider, collision, Direction::left, old_position); + + break; + } + } + } else if (collider.position.first > old_position.first) + { + for (auto collision : right_collisions) + { + if (collision.axis < old_position.first+collider.size.first) continue; + if (collision.axis > collider.position.first+collider.size.first) break; + + if ((old_position.second+collider.size.second > collision.lower) && (old_position.second < collision.upper)) + { + // We have a collision! + processCollision(game, collider, collision, Direction::right, old_position); + + break; + } + } + } + + if (collider.position.second < old_position.second) + { + for (auto collision : up_collisions) + { + if (collision.axis > old_position.second) continue; + if (collision.axis < collider.position.second) break; + + if ((collider.position.first+collider.size.first > collision.lower) && (collider.position.first < collision.upper)) + { + // We have a collision! + processCollision(game, collider, collision, Direction::up, old_position); + + break; + } + } + } else if (collider.position.second > old_position.second) + { + for (auto collision : down_collisions) + { + if (collision.axis < old_position.second+collider.size.second) continue; + if (collision.axis > collider.position.second+collider.size.second) break; + + if ((collider.position.first+collider.size.first > collision.lower) && (collider.position.first < collision.upper)) + { + // We have a collision! + processCollision(game, collider, collision, Direction::down, old_position); + + break; + } + } + } +} + +void MapCollisionComponent::processCollision(Game& game, Entity& collider, Collision collision, Direction dir, std::pair old_position) +{ + if (collision.type == Collision::Type::wall) + { + if (dir == Direction::left) + { + collider.position.first = collision.axis; + collider.send(game, Message::Type::stopMovingHorizontally); + } else if (dir == Direction::right) + { + collider.position.first = collision.axis - collider.size.first; + collider.send(game, Message::Type::stopMovingHorizontally); + } else if (dir == Direction::up) + { + collider.position.second = collision.axis; + collider.send(game, Message::Type::stopMovingVertically); + } else if (dir == Direction::down) + { + collider.position.second = collision.axis - collider.size.second; + collider.send(game, Message::Type::hitTheGround); + } + } else if (collision.type == Collision::Type::wrap) + { + if (dir == Direction::left) + { + collider.position.first = GAME_WIDTH-collider.size.first/2; + } else if (dir == Direction::right) + { + collider.position.first = -collider.size.first/2; + } else if (dir == Direction::up) + { + collider.position.second = GAME_HEIGHT-collider.size.second/2-1; + } else if (dir == Direction::down) + { + collider.position.second = -collider.size.second/2; + } + } else if (collision.type == Collision::Type::teleport) + { + if (dir == Direction::left) + { + game.loadMap(*map.getLeftMap(), std::make_pair(GAME_WIDTH-collider.size.first/2, old_position.second)); + } else if (dir == Direction::right) + { + game.loadMap(*map.getRightMap(), std::make_pair(-collider.size.first/2, old_position.second)); + } + } else if (collision.type == Collision::Type::reverse) + { + if (dir == Direction::right) + { + collider.position.first = collision.axis - collider.size.first; + collider.send(game, Message::Type::walkLeft); + } + } else if (collision.type == Collision::Type::platform) + { + Message msg(Message::Type::drop); + msg.dropAxis = collision.axis; + + collider.send(game, msg); + } else if (collision.type == Collision::Type::danger) + { + game.playerDie(); + } +} -- cgit 1.4.1