Files
prog2/Game/WorldLevel.cpp
Bram Verhulst 39c744ba79 Add Imgui, Add TextureManager
From 1.1k texture loads to 5
2024-03-18 12:22:56 +01:00

221 lines
7.9 KiB
C++

#include "pch.h"
#include "WorldLevel.h"
#include <algorithm>
#include <iostream>
#include <ostream>
#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, TextureManager::GetInstance()};
}
}
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<std::pair<int, float>> 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<int, float>{i, t});
}
}
std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair<int, float>& a, const std::pair<int, float>& b) {
return a.second < b.second;
});
for (std::pair<int, float> 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<int, float>{x + y * WORLD_WIDTH, t});
}
}
}
}
std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair<int, float>& a, const std::pair<int, float>& b) {
return a.second < b.second;
});
for (std::pair<int, float> 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<Collision::CollisionDirection>(i)) != m_Rects[0].ContactMap.end()) {
utils::SetColor(Colors::RED);
Collision::CollisionRect* rect = m_Rects[0].ContactMap.at(static_cast<Collision::CollisionDirection>(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<std::array<WorldTile*, WorldLevel::WORLD_WIDTH>, WorldLevel::WORLD_HEIGHT> WorldLevel::GetAllTiles() const {
return m_worldTiles;
}