igra
This commit is contained in:
@@ -1,19 +1,37 @@
|
||||
#include <game/agame/background.hpp>
|
||||
#include <game/agame/player.hpp>
|
||||
#include <window/window.hpp>
|
||||
#include <object/camera.hpp>
|
||||
#include <algorithm>
|
||||
#include <utils.hpp>
|
||||
|
||||
namespace Game::AGame {
|
||||
void Background::start() {
|
||||
mSeaTex = std::make_shared<Game::Renderer::Texture>("../resources/l3sea.png", SDL_GetRenderer(Window::Window::getSDLWindowBackend()), "seaTex");
|
||||
mEnemyTex = std::make_shared<Game::Renderer::Texture>("../resources/l3enemy.png", SDL_GetRenderer(Window::Window::getSDLWindowBackend()), "enemyTex");
|
||||
mTrashTex = std::make_shared<Game::Renderer::Texture>("../resources/l3trash.png", SDL_GetRenderer(Window::Window::getSDLWindowBackend()), "trashTex");
|
||||
mFriendlyTex = std::make_shared<Game::Renderer::Texture>("../resources/l3friendly.png", SDL_GetRenderer(Window::Window::getSDLWindowBackend()), "friendlyTex");
|
||||
GameManager::setSharedData("enemyActiveCount", 0);
|
||||
GameManager::setSharedData("trashActiveCount", 0);
|
||||
GameManager::setSharedData("friendlyActiveCount", 0);
|
||||
GameManager::setSharedData("gameStage", 1);
|
||||
GameManager::setSharedData("gameWon", false);
|
||||
GameManager::setSharedData("gameLost", false);
|
||||
|
||||
mZIndex = -1; // Ensure background renders behind other entities
|
||||
mTex->setTiled(true); // Set the background texture to be tiled
|
||||
if (mSeaTex) {
|
||||
mSeaTex->setTiled(true);
|
||||
}
|
||||
mTiledScale = 0.5f;
|
||||
SDL_GetWindowSizeInPixels(Window::Window::getSDLWindowBackend(), &mW, &mH);
|
||||
|
||||
// Land boundary: left 1/3 of map in centered coordinates
|
||||
// For 1280px window: -640 (left) + 426.67 (1/3) = -213.33
|
||||
mLandBoundaryX = -static_cast<float>(mW) / 2.f + static_cast<float>(mW) / 3.f;
|
||||
GameManager::setSharedData("terrainLandBoundaryX", mLandBoundaryX);
|
||||
GameManager::setSharedData("enemyRevealRadius", 260.f);
|
||||
|
||||
mTransform.scaleX *= 10.f;
|
||||
mTransform.scaleY *= 10.f;
|
||||
|
||||
@@ -21,72 +39,147 @@ namespace Game::AGame {
|
||||
mTransform.y -= mTex->getHeight() * mTransform.adjustedScaleY() / 2.f;
|
||||
|
||||
LOG("W: " << mW << " H: " << mH);
|
||||
spawnLevel(1);
|
||||
}
|
||||
|
||||
mTransform.x = mW / 2.f - (mW / 3.f);
|
||||
mTransform.y = -mH;
|
||||
void Background::render(Game::Renderer::Renderer* renderer, Game::Renderer::RendererConfig config) {
|
||||
if (!renderer || !mTex || !mSeaTex) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float worldLeft = -static_cast<float>(mW) / 2.f;
|
||||
const float worldRight = static_cast<float>(mW) / 2.f;
|
||||
const float worldTop = -static_cast<float>(mH) / 2.f;
|
||||
const float worldBottom = static_cast<float>(mH) / 2.f;
|
||||
|
||||
const float landLeft = worldLeft;
|
||||
const float landRight = mLandBoundaryX;
|
||||
const float seaLeft = mLandBoundaryX;
|
||||
const float seaRight = worldRight;
|
||||
|
||||
auto drawSection = [&](const std::shared_ptr<Game::Renderer::Texture>& tex, float startX, float endX) {
|
||||
if (!tex) {
|
||||
return;
|
||||
}
|
||||
|
||||
float tileW = 0.f;
|
||||
float tileH = 0.f;
|
||||
SDL_GetTextureSize(tex->getSDLTexture(), &tileW, &tileH);
|
||||
tileW *= mTiledScale;
|
||||
tileH *= mTiledScale;
|
||||
if (tileW <= 0.f || tileH <= 0.f) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float screenStartX = startX - config.camX + config.screenW / 2.f;
|
||||
const float screenEndX = endX - config.camX + config.screenW / 2.f;
|
||||
const float screenStartY = worldTop - config.camY + config.screenH / 2.f;
|
||||
const float screenEndY = worldBottom - config.camY + config.screenH / 2.f;
|
||||
|
||||
for (float x = screenStartX; x < screenEndX; x += tileW) {
|
||||
for (float y = screenStartY; y < screenEndY; y += tileH) {
|
||||
SDL_FRect dst{ x, y, tileW, tileH };
|
||||
SDL_RenderTexture(renderer->getSDLRenderer(), tex->getSDLTexture(), nullptr, &dst);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
drawSection(mTex, landLeft, landRight);
|
||||
drawSection(mSeaTex, seaLeft, seaRight);
|
||||
}
|
||||
|
||||
void Background::spawnFriendly(int stage, int count) {
|
||||
const float viewLeft = -mW / 2.f;
|
||||
const float viewTop = -mH / 2.f;
|
||||
const float viewBottom = mH / 2.f;
|
||||
|
||||
Object::Transform tS;
|
||||
tS.rotation = 0.f;
|
||||
tS.scaleX = 6.f;
|
||||
tS.scaleY = 6.f;
|
||||
|
||||
const float halfFriendlyW = mFriendlyTex->getWidth() * tS.adjustedScaleX() / 2.f;
|
||||
const float halfFriendlyH = mFriendlyTex->getHeight() * tS.adjustedScaleY() / 2.f;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
tS.x = static_cast<float>(Utils::getUtils().rirng32(static_cast<int>(viewLeft + halfFriendlyW + 25.f), static_cast<int>(mLandBoundaryX - halfFriendlyW - 25.f)));
|
||||
tS.y = static_cast<float>(Utils::getUtils().rirng32(static_cast<int>(viewTop + halfFriendlyH + 100.f), static_cast<int>(viewBottom - halfFriendlyH - 100.f)));
|
||||
GameManager::instantiateEntity(std::make_unique<AGame::Friendly>("Friendly" + std::to_string(stage) + "_" + std::to_string(i + 1), mFriendlyTex, tS));
|
||||
}
|
||||
}
|
||||
|
||||
void Background::spawnLevel(int stage) {
|
||||
const float viewLeft = -mW / 2.f;
|
||||
const float viewRight = mW / 2.f;
|
||||
const float viewTop = -mH / 2.f;
|
||||
const float viewBottom = mH / 2.f;
|
||||
|
||||
const int enemyCount = 2 + stage * 2;
|
||||
const int trashCount = 4 + stage * 3;
|
||||
const int friendlyCount = 1 + (stage - 1);
|
||||
|
||||
GameManager::setSharedData("gameStage", stage);
|
||||
GameManager::setSharedData("enemyActiveCount", enemyCount);
|
||||
GameManager::setSharedData("trashActiveCount", trashCount);
|
||||
GameManager::setSharedData("friendlyActiveCount", friendlyCount);
|
||||
|
||||
if (stage > 1) {
|
||||
auto* player = GameManager::getEntityByName<Player>("Player");
|
||||
if (player) {
|
||||
player->respawnRandomSea(mLandBoundaryX);
|
||||
}
|
||||
}
|
||||
|
||||
Object::Transform tS;
|
||||
tS.rotation = 0.f;
|
||||
|
||||
tS.scaleX = 7.f;
|
||||
tS.scaleY = 7.f;
|
||||
const float halfEnemyW = mEnemyTex->getWidth() * tS.adjustedScaleX() / 2.f;
|
||||
const float halfEnemyH = mEnemyTex->getHeight() * tS.adjustedScaleY() / 2.f;
|
||||
for (int i = 0; i < enemyCount; ++i) {
|
||||
tS.x = static_cast<float>(Utils::getUtils().rirng32(static_cast<int>(viewLeft + halfEnemyW + 25.f), static_cast<int>(mLandBoundaryX - halfEnemyW - 25.f)));
|
||||
tS.y = static_cast<float>(Utils::getUtils().rirng32(static_cast<int>(viewTop + halfEnemyH + 100.f), static_cast<int>(viewBottom - halfEnemyH - 100.f)));
|
||||
GameManager::instantiateEntity(std::make_unique<AGame::Enemy>("Enemy" + std::to_string(stage) + "_" + std::to_string(i + 1), mEnemyTex, tS));
|
||||
}
|
||||
|
||||
tS.scaleX = 5.5f;
|
||||
tS.scaleY = 5.5f;
|
||||
const float halfTrashW = mTrashTex->getWidth() * tS.adjustedScaleX() / 2.f;
|
||||
const float halfTrashH = mTrashTex->getHeight() * tS.adjustedScaleY() / 2.f;
|
||||
for (int i = 0; i < trashCount; ++i) {
|
||||
tS.x = static_cast<float>(Utils::getUtils().rirng32(static_cast<int>(mLandBoundaryX + halfTrashW + 25.f), static_cast<int>(viewRight - halfTrashW - 25.f)));
|
||||
tS.y = static_cast<float>(Utils::getUtils().rirng32(static_cast<int>(viewTop + halfTrashH + 100.f), static_cast<int>(viewBottom - halfTrashH - 100.f)));
|
||||
GameManager::instantiateEntity(std::make_unique<AGame::Trash>("Trash" + std::to_string(stage) + "_" + std::to_string(i + 1), mTrashTex, tS));
|
||||
}
|
||||
|
||||
spawnFriendly(stage, friendlyCount);
|
||||
}
|
||||
|
||||
void Background::update(float deltaTime) {
|
||||
mEnemySpawnTimer += deltaTime;
|
||||
(void)deltaTime;
|
||||
|
||||
int cnt = GameManager::getSharedData<int>("enemyActiveCount");
|
||||
if (mEnemySpawnTimer >= mTimeToSpawn && cnt < 5) {
|
||||
mEnemySpawnTimer = 0.f; // RESET
|
||||
GameManager::setSharedData("enemyActiveCount", cnt + 1);
|
||||
// Spawn Enemy on grass
|
||||
Object::Transform tS;
|
||||
tS.scaleY = 7.f;
|
||||
tS.scaleX = 7.f;
|
||||
tS.rotation = 0.f;
|
||||
const int enemyCount = GameManager::getSharedData<int>("enemyActiveCount");
|
||||
const int trashCount = GameManager::getSharedData<int>("trashActiveCount");
|
||||
const int stage = GameManager::getSharedData<int>("gameStage");
|
||||
|
||||
float camX, camY;
|
||||
Object::Camera::getInstance().getPosition(camX, camY);
|
||||
|
||||
const float halfEnemyW = mEnemyTex->getWidth() * tS.adjustedScaleX() / 2.f;
|
||||
const float halfEnemyH = mEnemyTex->getHeight() * tS.adjustedScaleY() / 2.f;
|
||||
|
||||
const float viewLeft = camX - (mW / 2.f);
|
||||
const float viewRight = camX + (mW / 2.f);
|
||||
const float viewTop = camY - (mH / 2.f);
|
||||
const float viewBottom = camY + (mH / 2.f);
|
||||
|
||||
// Right 1/3 of the currently visible screen, in world coordinates.
|
||||
int spawnMinX = static_cast<int>(viewLeft + (2.f * mW / 3.f) + halfEnemyW);
|
||||
int spawnMaxX = static_cast<int>(viewRight - halfEnemyW - 25.f);
|
||||
int spawnMinY = static_cast<int>(viewTop + halfEnemyH + 100.f);
|
||||
int spawnMaxY = static_cast<int>(viewBottom - halfEnemyH - 100.f);
|
||||
|
||||
// Safety for tiny windows / huge sprites.
|
||||
if (spawnMinX > spawnMaxX) spawnMinX = spawnMaxX = static_cast<int>(camX);
|
||||
if (spawnMinY > spawnMaxY) spawnMinY = spawnMaxY = static_cast<int>(camY);
|
||||
|
||||
tS.x = static_cast<float>(Utils::getUtils().rirng32(spawnMinX, spawnMaxX));
|
||||
tS.y = static_cast<float>(Utils::getUtils().rirng32(spawnMinY, spawnMaxY));
|
||||
GameManager::instantiateEntity(std::make_unique<AGame::Enemy>("Enemy" + std::to_string(cnt + 1), mEnemyTex, tS));
|
||||
|
||||
// Spawn Trash at shoreline
|
||||
tS.scaleX = 5.5f;
|
||||
tS.scaleY = 5.5f;
|
||||
tS.rotation = 0.f;
|
||||
tS.x = mTransform.x - 75.f;
|
||||
tS.y = static_cast<float>(Utils::getUtils().rirng32(spawnMinY, spawnMaxY));
|
||||
GameManager::instantiateEntity(std::make_unique<AGame::Trash>("Trash" + std::to_string(cnt + 1), mTrashTex, tS));
|
||||
if (mPendingLevelSpawn) {
|
||||
if (enemyCount <= 0 && trashCount <= 0) {
|
||||
GameManager::processPendingEntityRemovals();
|
||||
mPendingLevelSpawn = false;
|
||||
spawnLevel(mPendingLevelStage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*const bool* state = SDL_GetKeyboardState(nullptr);
|
||||
if (state[SDL_SCANCODE_P]) {
|
||||
mTransform.scaleX *= 2.f;
|
||||
mTransform.scaleY *= 2.f;
|
||||
if (enemyCount <= 0 && trashCount <= 0) {
|
||||
if (stage < mMaxLevels) {
|
||||
mPendingLevelSpawn = true;
|
||||
mPendingLevelStage = stage + 1;
|
||||
} else if (!GameManager::getSharedData<bool>("gameWon")) {
|
||||
GameManager::setSharedData("gameWon", true);
|
||||
LOG("All levels cleared");
|
||||
}
|
||||
}
|
||||
if (state[SDL_SCANCODE_L]) {
|
||||
mTransform.scaleX *= 0.5f;
|
||||
mTransform.scaleY *= 0.5f;
|
||||
}*/
|
||||
//mTransform.rotation += 1.f; // Rotate clockwise for testing
|
||||
//mTransform.scaleX = 1.f + 1.f * std::sin(RUNNING_TIME() / 0.5f); // Pulsate scale for testing
|
||||
//mTransform.scaleY = 1.f + 0.5f * std::cos(RUNNING_TIME() / 0.5f); // Pulsate scale for testing
|
||||
|
||||
//Object::Camera::getInstance().move(1.f, 0.f);
|
||||
}
|
||||
|
||||
void Background::onWindowResized(int newWidth, int newHeight) {
|
||||
|
||||
Reference in New Issue
Block a user