diff --git a/The Great Machine/Dungeon.cpp b/The Great Machine/Dungeon.cpp index 9b38493..5748815 100644 --- a/The Great Machine/Dungeon.cpp +++ b/The Great Machine/Dungeon.cpp @@ -82,6 +82,7 @@ Dungeon::Dungeon() Player->HitBox = new Collider{ 0, 0, 28, 36 }; Lives = new olc::Renderable(); + Lives->Load("res/heart.png"); EnemyRenderable = new olc::Renderable(); EnemyRenderable->Load("res/player.png"); @@ -168,6 +169,11 @@ Dungeon::Dungeon() SoundFootsteps.setLoop(true); SoundFootsteps.setVolume(20.f); + SoundBufferHit.loadFromFile("res/hit.wav"); + SoundHit.setBuffer(SoundBufferHit); + SoundHit.setLoop(false); + SoundHit.setVolume(40.f); + } void Dungeon::Generate() @@ -483,7 +489,7 @@ void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) ActiveCamera->Update(fTime); CollisionTick(engine); - if (!HasBegun) return; + if (!HasBegun || !IsAlive || HasWon) return; engine->SetDrawTarget(1); @@ -493,7 +499,7 @@ void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) int enemyBoundsBottom = enemyBoundsTop + 720.0f; // spawn enemies - if (rand() % 100 < 1) + if (rand() % 100 < 1 && Enemies.size() < 20) { Enemy* enemy = new Enemy(); enemy->Type = EEntity::Type::Enemy; @@ -515,10 +521,11 @@ void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) float distanceFromPlayer = vecDistance(Player->Coords, enemy->Coords); _Logger.Debug(enemy->Coords.x, " ", enemy->Coords.y, " ", distanceFromPlayer); - if (distanceFromPlayer > 300) + if (distanceFromPlayer > 300.0f) { enemy->HitBox = new Collider{ 0, 0, 28, 36 }; Enemies.push_back(enemy); + StartedSpawning = true; } else { @@ -534,18 +541,37 @@ void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) enemy->dxdy = static_cast(TileSize) * (fTime * (Player->Speed / 1.5f) * olc::vf2d(desiredLocation - enemy->Coords).norm()); enemy->Coords += enemy->dxdy; + float distanceFromPlayer = vecDistance(Player->Coords, enemy->Coords); + if (distanceFromPlayer > 550.0f) + { + Enemies.erase(Enemies.begin() + i); + delete enemy->HitBox; + delete enemy; + continue; + } + bool colliding = EntityCollide(Player, enemy, engine); if (!colliding) continue; + SoundHit.play(); Player->Life--; Enemies.erase(Enemies.begin() + i); delete enemy->HitBox; delete enemy; } + if (StartedSpawning != true) return; + if (Player->Life <= 0) { IsAlive = false; _Logger.Info("Died, health ", Player->Life); + return; + } + + if(Enemies.size() == 0) + { + HasWon = true; + return; } } @@ -564,8 +590,6 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) // Maps not gonna be big enough for me to care about optimistaion // maybe i should care? i don't - // Entities are always (tilesize / 3) * 2 - // Dungeon Layer engine->SetDrawTarget(4); @@ -621,6 +645,7 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) { SoundFire.play(); LastPlayFire = true; + IsLightOn = true; HasFireLit = true; } @@ -660,7 +685,54 @@ void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) engine->DrawString({15, 15}, std::to_string(Enemies.size()), olc::WHITE, 5); + for (int i = 1; i <= Player->Life; i++) + engine->DrawDecal({static_cast(engine->ScreenWidth() - (static_cast(i) * Lives->Sprite()->width)) ,0.0f}, Lives->Decal()); + if (!IsAlive) + { + SoundFire.stop(); + engine->SetDrawTarget(uint8_t(0)); + engine->Clear({38, 36, 40}); + engine->DrawString({15, engine->ScreenHeight() / 2 - 76}, "your demons overran you", olc::WHITE, 4); + engine->DrawString({15, engine->ScreenHeight() / 2 - 38}, "the machine's manifestations won", olc::WHITE, 4); + engine->DrawString({15, engine->ScreenHeight() / 2}, "you are nothing to them", olc::WHITE, 4); + engine->DrawString({15, engine->ScreenHeight() / 2 + 38}, "you never were", olc::WHITE, 4); + return; + } + + if (HasWon) + { + IsFireLit = false; + SoundFire.stop(); + engine->SetDrawTarget(uint8_t(0)); + engine->Clear({38, 36, 40}); + engine->DrawString({15, engine->ScreenHeight() / 2 - 76}, "you did it..", olc::WHITE, 4); + engine->DrawString({15, engine->ScreenHeight() / 2 - 38}, "you outran all your demons", olc::WHITE, 4); + engine->DrawString({15, engine->ScreenHeight() / 2}, "but your demons never really leave", olc::WHITE, 4); + engine->DrawString({15, engine->ScreenHeight() / 2 + 76}, "welcome to the great machine", olc::WHITE, 4); + engine->DrawString({5, engine->ScreenHeight() - 15}, "Press enter to enter the great machine", olc::WHITE); + + if (engine->GetKey(olc::ENTER).bPressed) + { + _Logger.Info("Restart"); + Player->Life = 7; + Player->Coords = { 5.0f, 5.0f }; + ActiveCamera->TrackEntity(Player); + IsFireLit = true; + StartedSpawning = false; + IsAlive = true; + HasBegun = false; + HasWon = false; + FireAccumilator = 0.0f; + WasFireLit = false; + HasFireLit = false; + LastPlayFire = false; + PlayFire = false; + IsLightOn = false; + } + + return; + } } diff --git a/The Great Machine/Dungeon.hpp b/The Great Machine/Dungeon.hpp index 2bee484..1c8b8ae 100644 --- a/The Great Machine/Dungeon.hpp +++ b/The Great Machine/Dungeon.hpp @@ -38,6 +38,7 @@ class Dungeon Playable* Player; Camera* ActiveCamera; + bool StartedSpawning = false; olc::Renderable* EnemyRenderable; olc::AnimatedSprite* EnemyAnimator; std::vector Enemies; @@ -66,6 +67,9 @@ class Dungeon sf::SoundBuffer SoundBufferFootsteps; sf::Sound SoundFootsteps; + sf::SoundBuffer SoundBufferHit; + sf::Sound SoundHit; + ~Dungeon(); private: diff --git a/The Great Machine/enc_temp_folder/497e7c1a2162817fbeb7197d2f9d9a/Dungeon.cpp b/The Great Machine/enc_temp_folder/497e7c1a2162817fbeb7197d2f9d9a/Dungeon.cpp deleted file mode 100644 index 9f521fb..0000000 --- a/The Great Machine/enc_temp_folder/497e7c1a2162817fbeb7197d2f9d9a/Dungeon.cpp +++ /dev/null @@ -1,689 +0,0 @@ -#include "Dungeon.hpp" - -#include -#include - -#include "olcPixelGameEngine.hpp" -#include "olcPGEX_AnimatedSprite.hpp" - -#include "Collisions.hpp" -#include "Things.hpp" -#include "Camera.hpp" -#include "Logger.hpp" - - -void PerlinNoise1D(int nCount, float *fSeed, int nOctaves, float fBias, float *fOutput) -{ - for (int x = 0; x < nCount; x++) - { - float fNoise = 0.0f; - float fScaleAcc = 0.0f; - float fScale = 1.0f / fBias; - - for (int o = 0; o < nOctaves; o++) - { - int nPitch = nCount >> o; - int nSample1 = (x / nPitch) * nPitch; - int nSample2 = (nSample1 + nPitch) % nCount; - - float fBlend = (float)(x - nSample1) / (float)nPitch; - - float fSample = (1.0f - fBlend) * fSeed[nSample1] + fBlend * fSeed[nSample2]; - - fScaleAcc += fScale; - fNoise += fSample * fScale; - // fScale = fScale / fBias; - } - - // Scale to seed range - fOutput[x] = fNoise / fScaleAcc; - } -} - -static int perlinSize = 10000; -static float* perlinSeed; -static float* perlinOutput; - -void SetupPerlin() -{ - perlinSeed = (float*)malloc(sizeof(float) * perlinSize); - perlinOutput = (float*)malloc(sizeof(float) * perlinSize); - for (int i = 0; i < perlinSize; i++) - perlinSeed[i] = static_cast(rand()) / static_cast(RAND_MAX); - - PerlinNoise1D(perlinSize, perlinSeed, 8, 2.0f, perlinOutput); -} - -float GetNextPerlin() -{ - static int i = 0; - i++; - if (i > perlinSize) - i = 0; - return perlinOutput[i]; -} - - -Dungeon::Dungeon() -: _Logger(Logger::getInstance()) -{ - SetupPerlin(); - - ActiveCamera = new Camera(); - ActiveCamera->Coords = { 0, 0 }; - ActiveCamera->ViewPort = { 1280, 720 }; - - Player = new Playable(); - - Player->Coords = { 2, 2 }; - Player->Type = EEntity::Type::Player; - // Relative to player TL corner - // not really used ? lol - Player->HitBox = new Collider{ 0, 0, 28, 36 }; - - - - EnemyRenderable = new olc::Renderable(); - EnemyRenderable->Load("res/player.png"); - EnemyAnimator = new olc::AnimatedSprite(); - EnemyAnimator->mode = olc::AnimatedSprite::SPRITE_MODE::SINGLE; - EnemyAnimator->type = olc::AnimatedSprite::SPRITE_TYPE::DECAL; - EnemyAnimator->spriteSheet = EnemyRenderable; - EnemyAnimator->SetSpriteSize({28, 36}); - - EnemyAnimator->AddState("idle", 0.127f, olc::AnimatedSprite::PLAY_MODE::LOOP, std::vector{ - {28, 0} - }); - EnemyAnimator->SetState("idle"); - - - Player->Renderable = new olc::Renderable(); - Player->Renderable->Load("res/player.png"); - Player->Animator = new olc::AnimatedSprite(); - Player->Animator->mode = olc::AnimatedSprite::SPRITE_MODE::SINGLE; - Player->Animator->type = olc::AnimatedSprite::SPRITE_TYPE::DECAL; - Player->Animator->spriteSheet = Player->Renderable; - Player->Animator->SetSpriteSize({28, 36}); - - Player->Animator->AddState("idle", 0.127f, olc::AnimatedSprite::PLAY_MODE::LOOP, std::vector{ - {28, 0} - }); - - Player->Animator->AddState("north", 0.127f, olc::AnimatedSprite::PLAY_MODE::LOOP, std::vector{ - {0, 110}, - {28, 110}, - {56, 110}, - {84, 110} - }); - Player->Animator->AddState("east", 0.127f, olc::AnimatedSprite::PLAY_MODE::LOOP, std::vector{ - {0, 36}, - {28, 36}, - {56, 36}, - {84, 36} - }); - Player->Animator->AddState("south", 0.127f, olc::AnimatedSprite::PLAY_MODE::LOOP, std::vector{ - {0, 0}, - {28, 0}, - {56, 0}, - {84, 0} - }); - Player->Animator->AddState("west", 0.127f, olc::AnimatedSprite::PLAY_MODE::LOOP, std::vector{ - {0, 72}, - {28, 72}, - {56, 72}, - {84, 72} - }); - Player->Animator->SetState("idle"); - - ActiveCamera->TrackEntity(Player); - ActiveCamera->Update(0.0f); - - TileSetDictionary = new TileDictionary(); - TileSetDictionary->Register(); - - TileSet = new olc::Renderable(); - TileSet->Load("res/dungeon_tileset.png"); - _Logger.Debug("Texture Loaded: ", TileSet, " ", TileSet->Sprite()->width, " ", TileSet->Sprite()->height); - - FireOverlay = new olc::Renderable(); - FireOverlay->Load("res/torch.png"); - - SoundBufferFireLighting.loadFromFile("res/fire_start.wav"); - SoundFireLighting.setBuffer(SoundBufferFireLighting); - SoundFireLighting.setLoop(false); - SoundFireLighting.setVolume(50.f); - - SoundBufferFire.loadFromFile("res/fire.wav"); - SoundFire.setBuffer(SoundBufferFire); - SoundFire.setLoop(true); - SoundFire.setVolume(100.f); - - SoundBufferAmbient.loadFromFile("res/ambient.ogg"); - SoundAmbient.setBuffer(SoundBufferAmbient); - SoundAmbient.setLoop(true); - SoundAmbient.play(); - - SoundBufferFootsteps.loadFromFile("res/run.ogg"); - SoundFootsteps.setBuffer(SoundBufferFootsteps); - SoundFootsteps.setLoop(true); - SoundFootsteps.setVolume(20.f); - - -} - -void Dungeon::Generate() -{ - srand(time(NULL)); - - DungeonWidth = 0; - DungeonHeight = 0; - - // Generate a dungeon - // Loosely follows the algorithm in section 3.3 "Agent Based Growing" - // http://pcgbook.com/wp-content/uploads/chapter03.pdf - - struct Room - { - int x, y, w, h; - }; - - auto randomRoom = [](int x, int y) - { return new Room{ x, y, (rand() % 7) + 3, (rand() % 7) + 3 }; }; - - std::vector tiles; - - // Starting at 0,0 - - int directionChance = 5; - int roomChance = 5; - int dungeonMinSize = 3000; - - struct Agent - { - // 0 up 1 right 2 down 3 left - int x, y, direction; - }; - - Agent* agent = new Agent(); - agent->x = 0; agent->y = 0; - agent->direction = rand() % 4; - - _Logger.Debug("Agent ", agent->x, " ", agent->y, " ", agent->direction); - - auto addTile = [&](int x, int y) { - for (auto i : tiles) - if (i.x == x && i.y == y) - return; - tiles.push_back({ x, y }); - }; - - addTile(0, 0); - - while (tiles.size() < dungeonMinSize) - { - switch (agent->direction) - { - case 0: agent->y -= 1; break; - case 1: agent->x += 1; break; - case 2: agent->y += 1; break; - case 3: agent->x -= 1; break; - } - addTile(agent->x, agent->y); - - if (rand() % 200 < directionChance) - { - agent->direction = rand() % 4; - directionChance = 0; - } - else - { - directionChance += 5; - } - - if (rand() % 300 < roomChance) - { - Room* room = randomRoom(agent->x, agent->y); - for (int x = room->x; x < room->w + room->x; x++) - for (int y = room->y; y < room->h + room->y; y++) - addTile(x, y); - delete room; - roomChance = 0; - } - else - { - roomChance += 5; - } - } - - for (auto& tile : tiles) - { - if (DungeonWidth <= tile.x) DungeonWidth = tile.x; - if (DungeonHeight <= tile.y) DungeonHeight = tile.y; - - ETile::Type tileType = rand() % 100 > 1 ? ETile::Type::Floor : ETile::Type::FloorV1; - - auto DoesTileExist = [&](olc::vi2d tile) - { - return std::find(tiles.begin(), tiles.end(), tile) != tiles.end(); - }; - - bool tileBelow = DoesTileExist({ tile.x, tile.y + 1 }); - bool tileAbove = DoesTileExist({ tile.x, tile.y - 1 }); - bool tileLeft = DoesTileExist({ tile.x - 1, tile.y }); - bool tileRight = DoesTileExist({ tile.x + 1, tile.y }); - - // Order here is very important! stop fucking it up - - if (!tileAbove) - tileType = ETile::Type::WallU; - if (!tileRight) - tileType = ETile::Type::WallR; - if (!tileBelow) - tileType = ETile::Type::WallD; - if (!tileLeft) - tileType = ETile::Type::WallL; - - if (!tileAbove && !tileBelow) - tileType = ETile::Type::PathAcross; - if (!tileRight && !tileLeft) - tileType = ETile::Type::PathUp; - - if (!tileAbove && !tileLeft) - tileType = ETile::Type::WallTLCorner; - if (!tileAbove && !tileRight) - tileType = ETile::Type::WallTRCorner; - if (!tileBelow && !tileLeft) - tileType = ETile::Type::WallBLCorner; - if (!tileBelow && !tileRight) - tileType = ETile::Type::WallBRCorner; - - if (!tileAbove && !tileBelow && !tileRight) - tileType = ETile::Type::PathRight; - if (!tileAbove && !tileBelow && !tileLeft) - tileType = ETile::Type::PathLeft; - if (!tileRight && !tileLeft && !tileAbove) - tileType = ETile::Type::PathTop; - if (!tileRight && !tileLeft && !tileBelow) - tileType = ETile::Type::PathBottom; - - // Is the tile below free? if so, make it 3D - if (!tileBelow) - { - Tile* psuedo3DTile = new Tile({ tile.x, tile.y + 1 }, - ETile::Type::ThreeDStandard, ETile::State::Default); - DungeonTiles[psuedo3DTile->Coords] = psuedo3DTile; - } - - Tile* t = new Tile(tile, tileType, ETile::State::Default); - DungeonTiles[t->Coords] = t; - } -} - -void Dungeon::Input(olc::PixelGameEngine* engine, float fTime) -{ - - olc::vf2d oldCoords = Player->Coords; - - static std::string state = "idle"; - static std::string lastState = "idle"; - static bool WasMoving = false; - bool IsMoving = false; - - if (engine->GetKey(olc::W).bHeld) - { - Player->Coords.y -= static_cast(TileSize) * (fTime * Player->Speed); - if (state != "north") - state = "north"; - IsMoving = true; - } - if (engine->GetKey(olc::A).bHeld) - { - Player->Coords.x -= static_cast(TileSize) * (fTime * Player->Speed); - if (state != "west") - state = "west"; - IsMoving = true; - } - if (engine->GetKey(olc::S).bHeld) - { - Player->Coords.y += static_cast(TileSize) * (fTime * Player->Speed); - if (state != "south") - state = "south"; - IsMoving = true; - } - if (engine->GetKey(olc::D).bHeld) - { - Player->Coords.x += static_cast(TileSize) * (fTime * Player->Speed); - if (state != "east") - state = "east"; - IsMoving = true; - } - - if (engine->GetKey(olc::W).bHeld && engine->GetKey(olc::A).bHeld) - { - Player->Coords.y += static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - Player->Coords.x += static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - if (state != "west") - state = "west"; - } - if (engine->GetKey(olc::W).bHeld && engine->GetKey(olc::D).bHeld) - { - Player->Coords.y += static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - Player->Coords.x -= static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - if (state != "east") - state = "east"; - - } - if (engine->GetKey(olc::S).bHeld && engine->GetKey(olc::D).bHeld) - { - Player->Coords.y -= static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - Player->Coords.x -= static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - if (state != "east") - state = "east"; - } - if (engine->GetKey(olc::S).bHeld && engine->GetKey(olc::A).bHeld) - { - Player->Coords.y -= static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - Player->Coords.x += static_cast(TileSize) * (fTime * (Player->Speed / 3.0f)); - if (state != "west") - state = "west"; - } - - if (!WasMoving && IsMoving) - { - SoundFootsteps.setPlayingOffset(sf::seconds(0.05f)); - SoundFootsteps.play(); - } - if (WasMoving && !IsMoving) - { - SoundFootsteps.stop(); - } - WasMoving = IsMoving; - - if (oldCoords == Player->Coords) - { - state = "idle"; - SoundFootsteps.pause(); - } - if (state != lastState) - Player->Animator->SetState(state); - lastState = state; - - // Map collisions - olc::vi2d currentTile = { static_cast(Player->Coords.x / TileSize), static_cast(Player->Coords.y / TileSize) }; - - static olc::vi2d lastTile; - - if (lastTile != currentTile) - _Logger.Debug("Player Tile: ", currentTile.x, " ", currentTile.y); - - auto IsMapMember = [&] (int x, int y) { - std::unordered_map::const_iterator found = DungeonTiles.find({x, y}); - return found != DungeonTiles.end(); - }; - - auto IsNeighbouringMapMember = [&] (int x, int y) { - if (IsMapMember(x + 1, y)) return true; - if (IsMapMember(x - 1, y)) return true; - if (IsMapMember(x, y + 1)) return true; - if (IsMapMember(x, y - 1)) return true; - return false; - }; - - // get nearby collidables - std::vector nearbyCollidables; - - for (int x = currentTile.x - 1; x <= currentTile.x + 1; x++) - for (int y = currentTile.y - 1; y <= currentTile.y + 1; y++) - { - //_Logger.Debug("IsMapMember ", x, " ", y, " ", IsMapMember(x,y)); - //_Logger.Debug("IsNeighbouringMapMember ", x, " ", y, " ", IsNeighbouringMapMember(x,y)); - - // If isnt in the map but borders a map tile, add a void type for collision - if (IsMapMember(x,y)) - { - nearbyCollidables.push_back(DungeonTiles[{x, y}]); - } else - { - if (IsNeighbouringMapMember(x,y)) - nearbyCollidables.push_back(new Tile({x, y}, ETile::Type::Void, ETile::State::Default)); - } - } - - // Passes ownership back - CollisionInfo collisionInfo; - bool colliding = EntityCollideDungeon(Player, nearbyCollidables, TileSize, &collisionInfo, engine); - - // collision response - if (colliding) - Player->Coords = oldCoords; - - //if (collisionInfo.CollidingY) - //Player->Coords.y = oldCoords.y; - //if (collisionInfo.CollidingX) - //Player->Coords.x = oldCoords.x; - - // delete nearbyCollidables that are void - for (int i = 0; i < nearbyCollidables.size(); i++) - { - if (nearbyCollidables[i]->Type == ETile::Type::Void) - delete nearbyCollidables[i]; - } - - lastTile = currentTile; -} - -template -float vecDistance(T v1, T v2) -{ - return sqrt(pow(v2.x - v1.x, 2.0f) + pow(v2.y - v1.y, 2.0f) * 1.0f); -} - - -void Dungeon::Update(olc::PixelGameEngine* engine, float fTime) -{ - ActiveCamera->Update(fTime); - CollisionTick(engine); - - if (!HasBegun) return; - - engine->SetDrawTarget(1); - - int enemyBoundsLeft = static_cast(Player->Coords.x - (1280.0f / 2.0f)); - int enemyBoundsTop = static_cast(Player->Coords.y - (720.0f / 2.0f)); - int enemyBoundsRight = enemyBoundsLeft + 1280.0f; - int enemyBoundsBottom = enemyBoundsTop + 720.0f; - - // spawn enemies - if (rand() % 100 < 1) - { - Enemy* enemy = new Enemy(); - enemy->Type = EEntity::Type::Enemy; - enemy->Renderable = EnemyRenderable; - enemy->Animator = EnemyAnimator; - - // This is naive I KNOW. fuck off - // stops integer divisions by 0 - if (enemyBoundsLeft == 0) enemyBoundsLeft = 1; - if (enemyBoundsTop == 0) enemyBoundsTop = 1; - - auto rangedRand = [](float min, float max) -> int { - return static_cast(min) + rand() % ((static_cast(max) + 1) - static_cast(min)); - }; - - enemy->Coords = { static_cast(rangedRand(enemyBoundsLeft, enemyBoundsRight)), static_cast(rangedRand(enemyBoundsTop, enemyBoundsBottom) ) }; - - enemy->dxdy = { static_cast(rand() % 10 - 5), static_cast(rand() % 10 - 5) }; - - float distanceFromPlayer = vecDistance(Player->Coords, enemy->Coords); - _Logger.Debug(enemy->Coords.x, " ", enemy->Coords.y, " ", distanceFromPlayer); - if (distanceFromPlayer > 300) - { - enemy->HitBox = new Collider{ 0, 0, 28, 36 }; - Enemies.push_back(enemy); - } - else - { - delete enemy; - } - } - - olc::vf2d desiredLocation = Player->Coords; - for (int i = 0; i < Enemies.size(); i++) - { - Enemy* enemy = Enemies[i]; - - enemy->dxdy = static_cast(TileSize) * (fTime * (Player->Speed / 1.5f) * olc::vf2d(desiredLocation - enemy->Coords).norm()); - enemy->Coords += enemy->dxdy; - - bool colliding = EntityCollide(Player, enemy, engine); - if (!colliding) continue; - Player->Life--; - Enemies.erase(Enemies.begin() + i); - delete enemy->HitBox; - delete enemy; - } - - if (Player->Life <= 0) - { - IsAlive = false; - _Logger.Info("Died, health ", Player->Life); - } -} - -olc::Pixel pixelMultiply(const int x, const int y, const olc::Pixel& pSource, const olc::Pixel& pDest) -{ - olc::Pixel ret; - ret.r = pDest.r * pSource.r; - ret.g = pDest.g * pSource.g; - ret.b = pDest.b * pSource.b; - ret.a = pDest.a * pSource.a; - return ret; -} - -void Dungeon::Draw(olc::PixelGameEngine* engine, float fTime) -{ - // Maps not gonna be big enough for me to care about optimistaion - // maybe i should care? i don't - - // Entities are always (tilesize / 3) * 2 - - // Dungeon Layer - engine->SetDrawTarget(4); - - engine->SetPixelMode(olc::Pixel::ALPHA); - for (std::pair tile : DungeonTiles) - - engine->DrawPartialDecal({ static_cast((tile.first.x * TileSize) - ActiveCamera->Coords.x), static_cast((tile.first.y * TileSize) - ActiveCamera->Coords.y) }, - { static_cast(TileSize), static_cast(TileSize) }, TileSet->Decal(), TileSetDictionary->Dictionary[tile.second->Type], { 16, 16 }); - - // Entity Layer - engine->SetDrawTarget(3); - - // Draw character - Player->Animator->Draw(fTime, {Player->Coords.x - ActiveCamera->Coords.x, Player->Coords.y - ActiveCamera->Coords.y}); - - for (int i = 0; i < Enemies.size(); i++) - { - Enemies[i]->Animator->SetState("idle"); - Enemies[i]->Animator->Draw(fTime, {Enemies[i]->Coords.x - ActiveCamera->Coords.x, Enemies[i]->Coords.y - ActiveCamera->Coords.y}); - } - - // Lighting layers - engine->SetDrawTarget(2); - - static bool WasFireLit = false; - static bool HasFireLit = false; - static float FireAccumilator = 0.0f; - - if (engine->GetKey(olc::F).bPressed) IsFireLit = true; - - if (!IsLightOn && !HasFireLit) - { - engine->FillRectDecal({0.0f, 0.0f}, {static_cast(engine->ScreenWidth()), static_cast(engine->ScreenHeight())}, olc::Pixel(0,0,0)); - } - - if (!IsFireLit) return; - - // Wait for fire to get going to render - if (WasFireLit != IsFireLit) - { - SoundFireLighting.setPlayingOffset(sf::seconds(0.3f)); - SoundFireLighting.play(); - } - WasFireLit = true; - static bool LastPlayFire = false; - static bool PlayFire = false; - FireAccumilator += fTime; - if (FireAccumilator > 1.4f) - PlayFire = true; - if (FireAccumilator < 1.4f) - return; - if (LastPlayFire != PlayFire) - { - SoundFire.play(); - LastPlayFire = true; - HasFireLit = true; - } - - HasBegun = true; - - static std::function fPixelMultiply = pixelMultiply; - - // loads to make it more chaotic - float lightScale = 1.2f + GetNextPerlin(); GetNextPerlin(); GetNextPerlin(); GetNextPerlin(); GetNextPerlin(); - - float lightX = static_cast(Player->Coords.x - ActiveCamera->Coords.x) - ((FireOverlay->Sprite()->width * lightScale) / 2.0f) + static_cast(Player->HitBox->w) / 2.0f; - float lightY = static_cast(Player->Coords.y - ActiveCamera->Coords.y) - ((FireOverlay->Sprite()->height * lightScale) / 2.0f) + static_cast(Player->HitBox->h) / 2.0f; - - float lightLeft = lightX + 1.0f; - float lightRight = lightX + FireOverlay->Sprite()->width * lightScale - 1.0f; - float lightTop = lightY + 1.0f; - float lightBottom = lightY + FireOverlay->Sprite()->height * lightScale - 1.0f; - - // orange tint - engine->FillRectDecal({0.0f, 0.0f}, {static_cast(engine->ScreenWidth()), static_cast(engine->ScreenHeight())}, olc::Pixel(255, 123, 0, 30)); - - engine->SetPixelMode(fPixelMultiply); - engine->DrawDecal({ lightX, lightY }, FireOverlay->Decal(), {lightScale, lightScale}, olc::RED); - engine->SetPixelMode(olc::Pixel::ALPHA); - - // top - engine->FillRectDecal({0.0f, 0.0f}, {static_cast(engine->ScreenWidth()), lightTop}, olc::BLACK); - // right - engine->FillRectDecal({lightRight, 0.0f}, {static_cast(engine->ScreenWidth()) - lightRight, static_cast(engine->ScreenHeight())}, olc::BLACK); - // bottom - engine->FillRectDecal({0.0f, lightBottom}, {static_cast(engine->ScreenWidth()), static_cast(engine->ScreenHeight()) - lightBottom}, olc::BLACK); - // left - engine->FillRectDecal({0.0f, 0.0f}, {lightLeft, static_cast(engine->ScreenHeight())}, olc::BLACK); - - // UI Layer - engine->SetDrawTarget(1); - - engine->DrawString({15, 15}, std::to_string(Enemies.size()), olc::WHITE, 5); - - - -} - -Dungeon::~Dungeon() -{ - delete Player->HitBox; - delete Player->Renderable; - delete Player->Animator; - delete Player; - - delete ActiveCamera; - delete TileSetDictionary; - delete TileSet; - for (std::pair tile : DungeonTiles) - delete tile.second; - - for (auto enemy : Enemies) - { - delete enemy->HitBox; - delete enemy; - } - - free(perlinSeed); - free(perlinOutput); -} diff --git a/res/ActionVFX_Bullet_Hits_SFX_0322.zip b/res/ActionVFX_Bullet_Hits_SFX_0322.zip new file mode 100644 index 0000000..5cfaa82 Binary files /dev/null and b/res/ActionVFX_Bullet_Hits_SFX_0322.zip differ diff --git a/res/heart.png b/res/heart.png index 2e86ed0..ca5c3e5 100644 Binary files a/res/heart.png and b/res/heart.png differ diff --git a/res/hit.wav b/res/hit.wav new file mode 100644 index 0000000..a43b4d0 Binary files /dev/null and b/res/hit.wav differ