From 77be863f4f15d2481a64e4e8dadb4060a6e4e590 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sun, 11 Feb 2018 12:34:52 -0500 Subject: Implemented map rendering and basic collision Only wall and platform collision currently works, and map edges are not currently implemented. --- src/systems/pondering.cpp | 248 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 242 insertions(+), 6 deletions(-) (limited to 'src/systems/pondering.cpp') diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index e40db1d..26a6f56 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp @@ -2,6 +2,8 @@ #include "game.h" #include "components/ponderable.h" #include "components/transformable.h" +#include "components/droppable.h" +#include "consts.h" void PonderingSystem::tick(double dt) { @@ -9,17 +11,251 @@ void PonderingSystem::tick(double dt) PonderableComponent, TransformableComponent>(); + auto maps = game_.getEntityManager().getEntitiesWithComponents< + MappableComponent>(); + for (id_type entity : entities) { - auto& transformable = game_.getEntityManager().getComponent(entity); - auto& ponderable = game_.getEntityManager().getComponent(entity); + auto& transformable = game_.getEntityManager(). + getComponent(entity); + + auto& ponderable = game_.getEntityManager(). + getComponent(entity); // Accelerate - ponderable.setVelocityX(ponderable.getVelocityX() + ponderable.getAccelX() * dt); - ponderable.setVelocityY(ponderable.getVelocityY() + ponderable.getAccelY() * dt); + ponderable.setVelocityX( + ponderable.getVelocityX() + ponderable.getAccelX() * dt); + + ponderable.setVelocityY( + ponderable.getVelocityY() + ponderable.getAccelY() * dt); + + const double oldX = transformable.getX(); + const double oldY = transformable.getY(); + const double oldRight = oldX + transformable.getW(); + const double oldBottom = oldY + transformable.getH(); + + double newX = oldX + ponderable.getVelocityX() * dt; + double newY = oldY + ponderable.getVelocityY() * dt; + + if (ponderable.getVelocityY() > 0.0) + { + ponderable.setState(PonderableComponent::State::falling); + } + + for (id_type mapEntity : maps) + { + auto& mappable = game_.getEntityManager(). + getComponent(mapEntity); + + if (newX < oldX) + { + for (auto it = mappable.getLeftBoundaries().lower_bound(oldX); + (it != std::end(mappable.getLeftBoundaries())) && (it->first >= newX); + it++) + { + if ((oldBottom > it->second.getLower()) + && (oldY < it->second.getUpper())) + { + // We have a collision! + processCollision( + entity, + Direction::left, + newX, + newY, + it->first, + it->second.getType()); + + break; + } + } + } else if (newX > oldX) + { + for (auto it = mappable.getRightBoundaries().lower_bound(oldRight); + (it != std::end(mappable.getRightBoundaries())) + && (it->first <= (newX + transformable.getW())); + it++) + { + if ((oldBottom > it->second.getLower()) + && (oldY < it->second.getUpper())) + { + // We have a collision! + processCollision( + entity, + Direction::right, + newX, + newY, + it->first, + it->second.getType()); + + break; + } + } + } + + if (newY < oldY) + { + for (auto it = mappable.getUpBoundaries().lower_bound(oldY); + (it != std::end(mappable.getUpBoundaries())) && (it->first >= newY); + it++) + { + if ((oldRight > it->second.getLower()) + && (oldX < it->second.getUpper())) + { + // We have a collision! + processCollision( + entity, + Direction::up, + newX, + newY, + it->first, + it->second.getType()); + + break; + } + } + } else if (newY > oldY) + { + for (auto it = mappable.getDownBoundaries().lower_bound(oldBottom); + (it != std::end(mappable.getDownBoundaries())) + && (it->first <= (newY + transformable.getH())); + it++) + { + if ((oldRight > it->second.getLower()) + && (oldX < it->second.getUpper())) + { + // We have a collision! + processCollision( + entity, + Direction::down, + newX, + newY, + it->first, + it->second.getType()); + + break; + } + } + } + } // Move - transformable.setX(transformable.getX() + ponderable.getVelocityX() * dt); - transformable.setY(transformable.getY() + ponderable.getVelocityY() * dt); + transformable.setX(newX); + transformable.setY(newY); + } +} + +void PonderingSystem::initializeBody( + id_type entity, + PonderableComponent::Type type) +{ + auto& ponderable = game_.getEntityManager(). + emplaceComponent(entity, type); + + if (type == PonderableComponent::Type::freefalling) + { + ponderable.setAccelY(JUMP_GRAVITY(TILE_HEIGHT*3.5, 0.233)); + ponderable.setState(PonderableComponent::State::falling); + } +} + +void PonderingSystem::processCollision( + id_type entity, + Direction dir, + double& newX, + double& newY, + int axis, + MappableComponent::Boundary::Type type) +{ + auto& ponderable = game_.getEntityManager(). + getComponent(entity); + + auto& transformable = game_.getEntityManager(). + getComponent(entity); + + switch (type) + { + case MappableComponent::Boundary::Type::wall: + { + switch (dir) + { + case Direction::left: + { + newX = axis; + ponderable.setVelocityX(0.0); + + break; + } + + case Direction::right: + { + newX = axis - transformable.getW(); + ponderable.setVelocityX(0.0); + + break; + } + + case Direction::up: + { + newY = axis; + ponderable.setVelocityY(0.0); + + break; + } + + case Direction::down: + { + newY = axis - transformable.getH(); + ponderable.setVelocityY(0.0); + + if (ponderable.getState() == PonderableComponent::State::falling) + { + ponderable.setState(PonderableComponent::State::grounded); + } + + break; + } + } + + break; + } + + case MappableComponent::Boundary::Type::platform: + { + if (game_.getEntityManager().hasComponent(entity)) + { + auto& droppable = game_.getEntityManager(). + getComponent(entity); + + if (droppable.isDroppable()) + { + droppable.setDroppable(false); + } else { + newY = axis - transformable.getH(); + ponderable.setVelocityY(0.0); + + if (ponderable.getState() == PonderableComponent::State::falling) + { + ponderable.setState(PonderableComponent::State::grounded); + } + } + } else { + newY = axis - transformable.getH(); + ponderable.setVelocityY(0.0); + + if (ponderable.getState() == PonderableComponent::State::falling) + { + ponderable.setState(PonderableComponent::State::grounded); + } + } + + break; + } + + default: + { + // Not yet implemented. + + break; + } } } -- cgit 1.4.1