diff --git a/Faceball2030/main.cpp b/Faceball2030/main.cpp index 3ecc7ea..7d5931d 100644 --- a/Faceball2030/main.cpp +++ b/Faceball2030/main.cpp @@ -112,9 +112,120 @@ bool Enemy::Update(float fElapsedTime) { blinkingAmt = std::sinf(30 * aliveTime); } } + else { + if (!deathAnimationOver()) { + std::vector& tris = mesh.tris; + uint8_t darkenAmt = 0; + while (getColorFactor() >= 1) { + darkenAmt++; + decreaseColorFactor(); + } + if (isExploded()) { + if (!flippedTriangles) { + flippedTriangles = true; + for (Triangle& t : tris) { + vec3d temp = t.p[1]; + t.p[1] = t.p[2]; + t.p[2] = t.p[1]; + } + } + for (Triangle& t : tris) { + float dir = std::atan2f(t.p[0].z, t.p[0].x); + t.p[0].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; + t.p[0].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; + if (t.p[0].y > 0.041f) { + t.p[0].y = std::max(0.04f, t.p[0].y - 0.8f * fElapsedTime * 3); + } + dir = std::atan2f(t.p[1].z, t.p[1].x); + t.p[1].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; + t.p[1].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; + if (t.p[1].y > 0.041f) { + t.p[1].y = std::max(0.04f, t.p[1].y - 0.8f * fElapsedTime * 3); + } + dir = std::atan2f(t.p[2].z, t.p[2].x); + t.p[2].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3; + t.p[2].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3; + if (t.p[2].y > 0.041f) { + t.p[2].y = std::max(0.04f, t.p[2].y - 0.8f * fElapsedTime * 3); + } + if (darkenAmt > 0) { + t.col[0] -= {darkenAmt, darkenAmt, darkenAmt}; + t.col[1] -= {darkenAmt, darkenAmt, darkenAmt}; + t.col[2] -= {darkenAmt, darkenAmt, darkenAmt}; + } + } + } + else { + for (Triangle& t : tris) { + if (t.p[0].y > 0.1) { + t.p[0].y = std::max(0.1f, t.p[0].y - 0.3f * fElapsedTime); + } + else { + float dir = std::atan2f(t.p[0].z, t.p[0].x); + t.p[0].x += std::cosf(dir) * 0.04f * fElapsedTime; + t.p[0].z += std::sinf(dir) * 0.04f * fElapsedTime; + } + if (t.p[1].y > 0.1) { + t.p[1].y = std::max(0.1f, t.p[1].y - 0.3f * fElapsedTime); + } + else { + float dir = std::atan2f(t.p[1].z, t.p[1].x); + t.p[1].x += std::cosf(dir) * 0.06f * fElapsedTime; + t.p[1].z += std::sinf(dir) * 0.06f * fElapsedTime; + } + if (t.p[2].y > 0.1) { + t.p[2].y = std::max(0.1f, t.p[2].y - 0.3f * fElapsedTime); + } + else { + float dir = std::atan2f(t.p[2].z, t.p[2].x); + t.p[2].x += std::cosf(dir) * 0.05f * fElapsedTime; + t.p[2].z += std::sinf(dir) * 0.05f * fElapsedTime; + } + if (darkenAmt > 0) { + t.col[0] -= {darkenAmt, darkenAmt, darkenAmt}; + t.col[1] -= {darkenAmt, darkenAmt, darkenAmt}; + t.col[2] -= {darkenAmt, darkenAmt, darkenAmt}; + } + } + } + if (isExploded()) { + increaseDeathTimer(fElapsedTime * 3); + increaseColorFactor(fElapsedTime * 3); + } + else { + increaseDeathTimer(fElapsedTime); + increaseColorFactor(fElapsedTime); + } + } + else + if (!finishedAnimation) { + finishedAnimation = true; + if (isExploded()) { + for (Triangle& t : mesh.tris) { + t.p[0].y = 0.04f + game->restingTriangleYDepth; + t.p[1].y = 0.04f + game->restingTriangleYDepth; + t.p[2].y = 0.04f + game->restingTriangleYDepth; + game->restingTriangleYDepth += 0.000001f; + if (game->restingTriangleYDepth > 0.001f) { + game->restingTriangleYDepth = 0.f; + } + } + } + } + } return true; } +//Has Camo powerup code so camo masks the player position. +vf2d Enemy::GetPlayerPosition() { + if (game->PlayerHasCamo()) { + return { int(id) % game->MAP_SIZE.x,int(id) % game->MAP_SIZE.y }; + } + else { + return game->GetPlayerPos(); + } +} + void Enemy::OnDeathEvent() { game->SubtractTag(); if (game->enemyData[id].powerupDrop != PowerupType::NONE) { @@ -122,6 +233,14 @@ void Enemy::OnDeathEvent() { } } +vf2d FaceBall::GetPlayerPos() { + return { player.GetPos().x,player.GetPos().z }; +} + +bool FaceBall::PlayerHasCamo() { + return camoDuration >= 0; +} + void FaceBall::InitializeEnemyData() { enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK }; enemyData[EXIT] = { "EXIT",undefined,GREEN }; @@ -1301,6 +1420,9 @@ void FaceBall::HandleKeys(float fElapsedTime) { else { pitch = 0; if (GetMouse(0).bPressed) { + if (bullets.size() >= shotLimit) { + bullets.erase(bullets.begin()); + } bullets.push_back({ bullet,{player.GetPos().x,player.GetPos().y - 0.15f, player.GetPos().z},fYaw,0.125f,{shotSpd * std::cosf(fYaw),shotSpd * std::sinf(fYaw)},GREEN,true }); } } @@ -1321,7 +1443,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0?0.2f:0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } @@ -1334,7 +1456,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } @@ -1357,7 +1479,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } @@ -1370,7 +1492,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } @@ -1390,7 +1512,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } @@ -1403,7 +1525,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } @@ -1428,7 +1550,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } @@ -1441,7 +1563,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { e.Hurt(999); e.setExploded(true); HurtPlayer(e.GetID(), 1, e.isBlinking()); - hudShakeTime = 0.6f; + hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f; } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } @@ -1449,10 +1571,10 @@ void FaceBall::HandleKeys(float fElapsedTime) { } if (GetKey(olc::A).bHeld) { if (freeRoam) { - freeRoamCamera_yaw -= 2 * fElapsedTime; + freeRoamCamera_yaw -= turnSpd * fElapsedTime; } else { - fYaw -= 2 * fElapsedTime; + fYaw -= turnSpd * fElapsedTime; if (hudOffset < 20) { hudOffset = std::min(20.f, hudOffset + 128 * fElapsedTime); } @@ -1460,10 +1582,10 @@ void FaceBall::HandleKeys(float fElapsedTime) { } if (GetKey(olc::D).bHeld) { if (freeRoam) { - freeRoamCamera_yaw += 2 * fElapsedTime; + freeRoamCamera_yaw += turnSpd * fElapsedTime; } else { - fYaw += 2 * fElapsedTime; + fYaw += turnSpd * fElapsedTime; if (hudOffset > -20) { hudOffset = std::max(-20.f,hudOffset-128 * fElapsedTime); } @@ -1644,13 +1766,21 @@ bool Bullet::Update(float fElapsedTime) { } void FaceBall::HurtPlayer(EnemyID id,int damage,bool blinking) { + if (shieldDuration >= 0) { + damage = 0; + } hp = std::max(0, hp - damage); if (hp <= 0) { respawnTimer = 3.0f; } lastHitBy = id; lastHitByBlinking = blinking; - screenCol = enemyData[lastHitBy].col; + if (shieldDuration < 0) { + screenCol = enemyData[lastHitBy].col; + } + else { + screenCol = WHITE; + } } void FaceBall::Display3DKillerModel() { @@ -1888,112 +2018,12 @@ void FaceBall::SubtractTag() { } void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime,int myIndex) { - if (e.isDead()) { - if (!e.deathAnimationOver()) { - std::vector& tris = e.mesh.tris; - uint8_t darkenAmt = 0; - while (e.getColorFactor() >= 1) { - darkenAmt++; - e.decreaseColorFactor(); - } - if (e.isExploded()) { - if (!e.flippedTriangles) { - e.flippedTriangles = true; - for (Triangle& t : tris) { - vec3d temp=t.p[1]; - t.p[1] = t.p[2]; - t.p[2] = t.p[1]; - } - } - for (Triangle& t : tris) { - float dir = std::atan2f(t.p[0].z, t.p[0].x); - t.p[0].x += std::cosf(dir+ (rand() % 200 / 200.f)- 1) * (rand() % 100/100.f) * fElapsedTime*3; - t.p[0].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; - if (t.p[0].y > 0.041f) { - t.p[0].y = std::max(0.04f, t.p[0].y - 0.8f * fElapsedTime * 3); - } - dir = std::atan2f(t.p[1].z, t.p[1].x); - t.p[1].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; - t.p[1].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3; - if (t.p[1].y > 0.041f) { - t.p[1].y = std::max(0.04f, t.p[1].y - 0.8f * fElapsedTime * 3); - } - dir = std::atan2f(t.p[2].z, t.p[2].x); - t.p[2].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3; - t.p[2].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3; - if (t.p[2].y > 0.041f) { - t.p[2].y = std::max(0.04f, t.p[2].y - 0.8f * fElapsedTime * 3); - } - if (darkenAmt > 0) { - t.col[0] -= {darkenAmt, darkenAmt, darkenAmt}; - t.col[1] -= {darkenAmt, darkenAmt, darkenAmt}; - t.col[2] -= {darkenAmt, darkenAmt, darkenAmt}; - } - } - } - else { - for (Triangle& t : tris) { - if (t.p[0].y > 0.1) { - t.p[0].y = std::max(0.1f, t.p[0].y - 0.3f * fElapsedTime); - } - else { - float dir = std::atan2f(t.p[0].z, t.p[0].x); - t.p[0].x += std::cosf(dir) * 0.04f * fElapsedTime; - t.p[0].z += std::sinf(dir) * 0.04f * fElapsedTime; - } - if (t.p[1].y > 0.1) { - t.p[1].y = std::max(0.1f, t.p[1].y - 0.3f * fElapsedTime); - } - else { - float dir = std::atan2f(t.p[1].z, t.p[1].x); - t.p[1].x += std::cosf(dir) * 0.06f * fElapsedTime; - t.p[1].z += std::sinf(dir) * 0.06f * fElapsedTime; - } - if (t.p[2].y > 0.1) { - t.p[2].y = std::max(0.1f, t.p[2].y - 0.3f * fElapsedTime); - } - else { - float dir = std::atan2f(t.p[2].z, t.p[2].x); - t.p[2].x += std::cosf(dir) * 0.05f * fElapsedTime; - t.p[2].z += std::sinf(dir) * 0.05f * fElapsedTime; - } - if (darkenAmt > 0) { - t.col[0] -= {darkenAmt, darkenAmt, darkenAmt}; - t.col[1] -= {darkenAmt, darkenAmt, darkenAmt}; - t.col[2] -= {darkenAmt, darkenAmt, darkenAmt}; - } - } - } - if (e.isExploded()) { - e.increaseDeathTimer(fElapsedTime*3); - e.increaseColorFactor(fElapsedTime*3); - } - else { - e.increaseDeathTimer(fElapsedTime); - e.increaseColorFactor(fElapsedTime); - } - } - else - if (!e.finishedAnimation){ - e.finishedAnimation = true; - if (e.isExploded()) { - for (Triangle& t : e.mesh.tris) { - t.p[0].y = 0.04f+ restingTriangleYDepth; - t.p[1].y = 0.04f + restingTriangleYDepth; - t.p[2].y = 0.04f + restingTriangleYDepth; - restingTriangleYDepth += 0.000001f; - if (restingTriangleYDepth > 0.001f) { - restingTriangleYDepth = 0.f; - } - } - } - } - } - else { + if (!e.isDead()) { EnemyData dat = enemyData[e.GetID()]; e.ReloadBullet(fElapsedTime); switch (e.GetID()) { - case SHOOTME: { + case SHOOTME: + case SHOOTME_ARMOR: { e.rot += 0.5 * fElapsedTime; }break; case SHOOTME2: { @@ -2074,13 +2104,13 @@ bool FaceBall::OnUserUpdate(float fElapsedTime) switch (mode) { case GAME: { hudDisplayText = ""; - if (stopDuration > 0) { + if (stopDuration >= 0) { stopDuration -= fElapsedTime; } - if (shieldDuration > 0) { + if (shieldDuration >= 0) { shieldDuration -= fElapsedTime; } - if (camoDuration > 0) { + if (camoDuration >= 0) { camoDuration -= fElapsedTime; } for (std::vector::iterator it = bullets.begin(); it != bullets.end();) { @@ -2098,7 +2128,9 @@ bool FaceBall::OnUserUpdate(float fElapsedTime) if (e.isLastHitTimerActive()) { e.reduceLastHitTimer(fElapsedTime); } - RunEnemyAI(e, fElapsedTime, i); + if (stopDuration < 0) { + RunEnemyAI(e, fElapsedTime, i); + } } for (std::vector::iterator it = powerups.begin(); it != powerups.end();) { Powerup& p = *it; @@ -2118,13 +2150,18 @@ bool FaceBall::OnUserUpdate(float fElapsedTime) Powerup& power = powerups[lastPowerupCollidedWith]; switch (power.type) { case PowerupType::ARMOR: { - armorUpgrades++; + armorUpgrades=std::min(maxArmorUpgrades,armorUpgrades+1); + maxHP = hp = armorUpgrades + baseHP; }break; case PowerupType::SPEED: { - speedUpgrades++; + speedUpgrades = std::min(maxSpeedUpgrades, speedUpgrades + 1); + moveSpd = baseMoveSpd + speedUpgrades * 0.5; + turnSpd = baseTurnSpd + speedUpgrades * 0.25; + shotSpd = baseShotSpd + speedUpgrades * 0.5; }break; case PowerupType::SHOTS: { - shotsUpgrades++; + shotsUpgrades = std::min(maxShotsUpgrades, shotsUpgrades + 1); + shotLimit = baseShotLimit + shotsUpgrades * 1; }break; case PowerupType::STOP: { stopDuration = 20; diff --git a/Faceball2030/main.h b/Faceball2030/main.h index f1f9fc0..02883c8 100644 --- a/Faceball2030/main.h +++ b/Faceball2030/main.h @@ -249,6 +249,7 @@ struct Enemy : public Object { bool isExploded(); bool Update(float fElapsedTime); void OnDeathEvent(); + vf2d GetPlayerPosition(); }; class FaceBall : public PixelGameEngine @@ -320,7 +321,8 @@ class FaceBall : public PixelGameEngine }; Player player = { {3.7,0.3,0.7}, {{0.5,0.5},0.2} }; - int hp = 3; + const int baseHP = 3; + int hp = baseHP; int maxHP=hp; int score = 0; Object walls; @@ -329,11 +331,18 @@ class FaceBall : public PixelGameEngine float freeRoamCamera_pitch = pitch; float freeRoamCamera_yaw = fYaw; - int armorUpgrades = 2, maxArmorUpgrades=20; - int speedUpgrades = 2, maxSpeedUpgrades=5; - int shotsUpgrades = 2, maxShotsUpgrades=3; + int armorUpgrades = 0, maxArmorUpgrades=20; + int speedUpgrades = 0, maxSpeedUpgrades=5; + int shotsUpgrades = 0, maxShotsUpgrades=3; - float moveSpd = 2.0f; + const float baseMoveSpd = 2.0f; + const float baseTurnSpd = 2.0f; + const float baseShotSpd = 4.0f; + int baseShotLimit = 2; + + int shotLimit = baseShotLimit; + float moveSpd = baseMoveSpd; + float turnSpd = baseTurnSpd; float hudOffset = 0; float hudOffsetAcc = 0; float hudShakeAmt = 0; @@ -392,7 +401,7 @@ class FaceBall : public PixelGameEngine std::vectorbullets; float hudShakeTime = 0; Mesh bullet; - float shotSpd = 4.0f; + float shotSpd = baseShotSpd; static bool CheckCollision(vec3d movementVector,vf2d pos,float radius); static int CheckEnemyCollision(vec3d movementVector, vf2d pos, float radius, int ignoreIndex = -1); static int CheckExplosiveEnemyCollision(vec3d movementVector, vf2d pos, float radius, int ignoreIndex = -1); @@ -400,4 +409,5 @@ class FaceBall : public PixelGameEngine void SubtractTag(); void HurtPlayer(EnemyID id, int damage=1,bool blinking = false); void SpawnPowerup(PowerupType type, vec3d pos); + bool PlayerHasCamo(); }; \ No newline at end of file