Physical collisions with enemies and getting shot causes blinking to occur.

linux_template
sigonasr2 2 years ago
parent ab3945542f
commit 20c5ce9c5c
  1. 2
      Faceball2030/assets/map/map1.map
  2. 68
      Faceball2030/main.cpp
  3. 13
      Faceball2030/main.h

@ -9,7 +9,7 @@
8200 8200
8204 8204
40969 40969
32776 41368
24576 24576
8194 8194
8202 8202

@ -18,8 +18,14 @@ EnemyID Enemy::GetID() {
return id; return id;
} }
void Enemy::Hurt() { void Enemy::Hurt(int damage) {
health--; lastHitTime = 0.2f;
for (Triangle& t : mesh.tris) {
t.col[0] = BLACK;
t.col[1] = BLACK;
t.col[2] = BLACK;
}
health-=damage;
} }
bool Enemy::isDead() { bool Enemy::isDead() {
@ -58,15 +64,30 @@ bool Enemy::CanShoot() {
return fireDelay <= 0; return fireDelay <= 0;
} }
void Enemy::ShootBullet() { void Enemy::ShootBullet(int myIndex) {
fireDelay = game->enemyData[GetID()].fireDelay; fireDelay = game->enemyData[GetID()].fireDelay;
game->bullets.push_back({ game->bullet, pos,rot,0.2f,{std::cosf(rot) * game->shotSpd,std::sinf(rot) * game->shotSpd }, YELLOW,false,GetID(),blinking}); game->bullets.push_back({ game->bullet, pos,rot,0.2f,{std::cosf(rot) * game->shotSpd,std::sinf(rot) * game->shotSpd }, YELLOW,false,GetID(),myIndex,blinking});
} }
void Enemy::ReloadBullet(float fElapsedTime) { void Enemy::ReloadBullet(float fElapsedTime) {
fireDelay -= fElapsedTime; fireDelay -= fElapsedTime;
} }
void Enemy::reduceLastHitTimer(float fElapsedTime) {
lastHitTime -= fElapsedTime;
if (lastHitTime <= 0.0f) {
for (Triangle&t:mesh.tris) {
t.col[0] = WHITE;
t.col[1] = WHITE;
t.col[2] = WHITE;
}
}
}
bool Enemy::isLastHitTimerActive() {
return lastHitTime > 0.0f;
}
void FaceBall::InitializeEnemyData() { void FaceBall::InitializeEnemyData() {
enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK }; enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK };
enemyData[EXIT] = { "EXIT",undefined,GREEN }; enemyData[EXIT] = { "EXIT",undefined,GREEN };
@ -1114,22 +1135,30 @@ bool FaceBall::OnUserCreate()
return true; return true;
} }
//Collisions will not occur if the player is dead.
bool FaceBall::CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius) { bool FaceBall::CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius) {
if (game->hp <= 0) { return false; }
vf2d newpos = { pos.x + movementVector.x,pos.y + movementVector.z }; vf2d newpos = { pos.x + movementVector.x,pos.y + movementVector.z };
float dist = std::sqrtf(std::powf(newpos.x - game->player.GetPos().x, 2) + std::powf(newpos.y - game->player.GetPos().z, 2)); float dist = std::sqrtf(std::powf(newpos.x - game->player.GetPos().x, 2) + std::powf(newpos.y - game->player.GetPos().z, 2));
return dist < radius + game->player.GetRadius(); return dist < radius + game->player.GetRadius();
} }
int FaceBall::CheckEnemyCollision(vec3d movementVector, vf2d pos, float radius) { //This returns the index of an enemy that collided (Or -1 if nothing was collided with).
//Collisions will not occur if the enemy is dead.
int FaceBall::CheckEnemyCollision(vec3d movementVector, vf2d pos, float radius,int ignoreIndex) {
vf2d newpos = { pos.x + movementVector.x,pos.y + movementVector.z }; vf2d newpos = { pos.x + movementVector.x,pos.y + movementVector.z };
for (int i = 0; i < game->enemies.size();i++) { for (int i = 0; i < game->enemies.size();i++) {
if (i != ignoreIndex) {
Enemy& e = game->enemies[i]; Enemy& e = game->enemies[i];
if (!e.isDead()) {
float dist = std::sqrtf(std::powf(newpos.x - e.pos.x, 2) + std::powf(newpos.y - e.pos.z, 2)); 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) { if (dist < radius + e.radius) {
return i; return i;
} }
} }
}
}
return -1; return -1;
} }
@ -1139,7 +1168,6 @@ bool Bullet::Update(float fElapsedTime) {
int collided_enemy = FaceBall::CheckEnemyCollision(adjustedSpd, { pos.x,pos.z }, 0.1); int collided_enemy = FaceBall::CheckEnemyCollision(adjustedSpd, { pos.x,pos.z }, 0.1);
if (collided_enemy!=-1) { if (collided_enemy!=-1) {
Enemy& enemy = game->enemies[collided_enemy]; Enemy& enemy = game->enemies[collided_enemy];
if (!enemy.isDead()) {
enemy.Hurt(); enemy.Hurt();
if (enemy.isDead()) { if (enemy.isDead()) {
game->SubtractTag(); game->SubtractTag();
@ -1147,11 +1175,18 @@ bool Bullet::Update(float fElapsedTime) {
return false; return false;
} }
} }
}
else { else {
if (FaceBall::CheckPlayerCollision(adjustedSpd,{pos.x,pos.z},0.1)) { if (FaceBall::CheckPlayerCollision(adjustedSpd,{pos.x,pos.z},0.1)) {
game->HurtPlayer(shooterID,shooterBlinking); game->HurtPlayer(shooterID,shooterBlinking);
return false; return false;
} else
{
int enemyCollisionIndex = FaceBall::CheckEnemyCollision(adjustedSpd, { pos.x,pos.z }, 0.1, shooterIndex);
if (enemyCollisionIndex != -1) {
Enemy& enemy = game->enemies[enemyCollisionIndex];
enemy.Hurt(0);
return false;
}
} }
} }
if (!FaceBall::CheckCollision(adjustedSpd, {pos.x,pos.z}, 0.05)) { if (!FaceBall::CheckCollision(adjustedSpd, {pos.x,pos.z}, 0.05)) {
@ -1280,7 +1315,7 @@ void FaceBall::RenderHud(float fElapsedTime) {
DrawStringDecal({ float(ScreenWidth() / 2 - GetTextSize(bottomText).x / 2 * 3),float(ScreenHeight() - 140.f) }, bottomText, { 96,96,255 }, { 3,6 }); DrawStringDecal({ float(ScreenWidth() / 2 - GetTextSize(bottomText).x / 2 * 3),float(ScreenHeight() - 140.f) }, bottomText, { 96,96,255 }, { 3,6 });
} }
vf2d hudAdjustment = { -32,-18 }; vf2d hudAdjustment = { -32,-18 };
vf2d hudLoc = { hudAdjustment.x + hp>0?hudOffset:0,hudAdjustment.y}; vf2d hudLoc = { hudAdjustment.x + (hp>0?hudOffset:0),hudAdjustment.y};
DrawDecal(hudLoc, hud, { 1.05,1.05 }); DrawDecal(hudLoc, hud, { 1.05,1.05 });
DrawDecal(hudLoc + vf2d{ 704,56 } - hudAdjustment, life4, { 1,1 }, float(hp) / maxHP > 0.75f ? WHITE : VERY_DARK_GREEN); DrawDecal(hudLoc + vf2d{ 704,56 } - hudAdjustment, life4, { 1,1 }, float(hp) / maxHP > 0.75f ? WHITE : VERY_DARK_GREEN);
DrawDecal(hudLoc + vf2d{ 704 - 64,56 } - hudAdjustment, life3, { 1,1 }, float(hp) / maxHP > 0.34f && float(hp) / maxHP <= 0.75f ? WHITE : VERY_DARK_GREEN); DrawDecal(hudLoc + vf2d{ 704 - 64,56 } - hudAdjustment, life3, { 1,1 }, float(hp) / maxHP > 0.34f && float(hp) / maxHP <= 0.75f ? WHITE : VERY_DARK_GREEN);
@ -1363,7 +1398,7 @@ void FaceBall::SubtractTag() {
} }
} }
void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime) { void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime,int myIndex) {
if (e.isDead()) { if (e.isDead()) {
if (!e.deathAnimationOver()) { if (!e.deathAnimationOver()) {
std::vector<Triangle>& tris = e.mesh.tris; std::vector<Triangle>& tris = e.mesh.tris;
@ -1418,11 +1453,12 @@ void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime) {
switch (e.GetPhase()) { switch (e.GetPhase()) {
case Phase::DEFAULT: { case Phase::DEFAULT: {
vf2d movementVec = {std::cosf(e.rot) * dat.movSpd * fElapsedTime,std::sinf(e.rot) * dat.movSpd * fElapsedTime }; vf2d movementVec = {std::cosf(e.rot) * dat.movSpd * fElapsedTime,std::sinf(e.rot) * dat.movSpd * fElapsedTime };
if (!CheckCollision({movementVec.x,0,movementVec.y},{e.pos.x,e.pos.z}, e.radius)) { if (-1==CheckEnemyCollision({ movementVec.x,0,movementVec.y },{e.pos.x,e.pos.z},e.radius,myIndex)&&
!CheckCollision({movementVec.x,0,movementVec.y},{e.pos.x,e.pos.z}, e.radius)) {
e.pos.x += movementVec.x; e.pos.x += movementVec.x;
e.pos.z += movementVec.y; e.pos.z += movementVec.y;
if (e.CanShoot()) { if (e.CanShoot()) {
e.ShootBullet(); e.ShootBullet(myIndex);
} }
} }
else { else {
@ -1458,9 +1494,12 @@ bool FaceBall::OnUserUpdate(float fElapsedTime)
} }
} }
} }
for (std::vector<Enemy>::iterator it = enemies.begin(); it != enemies.end(); ++it) { for (int i = 0; i < enemies.size(); i++) {
Enemy& e = *it; Enemy& e = enemies[i];
RunEnemyAI(e,fElapsedTime); if (e.isLastHitTimerActive()) {
e.reduceLastHitTimer(fElapsedTime);
}
RunEnemyAI(e, fElapsedTime,i);
} }
switch (mode) { switch (mode) {
case GAME: { case GAME: {
@ -1503,7 +1542,6 @@ void FaceBall::OnTextEntryComplete(const std::string& sText) {
int main() int main()
{ {
FaceBall demo; FaceBall demo;
if (demo.Construct(1280, 720, 1, 1)) if (demo.Construct(1280, 720, 1, 1))
demo.Start(); demo.Start();

@ -151,6 +151,7 @@ struct Bullet : Object{
Pixel col = GREEN; Pixel col = GREEN;
bool friendly=true; bool friendly=true;
EnemyID shooterID; EnemyID shooterID;
int shooterIndex = -1;
bool shooterBlinking = false; bool shooterBlinking = false;
bool Update(float fElapsedTime); bool Update(float fElapsedTime);
}; };
@ -187,11 +188,13 @@ struct Enemy : public Object {
float colorFactor = 0; float colorFactor = 0;
Phase phase=Phase::DEFAULT; Phase phase=Phase::DEFAULT;
bool blinking = false; //TODO TO BE IMPLEMENTED. bool blinking = false; //TODO TO BE IMPLEMENTED.
float lastHitTime = 0;
public: public:
float turnAmt = 0; float turnAmt = 0;
Enemy(EnemyID id, vec3d pos, float rot, float radius); Enemy(EnemyID id, vec3d pos, float rot, float radius);
EnemyID GetID(); EnemyID GetID();
void Hurt(); //Can set the damage to 0 to cause just a visual hit.
void Hurt(int damage=1);
bool isDead(); bool isDead();
void increaseDeathTimer(float fElapsedTime); void increaseDeathTimer(float fElapsedTime);
bool deathAnimationOver(); bool deathAnimationOver();
@ -201,8 +204,10 @@ struct Enemy : public Object {
Phase GetPhase(); Phase GetPhase();
void SetPhase(Phase phase); void SetPhase(Phase phase);
bool CanShoot(); bool CanShoot();
void ShootBullet(); void ShootBullet(int myIndex);
void ReloadBullet(float fElapsedTime); void ReloadBullet(float fElapsedTime);
bool isLastHitTimerActive();
void reduceLastHitTimer(float fElapsedTime);
}; };
class FaceBall : public PixelGameEngine class FaceBall : public PixelGameEngine
@ -299,7 +304,7 @@ class FaceBall : public PixelGameEngine
void RenderBulletMesh(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Bullet& b); void RenderBulletMesh(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Bullet& b);
void RenderMesh(mat4x4&matView, std::vector<Triangle>&vecTrianglesToRaster,Object&o); void RenderMesh(mat4x4&matView, std::vector<Triangle>&vecTrianglesToRaster,Object&o);
void RenderMeshDeathScreen(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Object& o); void RenderMeshDeathScreen(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Object& o);
void RunEnemyAI(Enemy& e,float fElapsedTime); void RunEnemyAI(Enemy& e,float fElapsedTime,int myIndex);
void RenderHud(float fElapsedTime); void RenderHud(float fElapsedTime);
void ConvertBulletColor(Mesh& bullet, Pixel col); void ConvertBulletColor(Mesh& bullet, Pixel col);
public: public:
@ -307,7 +312,7 @@ class FaceBall : public PixelGameEngine
Mesh bullet; Mesh bullet;
float shotSpd = 4.0f; float shotSpd = 4.0f;
static bool CheckCollision(vec3d movementVector,vf2d pos,float radius); static bool CheckCollision(vec3d movementVector,vf2d pos,float radius);
static int CheckEnemyCollision(vec3d movementVector, vf2d pos, float radius); static int CheckEnemyCollision(vec3d movementVector, vf2d pos, float radius, int ignoreIndex = -1);
static bool CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius); static bool CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius);
void SubtractTag(); void SubtractTag();
void HurtPlayer(EnemyID id, bool blinking = false); void HurtPlayer(EnemyID id, bool blinking = false);

Loading…
Cancel
Save