From 2abd640dcb3ea7022754729d608c80930a7a5f86 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 16 Apr 2023 22:17:25 -0500 Subject: [PATCH] Explosion contact hits now occur. Also lowered the radius of SHOOTME2 so they can fit in between barriers. --- Faceball2030/main.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++- Faceball2030/main.h | 6 +++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/Faceball2030/main.cpp b/Faceball2030/main.cpp index b4bce21..1872ea4 100644 --- a/Faceball2030/main.cpp +++ b/Faceball2030/main.cpp @@ -88,12 +88,24 @@ bool Enemy::isLastHitTimerActive() { return lastHitTime > 0.0f; } +bool Enemy::isExplosive() { + return game->enemyData[id].explosive; +} + +void Enemy::setExploded(bool exploded) { + this->exploded = exploded; +} + +bool Enemy::isBlinking() { + return blinking; +} + void FaceBall::InitializeEnemyData() { enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK }; enemyData[EXIT] = { "EXIT",undefined,GREEN }; enemyData[START] = { "SPAWN POSITION",undefined,{128,64,0} }; - enemyData[SHOOTME] = { "SHOOTME",enemy_ShootMe,YELLOW,1,1,PI / 8,2,1 }; - enemyData[SHOOTME2] = { "SHOOTME2",enemy_IShoot,YELLOW,1,1,PI / 6,2,1,0.5f }; + enemyData[SHOOTME] = { "SHOOTME",enemy_ShootMe,YELLOW,1,1,PI / 8,2,1,0.2f,true }; + enemyData[SHOOTME2] = { "SHOOTME2",enemy_IShoot,YELLOW,1,1,PI / 6,2,1,0.3f,true }; enemyData[SONAR] = { "Sonar",enemy_Sonar,RED,5,1,PI / 8,2,1 }; enemyData[COIN] = { "Coin",undefined,BLUE }; enemyData[POWERUP_ARMOR] = { "Armor",undefined,{96,0,96} }; @@ -1066,10 +1078,24 @@ void FaceBall::HandleKeys(float fElapsedTime) { else { if (!CheckCollision({ vLeftStrafe.x,0,0 }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d xMovement{ vLeftStrafe.x,0,0 }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(xMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } if (!CheckCollision({ 0,0,vLeftStrafe.z }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d zMovement{ 0,0,vLeftStrafe.z }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(zMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } } @@ -1084,10 +1110,24 @@ void FaceBall::HandleKeys(float fElapsedTime) { else { if (!CheckCollision({ vRightStrafe.x,0,0 }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d xMovement{ vRightStrafe.x,0,0 }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(xMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } if (!CheckCollision({ 0,0,vRightStrafe.z }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d zMovement{ 0,0,vRightStrafe.z }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(zMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } } @@ -1099,10 +1139,24 @@ void FaceBall::HandleKeys(float fElapsedTime) { else { if (!CheckCollision({ vForward.x,0,0 }, {player.GetPos().x,player.GetPos().z},player.GetRadius())) { vec3d xMovement{ vForward.x,0,0 }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(xMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } if (!CheckCollision({ 0,0,vForward.z }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d zMovement{ 0,0,vForward.z }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(zMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } float distanceToExit = std::sqrtf(std::powf(player.GetPos().x - exit.pos.x, 2) + std::powf(player.GetPos().z - exit.pos.z, 2)); @@ -1119,10 +1173,24 @@ void FaceBall::HandleKeys(float fElapsedTime) { else { if (!CheckCollision({ vReverse.x,0,0 }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d xMovement{ vReverse.x,0,0 }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(xMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); } if (!CheckCollision({ 0,0,vReverse.z }, { player.GetPos().x,player.GetPos().z }, player.GetRadius())) { vec3d zMovement{ 0,0,vReverse.z }; + int enemyCollisionIndex = CheckExplosiveEnemyCollision(zMovement, { player.GetPos().x,player.GetPos().z }, player.GetRadius()); + if (enemyCollisionIndex != -1) { + Enemy& e = enemies[enemyCollisionIndex]; + e.Hurt(999); + e.setExploded(true); + HurtPlayer(e.GetID(), 1, e.isBlinking()); + } player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); } } @@ -1245,6 +1313,25 @@ int FaceBall::CheckEnemyCollision(vec3d movementVector, vf2d pos, float radius,i return -1; } +//This returns the index of only explosive enemies that collided (Or -1 if nothing was collided with). +//Collisions will not occur if the enemy is dead. +int FaceBall::CheckExplosiveEnemyCollision(vec3d movementVector, vf2d pos, float radius, int ignoreIndex) { + vf2d newpos = { pos.x + movementVector.x,pos.y + movementVector.z }; + for (int i = 0; i < game->enemies.size(); i++) { + if (i != ignoreIndex) { + Enemy& e = game->enemies[i]; + if (e.isExplosive()&&!e.isDead()) { + float dist = std::sqrtf(std::powf(newpos.x - e.pos.x, 2) + std::powf(newpos.y - e.pos.z, 2)); + if (dist < radius + e.radius) { + return i; + } + } + } + } + return -1; +} + + bool Bullet::Update(float fElapsedTime) { vec3d adjustedSpd = { spd.x * fElapsedTime,0,spd.y * fElapsedTime }; if (friendly) { diff --git a/Faceball2030/main.h b/Faceball2030/main.h index c0345d5..3cb9f50 100644 --- a/Faceball2030/main.h +++ b/Faceball2030/main.h @@ -166,6 +166,7 @@ struct EnemyData { int ammo = 2; float fireDelay = 1; float radius = 0.2f; + bool explosive = false; //Explodes on contact. }; struct mat4x4 @@ -185,6 +186,7 @@ struct Enemy : public Object { std::vector shots; float fireDelay=0; float deathTimer=0; + bool exploded = false; //If contacted and explosive, then explosion flag is set instead. float colorFactor = 0; Phase phase=Phase::DEFAULT; bool blinking = false; //TODO TO BE IMPLEMENTED. @@ -208,6 +210,9 @@ struct Enemy : public Object { void ReloadBullet(float fElapsedTime); bool isLastHitTimerActive(); void reduceLastHitTimer(float fElapsedTime); + bool isExplosive(); + void setExploded(bool exploded); + bool isBlinking(); }; class FaceBall : public PixelGameEngine @@ -316,6 +321,7 @@ class FaceBall : public PixelGameEngine float shotSpd = 4.0f; 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); static bool CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius); void SubtractTag(); void HurtPlayer(EnemyID id, int damage=1,bool blinking = false);