Physical collisions with enemies and getting shot causes blinking to occur.
This commit is contained in:
parent
ab3945542f
commit
20c5ce9c5c
@ -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…
x
Reference in New Issue
Block a user