#include "pch.h" #include "Player.h" #include #include "colors.h" #include "utils.h" #include "WorldLevel.h" Player::Player(const Point2f& Position) : m_Position(Position), m_Size(Point2f{40, 40}), m_Vel(Point2f{0,0}), m_Acc(Point2f{0,0}) { m_ContactMap[Collision::CollisionDirection::Top] = nullptr; m_ContactMap[Collision::CollisionDirection::Bottom] = nullptr; m_ContactMap[Collision::CollisionDirection::Left] = nullptr; m_ContactMap[Collision::CollisionDirection::Right] = nullptr; } Collision::CollisionRect Player::GetCollisionRect() { Collision::CollisionRect rect = {m_Position, m_Size, m_Vel}; return rect; } void Player::Draw() const { utils::SetColor(Colors::PINK); utils::DrawRect(Rectf{m_Position.x, m_Position.y, m_Size.x, m_Size.y}); } void Player::Update(float elapsedTime, WorldLevel& level) { // m_Acc.y += m_Gravity.y; // m_Vel.y = std::min(m_Vel.y, m_MaxSpeed); // // Point2f nextPos = m_Position + m_Vel * elapsedTime; // //collision checking m_Vel = Point2f{0, -100}; //check for keys if(utils::isKeyDown(SDL_SCANCODE_W)) { m_Vel.y = 100; } if(utils::isKeyDown(SDL_SCANCODE_S)) { m_Vel.y = -100; if(m_Grounded) { if(m_ContactMap[Collision::CollisionDirection::Bottom] != nullptr) { m_ContactMap[Collision::CollisionDirection::Bottom]->SetTileType(GroundTileTypes::Air); WorldTile* tile = m_ContactMap[Collision::CollisionDirection::Bottom]; //center of tile Point2f tileCenter = tile->GetCollisionRect().getCollisionRect().pos + tile->GetCollisionRect().getCollisionRect().size / 2; m_Position = Point2f{tileCenter.x - m_Size.x / 2, tileCenter.y - m_Size.y / 2}; } } } if(utils::isKeyDown(SDL_SCANCODE_A)) { m_Vel.x = -100; } if(utils::isKeyDown(SDL_SCANCODE_D)) { m_Vel.x = 100; } float t = 0, min_t = INFINITY; Point2f intersectionPoint, normal; std::vector> contactTimes{}; WorldGridManager& gridManager = level.GetGridManager(); for (size_t x { 0 }; x < WORLD_WIDTH; ++x) { for(size_t y { 0 }; y < WORLD_HEIGHT; ++y) { if(gridManager.GetTileAtIndex(x,y)->GetTileType() == GroundTileTypes::Dirt) { gridManager.GetTileAtIndex(x,y)->m_Hightlight = false; if(Collision::DynamicRectVsRect(this->GetCollisionRect(), elapsedTime, gridManager.GetTileAtIndex(x, y)->GetCollisionRect().getCollisionRect(), intersectionPoint, normal, t)) { contactTimes.push_back(std::pair{x + y * WORLD_WIDTH, t}); } } } } std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair& a, const std::pair& b) { return a.second < b.second; }); for (std::pair contact_time : contactTimes) { int x = contact_time.first % WORLD_WIDTH; int y = contact_time.first / WORLD_WIDTH; WorldTile* world_tile = gridManager.GetTileAtIndex(x,y); world_tile->m_Hightlight = true; bool isDiggingCandidate = true; Collision::CollisionRect tileRect = world_tile->GetCollisionRect().getCollisionRect(); //check if the tile is above the player if(tileRect.pos.y > m_Position.y + m_Size.y) { isDiggingCandidate = false; } //check if tile is left of player if(tileRect.pos.x > m_Position.x + m_Size.x) { isDiggingCandidate = false; } //check if tile is right of player if(tileRect.pos.x + tileRect.size.x < m_Position.x) { isDiggingCandidate = false; } //check if the collision happend under the player if(tileRect.pos.y < m_Position.y - m_Size.y) { //Tile is under player //check if the center of the player is between the centers of the tiles left and right if(m_Position.x + m_Size.x / 2 > tileRect.pos.x && m_Position.x + m_Size.x / 2 < tileRect.pos.x + tileRect.size.x) { if(isDiggingCandidate) { //Dig the tile m_ContactMap[Collision::CollisionDirection::Bottom] = world_tile; m_Grounded = true; } } } //m_ContactMap[Collision::CollisionDirection::Bottom] = world_tile; //m_Grounded = true; Collision::CollisionRect rect = world_tile->GetCollisionRect().getCollisionRect(); //TODO: fix this mess Collision::ResolvePlayerVsRect(*this, elapsedTime, &rect); } m_Position = m_Position + m_Vel * elapsedTime; }