#include "pch.h" #include "WorldLevel.h" #include #include #include #include "Collision.h" #include "colors.h" #include "utils.h" WorldLevel::WorldLevel(Camera* camera) : Level(camera), m_mousePos{ 0, 0 }, m_player(Player{ Point2f{ 0, 100 } }) { // The grid is 34 x 50 big, the top center is 0,0 in world coords for (size_t x { 0 }; x < WORLD_WIDTH; ++x) { for (size_t y { 0 }; y < WORLD_HEIGHT; ++y) { int actualX = x - WORLD_WIDTH / 2; m_worldTiles[x][y] = new WorldTile{ Point2f{ float(actualX * TILE_WIDTH), -float(y * TILE_HEIGHT) - TILE_HEIGHT}, GroundTileTypes::Dirt}; } } m_Rects.push_back(Collision::CollisionRect{ Point2f{0.0f, 10.0f}, Point2f{40.0f, 40.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{170.0f, 70.0f}, Point2f{10.0f, 40.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{150.0f, 50.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{150.0f, 150.0f}, Point2f{75.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{170.0f, 50.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{190.0f, 50.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{110.0f, 50.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{50.0f, 130.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{50.0f, 150.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{50.0f, 170.0f}, Point2f{20.0f, 20.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{150.0f, 100.0f}, Point2f{10.0f, 1.0f} }); m_Rects.push_back(Collision::CollisionRect{ Point2f{200.0f, 100.0f}, Point2f{20.0f, 60.0f} }); // std::string dirtPath = + "tiles/dirt/dirt" + std::to_string(utils::randRange(1, 5)) + ".png"; // m_pTextTexture = new Texture(dirtPath); } WorldLevel::~WorldLevel() { //delete m_pTextTexture; } void WorldLevel::Update(float elapsedSec) { int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); m_mousePos = Point2f{ float(mouseX), float(mouseY) }; m_mousePos = m_pCamera->TransformMouse(m_mousePos); //m_player.Update(elapsedSec, *this); WorldTile* selectedTile{ nullptr }; for (size_t x { 0 }; x < WORLD_WIDTH; ++x) { for (size_t y { 0 }; y < WORLD_HEIGHT; ++y) { if(m_worldTiles[x][y]->GetCollisionRect().Contains(m_mousePos)) { selectedTile = m_worldTiles[x][y]; } } } if(selectedTile != nullptr) { selectedTile->SetTileType(GroundTileTypes::Air); } Point2f RayPoint = Point2f{m_pCamera->Viewport.width, m_pCamera->Viewport.height}; Point2f RayDir = Point2f{m_mousePos.x - RayPoint.x, m_mousePos.y - RayPoint.y}; //wasd movement if(utils::isKeyDown(SDL_SCANCODE_W)) { m_Rects[0].vel.y += 20; } if(utils::isKeyDown(SDL_SCANCODE_S)) { m_Rects[0].vel.y += -10; } if(utils::isKeyDown(SDL_SCANCODE_A)) { m_Rects[0].vel.x += -10; } if(utils::isKeyDown(SDL_SCANCODE_D)) { m_Rects[0].vel.x += 10; } if(utils::isKeyDown(SDL_SCANCODE_SPACE)) { //check if the player is on the ground m_Rects[0].ContactMap[Collision::CollisionDirection::Bottom]->pos.y += 100; } m_Rects[0].vel.y -= 9.81f; m_Rects[0].ContactMap.clear(); float t = 0, min_t = INFINITY; Point2f intersectionPoint, normal; std::vector> contactTimes{}; for (size_t i { 1 }; i < m_Rects.size(); ++i) { if(Collision::DynamicRectVsRect(m_Rects[0], elapsedSec, m_Rects[i], intersectionPoint, normal, t)) { contactTimes.push_back(std::pair{i, 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) { Collision::ResolveDynamicRectVsRect(m_Rects[0], elapsedSec, &m_Rects[contact_time.first]); } contactTimes.clear(); //loop over the worldTiles for (int x {0} ; x < WORLD_WIDTH; ++x) { for (int y {0}; y < WORLD_HEIGHT; ++y) { if(m_worldTiles[x][y]->GetTileType() == GroundTileTypes::Dirt) { if(Collision::DynamicRectVsRect(m_Rects[0], elapsedSec, m_worldTiles[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) { WorldTile* tile = m_worldTiles[contact_time.first % WORLD_WIDTH][contact_time.first / WORLD_WIDTH]; Collision::CollisionRect rect = tile->GetCollisionRect().getCollisionRect(); Collision::ResolveDynamicRectVsRect(m_Rects[0], elapsedSec, &rect); //delete tile; //WorldTile* tileRect = tile->GetCollisionRect().tile; //tileRect->SetTileType(GroundTileTypes::Air); } m_Rects[0].pos = m_Rects[0].pos + m_Rects[0].vel * elapsedSec; } void WorldLevel::Draw() const { m_pCamera->BeginRendering(); for (Collision::CollisionRect rect : m_Rects) { utils::DrawRect(rect.pos, rect.size.x, rect.size.y); } //Rectf expanded = Rectf{ m_Rects[1].bottomLeft.x - m_Rects[0].width / 2, m_Rects[1].bottomLeft.y - m_Rects[0].height / 2, m_Rects[1].width + m_Rects[0].width, m_Rects[1].height + m_Rects[0].height }; //utils::SetColor(Colors::RED); //utils::DrawRect(expanded); Point2f RayPoint = Point2f{m_pCamera->Viewport.width, m_pCamera->Viewport.height}; Point2f RayDir = Point2f{m_mousePos.x - RayPoint.x, m_mousePos.y - RayPoint.y}; utils::SetColor(Colors::WHITE); utils::DrawLine(RayPoint, m_mousePos); utils::FillEllipse(m_mousePos, 20, 20); // Point2f intersectionPoint, normal; // float contactTime; // Rectf testRect = Rectf{m_Rects[1].bottomLeft.x, m_Rects[1].bottomLeft.y, m_Rects[1].width, m_Rects[1].height}; // if(utils::RayVsRect(RayPoint, RayDir, testRect, intersectionPoint, normal, contactTime) && contactTime > 0.0f && contactTime < 1.0f) { // utils::SetColor(Colors::GREEN); // utils::FillEllipse(intersectionPoint, 5, 5); // utils::DrawLine(intersectionPoint, Point2f{intersectionPoint.x + normal.x * 50, intersectionPoint.y + normal.y * 50}); // } // // utils::SetColor(Colors::YELLOW); // utils::FillEllipse(m_mousePos,2,2); for (size_t x { 0 }; x < WORLD_WIDTH; ++x) { for (size_t y { 0 }; y < WORLD_HEIGHT; ++y) { m_worldTiles[x][y]->Draw(); } } //loop over worldtiles for (int x { 0 }; x < WORLD_WIDTH; ++x) { for (int y { 0 }; y < WORLD_HEIGHT; ++y) { if(m_worldTiles[x][y]->GetTileType() == GroundTileTypes::Dirt) { Collision::CollisionRect rect = m_worldTiles[x][y]->GetCollisionRect().getCollisionRect(); utils::SetColor(Colors::GREEN); utils::DrawRect(rect.pos, rect.size.x, rect.size.y); } } } for (size_t i { 0 }; i < 4; ++i) { if(m_Rects[0].ContactMap.find(static_cast(i)) != m_Rects[0].ContactMap.end()) { utils::SetColor(Colors::RED); Collision::CollisionRect* rect = m_Rects[0].ContactMap.at(static_cast(i)); utils::FillRect(rect->pos, rect->size.x, rect->size.y); } } // utils::SetColor(Colors::WHITE); // for (int x { -100 }; x < 100; ++x) { // for (int y { -100 }; y < 100; ++y) { // utils::DrawLine(x * 50, -5000, x * 50, 50000); // utils::DrawLine(-5000, y * 50, 50000, y * 50); // } // } utils::SetColor(Colors::MAGENTA); utils::FillEllipse(0, 0, 5, 5); //m_player.Draw(); m_pCamera->EndRendering(); //utils::SetColor(Colors::WHITE); //m_pTextTexture->Draw(Point2f{ 0, 0 }); } void WorldLevel::MouseMove(const Point2f& mousePos) { m_mousePos = mousePos; } WorldTile* WorldLevel::GetTileAt(const Point2f& pos) const { return nullptr; } void WorldLevel::SetTileAt(const Point2f& pos, WorldTile* tile) { } std::array, WorldLevel::WORLD_HEIGHT> WorldLevel::GetAllTiles() const { return m_worldTiles; }