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. 84
      Faceball2030/main.cpp
  3. 13
      Faceball2030/main.h

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

@ -18,8 +18,14 @@ EnemyID Enemy::GetID() {
return id;
}
void Enemy::Hurt() {
health--;
void Enemy::Hurt(int damage) {
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() {
@ -58,15 +64,30 @@ bool Enemy::CanShoot() {
return fireDelay <= 0;
}
void Enemy::ShootBullet() {
void Enemy::ShootBullet(int myIndex) {
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) {
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() {
enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK };
enemyData[EXIT] = { "EXIT",undefined,GREEN };
@ -1114,20 +1135,28 @@ bool FaceBall::OnUserCreate()
return true;
}
//Collisions will not occur if the player is dead.
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 };
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();
}
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 };
for (int i = 0; i < game->enemies.size();i++) {
Enemy& e = game->enemies[i];
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;
if (i != ignoreIndex) {
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));
if (dist < radius + e.radius) {
return i;
}
}
}
}
return -1;
@ -1139,19 +1168,25 @@ bool Bullet::Update(float fElapsedTime) {
int collided_enemy = FaceBall::CheckEnemyCollision(adjustedSpd, { pos.x,pos.z }, 0.1);
if (collided_enemy!=-1) {
Enemy& enemy = game->enemies[collided_enemy];
if (!enemy.isDead()) {
enemy.Hurt();
if (enemy.isDead()) {
game->SubtractTag();
}
return false;
enemy.Hurt();
if (enemy.isDead()) {
game->SubtractTag();
}
return false;
}
}
else {
if (FaceBall::CheckPlayerCollision(adjustedSpd,{pos.x,pos.z},0.1)) {
game->HurtPlayer(shooterID,shooterBlinking);
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)) {
@ -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 });
}
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 + 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);
@ -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.deathAnimationOver()) {
std::vector<Triangle>& tris = e.mesh.tris;
@ -1418,11 +1453,12 @@ void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime) {
switch (e.GetPhase()) {
case Phase::DEFAULT: {
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.z += movementVec.y;
if (e.CanShoot()) {
e.ShootBullet();
e.ShootBullet(myIndex);
}
}
else {
@ -1458,9 +1494,12 @@ bool FaceBall::OnUserUpdate(float fElapsedTime)
}
}
}
for (std::vector<Enemy>::iterator it = enemies.begin(); it != enemies.end(); ++it) {
Enemy& e = *it;
RunEnemyAI(e,fElapsedTime);
for (int i = 0; i < enemies.size(); i++) {
Enemy& e = enemies[i];
if (e.isLastHitTimerActive()) {
e.reduceLastHitTimer(fElapsedTime);
}
RunEnemyAI(e, fElapsedTime,i);
}
switch (mode) {
case GAME: {
@ -1503,7 +1542,6 @@ void FaceBall::OnTextEntryComplete(const std::string& sText) {
int main()
{
FaceBall demo;
if (demo.Construct(1280, 720, 1, 1))
demo.Start();

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

Loading…
Cancel
Save