diff --git a/Faceball2030/assets/hud.png b/Faceball2030/assets/hud.png index 3e670a0..199520d 100644 Binary files a/Faceball2030/assets/hud.png and b/Faceball2030/assets/hud.png differ diff --git a/Faceball2030/assets/hud.xcf b/Faceball2030/assets/hud.xcf index 5c2bb2c..28a8117 100644 Binary files a/Faceball2030/assets/hud.xcf and b/Faceball2030/assets/hud.xcf differ diff --git a/Faceball2030/assets/life1.png b/Faceball2030/assets/life1.png new file mode 100644 index 0000000..7f60c03 Binary files /dev/null and b/Faceball2030/assets/life1.png differ diff --git a/Faceball2030/assets/life2.png b/Faceball2030/assets/life2.png new file mode 100644 index 0000000..ca5d177 Binary files /dev/null and b/Faceball2030/assets/life2.png differ diff --git a/Faceball2030/assets/life3.png b/Faceball2030/assets/life3.png new file mode 100644 index 0000000..d7e2421 Binary files /dev/null and b/Faceball2030/assets/life3.png differ diff --git a/Faceball2030/assets/life4.png b/Faceball2030/assets/life4.png new file mode 100644 index 0000000..c77f6d4 Binary files /dev/null and b/Faceball2030/assets/life4.png differ diff --git a/Faceball2030/assets/map/map1.map b/Faceball2030/assets/map/map1.map index a42bece..e6b3bdd 100644 --- a/Faceball2030/assets/map/map1.map +++ b/Faceball2030/assets/map/map1.map @@ -1,25 +1,25 @@ 8 4 -33195 -33178 -8600 -8604 -8603 -8602 -8600 -8604 +32779 +32778 +8200 +8204 +8203 +8202 +8200 +8204 40969 -33176 -400 -8594 -8618 +32776 +24576 +8194 8202 -8198 +8202 +25110 8197 8193 8192 -8598 -8617 +8198 +8201 8202 8202 8202 @@ -30,5 +30,5 @@ 8195 8202 8202 -25118 +24590 24735 diff --git a/Faceball2030/main.cpp b/Faceball2030/main.cpp index 18b8fe4..805af74 100644 --- a/Faceball2030/main.cpp +++ b/Faceball2030/main.cpp @@ -60,7 +60,7 @@ bool Enemy::CanShoot() { void Enemy::ShootBullet() { 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 }); + game->bullets.push_back({ game->bullet, pos,rot,0.2f,{std::cosf(rot) * game->shotSpd,std::sinf(rot) * game->shotSpd }, YELLOW,false,GetID(),blinking}); } void Enemy::ReloadBullet(float fElapsedTime) { @@ -699,6 +699,134 @@ void FaceBall::RenderMesh(mat4x4&matView,std::vector&vecTrianglesToRas } } +void FaceBall::RenderMeshDeathScreen(mat4x4& matView, std::vector& vecTrianglesToRaster, Object& o) { + for (auto& tri : o.mesh.tris) { + Triangle triProjected, triTransformed, triViewed; + mat4x4 localMat = Matrix_MakeIdentity(); + mat4x4 rotMat = Matrix_MakeRotationY(o.rot); + localMat = Matrix_MultiplyMatrix(localMat, rotMat); + mat4x4 matTrans = Matrix_MakeTranslation(o.pos.x, o.pos.y, o.pos.z); + localMat = Matrix_MultiplyMatrix(localMat, matTrans); + + triTransformed.p[0] = Matrix_MultiplyVector(localMat, tri.p[0]); + triTransformed.p[1] = Matrix_MultiplyVector(localMat, tri.p[1]); + triTransformed.p[2] = Matrix_MultiplyVector(localMat, tri.p[2]); + triTransformed.uv[0] = tri.uv[0]; + triTransformed.uv[1] = tri.uv[1]; + triTransformed.uv[2] = tri.uv[2]; + triTransformed.col[0] = tri.col[0]; + triTransformed.col[1] = tri.col[1]; + triTransformed.col[2] = tri.col[2]; + triTransformed.tex = tri.tex; + + vec3d normal, line1, line2; + line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]); + line2 = Vector_Sub(triTransformed.p[2], triTransformed.p[0]); + + normal = Vector_CrossProduct(line1, line2); + normal = Vector_Normalise(normal); + vec3d camera = { 0.758110702,0.222716771,3.00489759 }; + vec3d vCameraRay = Vector_Sub(triTransformed.p[0], camera); + + if (Vector_DotProduct(normal, vCameraRay) < 0) { + vec3d light_dir = Vector_Mul(vLookDir, -1); + light_dir = Vector_Normalise(light_dir); + + float dp = std::max(0.7f, Vector_DotProduct(light_dir, normal)); + + triViewed.p[0] = Matrix_MultiplyVector(matView, triTransformed.p[0]); + triViewed.p[1] = Matrix_MultiplyVector(matView, triTransformed.p[1]); + triViewed.p[2] = Matrix_MultiplyVector(matView, triTransformed.p[2]); + triViewed.uv[0] = triTransformed.uv[0]; + triViewed.uv[1] = triTransformed.uv[1]; + triViewed.uv[2] = triTransformed.uv[2]; + triViewed.col[0] = Pixel(triTransformed.col[0].r * dp * dp, triTransformed.col[0].g * dp * dp, triTransformed.col[0].b * dp * dp); + triViewed.col[1] = Pixel(triTransformed.col[1].r * dp * dp, triTransformed.col[1].g * dp * dp, triTransformed.col[1].b * dp * dp); + triViewed.col[2] = Pixel(triTransformed.col[2].r * dp * dp, triTransformed.col[2].g * dp * dp, triTransformed.col[2].b * dp * dp); + Pixel originalCol[3] = { triViewed.col[0],triViewed.col[1],triViewed.col[2] }; + float dist = std::sqrtf(std::powf(camera.x - triTransformed.p[0].x, 2) + std::powf(camera.y - triTransformed.p[0].y, 2) + std::powf(camera.z - triTransformed.p[0].z, 2)); + float dist2 = std::sqrtf(std::powf(camera.x - triTransformed.p[1].x, 2) + std::powf(camera.y - triTransformed.p[1].y, 2) + std::powf(camera.z - triTransformed.p[1].z, 2)); + float dist3 = std::sqrtf(std::powf(camera.x - triTransformed.p[2].x, 2) + std::powf(camera.y - triTransformed.p[2].y, 2) + std::powf(camera.z - triTransformed.p[2].z, 2)); + float colorMult = dist > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist + PI / 2); + float colorMult2 = dist2 > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist2 + PI / 2); + float colorMult3 = dist3 > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist3 + PI / 2); + triViewed.col[0] = Pixel(triViewed.col[0].r * colorMult, triViewed.col[0].g * colorMult, triViewed.col[0].b * colorMult); + triViewed.col[1] = Pixel(triViewed.col[1].r * colorMult2, triViewed.col[1].g * colorMult2, triViewed.col[1].b * colorMult2); + triViewed.col[2] = Pixel(triViewed.col[2].r * colorMult3, triViewed.col[2].g * colorMult3, triViewed.col[2].b * colorMult3); + triViewed.tex = triTransformed.tex; + + for (Bullet& b : bullets) { + float dist = std::sqrtf(std::powf(b.pos.x - triTransformed.p[0].x, 2) + std::powf(b.pos.y - triTransformed.p[0].y, 2) + std::powf(b.pos.z - triTransformed.p[0].z, 2)); + float dist2 = std::sqrtf(std::powf(b.pos.x - triTransformed.p[1].x, 2) + std::powf(b.pos.y - triTransformed.p[1].y, 2) + std::powf(b.pos.z - triTransformed.p[1].z, 2)); + float dist3 = std::sqrtf(std::powf(b.pos.x - triTransformed.p[2].x, 2) + std::powf(b.pos.y - triTransformed.p[2].y, 2) + std::powf(b.pos.z - triTransformed.p[2].z, 2)); + float colorMult = (dist < 2 ? std::sinf(0.75 * dist + PI / 2) * 4 : 1); + float colorMult2 = (dist2 < 2 ? std::sinf(0.75 * dist2 + PI / 2) * 4 : 1); + float colorMult3 = (dist3 < 2 ? std::sinf(0.75 * dist3 + PI / 2) * 4 : 1); + Pixel lightCol = b.col / 2 + Pixel{ 128, 128, 128 }; + if (dist < 2) { triViewed.col[0] = Pixel(std::min(255, std::max((int)originalCol[0].r, (int)(originalCol[0].r * colorMult / float(255.f / lightCol.r)))), std::min(255, std::max((int)originalCol[0].g, (int)(originalCol[0].g * colorMult / float(255.f / lightCol.g)))), std::min(255, std::max((int)originalCol[0].b, (int)(originalCol[0].b * colorMult / float(255.f / lightCol.b))))); } + if (dist2 < 2) { triViewed.col[1] = Pixel(std::min(255, std::max((int)originalCol[1].r, (int)(originalCol[1].r * colorMult2 / float(255.f / lightCol.r)))), std::min(255, std::max((int)originalCol[1].g, (int)(originalCol[1].g * colorMult2 / float(255.f / lightCol.g)))), std::min(255, std::max((int)originalCol[1].b, (int)(originalCol[1].b * colorMult2 / float(255.f / lightCol.b))))); } + if (dist3 < 2) { triViewed.col[2] = Pixel(std::min(255, std::max((int)originalCol[2].r, (int)(originalCol[2].r * colorMult3 / float(255.f / lightCol.r)))), std::min(255, std::max((int)originalCol[2].g, (int)(originalCol[2].g * colorMult3 / float(255.f / lightCol.g)))), std::min(255, std::max((int)originalCol[2].b, (int)(originalCol[2].b * colorMult3 / float(255.f / lightCol.b))))); } + } + //triViewed.col = triTransformed.col; + + int nClippedTriangles = 0; + Triangle clipped[2]; + nClippedTriangles = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triViewed, clipped[0], clipped[1]); + + for (int n = 0; n < nClippedTriangles; n++) { + // Project triangles from 3D --> 2D + triProjected.p[0] = Matrix_MultiplyVector(matProj, clipped[n].p[0]); + triProjected.p[1] = Matrix_MultiplyVector(matProj, clipped[n].p[1]); + triProjected.p[2] = Matrix_MultiplyVector(matProj, clipped[n].p[2]); + triProjected.col[0] = clipped[n].col[0]; + triProjected.col[1] = clipped[n].col[1]; + triProjected.col[2] = clipped[n].col[2]; + triProjected.tex = clipped[n].tex; + triProjected.uv[0] = clipped[n].uv[0]; + triProjected.uv[1] = clipped[n].uv[1]; + triProjected.uv[2] = clipped[n].uv[2]; + triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w; + triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w; + triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w; + + triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w; + triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w; + triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w; + + triProjected.uv[0].w = 1.0f / triProjected.p[0].w; + triProjected.uv[1].w = 1.0f / triProjected.p[1].w; + triProjected.uv[2].w = 1.0f / triProjected.p[2].w; + + + triProjected.p[0] = Vector_Div(triProjected.p[0], triProjected.p[0].w); + triProjected.p[1] = Vector_Div(triProjected.p[1], triProjected.p[1].w); + triProjected.p[2] = Vector_Div(triProjected.p[2], triProjected.p[2].w); + + triProjected.p[0].x *= -1.0f; + triProjected.p[1].x *= -1.0f; + triProjected.p[2].x *= -1.0f; + triProjected.p[0].y *= -1.0f; + triProjected.p[1].y *= -1.0f; + triProjected.p[2].y *= -1.0f; + + // Scale into view + vec3d vOffsetView = { 1,1,0 }; + triProjected.p[0] = Vector_Add(triProjected.p[0], vOffsetView); + triProjected.p[1] = Vector_Add(triProjected.p[1], vOffsetView); + triProjected.p[2] = Vector_Add(triProjected.p[2], vOffsetView); + triProjected.p[0].x *= 0.5f * (float)ScreenWidth(); + triProjected.p[0].y *= 0.5f * (float)ScreenHeight(); + triProjected.p[1].x *= 0.5f * (float)ScreenWidth(); + triProjected.p[1].y *= 0.5f * (float)ScreenHeight(); + triProjected.p[2].x *= 0.5f * (float)ScreenWidth(); + triProjected.p[2].y *= 0.5f * (float)ScreenHeight(); + + vecTrianglesToRaster.push_back(triProjected); + } + } + } +} + void FaceBall::RenderWorld() { // Set up rotation matrices mat4x4 matRotZ, matRotX, matWorld; @@ -742,7 +870,6 @@ void FaceBall::RenderWorld() { ClearBuffer(BLACK, true); triRenderCount = 0; for (auto& triToRaster : vecTrianglesToRaster) { - Triangle clipped[2]; std::listlistTriangles; listTriangles.push_back(triToRaster); @@ -967,6 +1094,10 @@ bool FaceBall::OnUserCreate() hud = new Decal(new Sprite("assets/hud.png")); exit_wall_tex = new Decal(new Sprite("assets/exitwall.png")); enemy_IShoot_tex = new Decal(new Sprite("assets/enemies/IShoot.png")); + life4 = new Decal(new Sprite("assets/life4.png")); + life3 = new Decal(new Sprite("assets/life3.png")); + life2 = new Decal(new Sprite("assets/life2.png")); + life1 = new Decal(new Sprite("assets/life1.png")); enemy_ShootMe = { "assets/enemies/ShootMe.obj", enemy_ShootMe_tex }; enemy_IShoot = { "assets/enemies/IShoot.obj", enemy_IShoot_tex }; @@ -983,6 +1114,13 @@ bool FaceBall::OnUserCreate() return true; } +bool FaceBall::CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius) { + 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) { vf2d newpos = { pos.x + movementVector.x,pos.y + movementVector.z }; for (int i = 0; i < game->enemies.size();i++) { @@ -1010,6 +1148,12 @@ bool Bullet::Update(float fElapsedTime) { } } } + else { + if (FaceBall::CheckPlayerCollision(adjustedSpd,{pos.x,pos.z},0.1)) { + game->HurtPlayer(shooterID,shooterBlinking); + return false; + } + } if (!FaceBall::CheckCollision(adjustedSpd, {pos.x,pos.z}, 0.05)) { pos.x += adjustedSpd.x; pos.z += adjustedSpd.z; @@ -1020,6 +1164,12 @@ bool Bullet::Update(float fElapsedTime) { return true; } +void FaceBall::HurtPlayer(EnemyID id,bool blinking) { + hp = std::max(0, hp - 1); + lastHitBy = id; + lastHitByBlinking = blinking; +} + void FaceBall::RenderHud(float fElapsedTime) { if (!GetKey(olc::D).bHeld && !GetKey(olc::A).bHeld) { hudOffsetAcc += 20 * fElapsedTime; @@ -1029,10 +1179,118 @@ void FaceBall::RenderHud(float fElapsedTime) { } } SetDecalMode(DecalMode::NORMAL); - DrawDecal({ -32 + hudOffset,-18 }, hud, { 1.05,1.05 }); - DrawStringDecal({ 112 + hudOffset,4 }, "Triangles: " + std::to_string(triRenderCount), BLACK, { 2,4 }); - std::string hudText = "Tags Left: " + std::to_string(tagsRemaining) + " Lives: " + std::to_string(lives); - DrawStringPropDecal(vf2d{ hudOffset + (float)(ScreenWidth() / 2 - GetTextSizeProp(hudText).x * 3 / 2),(float)(ScreenHeight() - 64 - GetTextSizeProp(hudText).y * 6) }, hudText, WHITE, { 3,6 }); + if (hp <= 0) { + FillRectDecal({ 0,0 }, { float(ScreenWidth()),float(ScreenHeight()) }); + std::string topText = enemyData[lastHitBy].name + " SAYS"; + std::string bottomText = "HAVE A NICE DAY !"; + // Set up rotation matrices + mat4x4 matRotZ, matRotX, matWorld; + + matRotZ = Matrix_MakeRotationZ(0); + matRotX = Matrix_MakeRotationX(0); + + //matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 0.0f); + matWorld = Matrix_MakeIdentity(); + matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX); + //matWorld = Matrix_MultiplyMatrix(matWorld, matTrans); + + vec3d vUp = { 0,1,0 }; + vec3d vTarget = { 0,sinf(0.0944495052),cosf(0.0944495052) }; + mat4x4 matCameraRot = Matrix_MakeRotationY(3.12987614 - PI / 2); + vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget); + vec3d camera = { 0.758110702,0.222716771,3.00489759 }; + vTarget = Vector_Add(camera, vLookDir); + mat4x4 matCamera = Matrix_PointAt(camera, vTarget, vUp); + mat4x4 matView = Matrix_QuickInverse(matCamera); + std::vectorvecTrianglesToRaster; + Object o = { enemyData[lastHitBy].mesh,{0,0,3} }; + RenderMeshDeathScreen(matView, vecTrianglesToRaster, o); + + //std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;}); + if (vecTrianglesToRaster.size() > 0) { + std::cout << vecTrianglesToRaster[0].p[0] << std::endl; + } + triRenderCount = 0; + for (auto& triToRaster : vecTrianglesToRaster) { + Triangle clipped[2]; + std::listlistTriangles; + listTriangles.push_back(triToRaster); + int nNewTriangles = 1; + + for (int p = 0; p < 4; p++) + { + int nTrisToAdd = 0; + while (nNewTriangles > 0) + { + // Take triangle from front of queue + Triangle test = listTriangles.front(); + listTriangles.pop_front(); + nNewTriangles--; + + // Clip it against a plane. We only need to test each + // subsequent plane, against subsequent new triangles + // as all triangles after a plane clip are guaranteed + // to lie on the inside of the plane. I like how this + // comment is almost completely and utterly justified + switch (p) + { + case 0: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, clipped[0], clipped[1]); break; + case 1: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, (float)ScreenHeight() - 1, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, clipped[0], clipped[1]); break; + case 2: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; + case 3: nTrisToAdd = Triangle_ClipAgainstPlane({ (float)ScreenWidth() - 1, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; + } + + // Clipping may yield a variable number of triangles, so + // add these new ones to the back of the queue for subsequent + // clipping against next planes + for (int w = 0; w < nTrisToAdd; w++) + listTriangles.push_back(clipped[w]); + } + nNewTriangles = listTriangles.size(); + } + + for (auto& t : listTriangles) { + // Rasterize triangle + SetDecalStructure(DecalStructure::LIST); + SetDecalMode(DecalMode::NORMAL); + DrawPolygonDecal(t.tex, { + {t.p[0].x, t.p[0].y}, + {t.p[1].x, t.p[1].y}, + {t.p[2].x, t.p[2].y} + }, { + {t.uv[0].u,t.uv[0].v}, + {t.uv[1].u,t.uv[1].v}, + {t.uv[2].u,t.uv[2].v}, + }, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { t.col[0],t.col[1],t.col[2] }); + /*SetDecalMode(DecalMode::WIREFRAME); + DrawPolygonDecal(nullptr,{ + {t.p[0].x, t.p[0].y}, + {t.p[1].x, t.p[1].y}, + {t.p[2].x, t.p[2].y} + },{ + {0,0}, + {0,0}, + {0,0}, + }, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { BLACK,BLACK,BLACK });*/ + SetDecalStructure(DecalStructure::FAN); + triRenderCount++; + } + } + DrawStringDecal({ (float)(ScreenWidth() / 2 - GetTextSize(topText).x / 2 * 3),140.f }, topText, { 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 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); + DrawDecal(hudLoc + vf2d{ 704 - 128,56 } - hudAdjustment, life2, { 1,1 }, hp > 0 && float(hp) / maxHP <= 0.34f ? WHITE : VERY_DARK_GREEN); + DrawDecal(hudLoc + vf2d{ 704 - 192,56 } - hudAdjustment, life1, { 1,1 }, hp <= 0 ? WHITE : VERY_DARK_GREEN); + if (hp > 0) { + DrawStringDecal({ 112 + hudOffset,4 }, "Triangles: " + std::to_string(triRenderCount), BLACK, { 2,4 }); + std::string hudText = "Tags Left: " + std::to_string(tagsRemaining) + " Lives: " + std::to_string(lives); + DrawStringPropDecal(vf2d{ hudOffset + (float)(ScreenWidth() / 2 - GetTextSizeProp(hudText).x * 3 / 2),(float)(ScreenHeight() - 64 - GetTextSizeProp(hudText).y * 6) }, hudText, WHITE, { 3,6 }); + } FillRectDecal({ 0,0 }, vf2d{ (float)ScreenWidth(),(float)ScreenHeight() }, { (uint8_t)0,(uint8_t)0,(uint8_t)0,(uint8_t)screenAlpha }); } @@ -1207,7 +1465,7 @@ bool FaceBall::OnUserUpdate(float fElapsedTime) switch (mode) { case GAME: { HandleKeys(fElapsedTime); - RenderWorld(); + if (hp > 0) { RenderWorld(); } RenderHud(fElapsedTime); }break; case EDITOR: { diff --git a/Faceball2030/main.h b/Faceball2030/main.h index f0c0fe0..db16b03 100644 --- a/Faceball2030/main.h +++ b/Faceball2030/main.h @@ -150,6 +150,8 @@ struct Bullet : Object{ vf2d spd = { 0,0 }; Pixel col = GREEN; bool friendly=true; + EnemyID shooterID; + bool shooterBlinking = false; bool Update(float fElapsedTime); }; @@ -184,6 +186,7 @@ struct Enemy : public Object { float deathTimer=0; float colorFactor = 0; Phase phase=Phase::DEFAULT; + bool blinking = false; //TODO TO BE IMPLEMENTED. public: float turnAmt = 0; Enemy(EnemyID id, vec3d pos, float rot, float radius); @@ -220,7 +223,8 @@ class FaceBall : public PixelGameEngine enemy_Sonar, mapExit,enemy_IShoot; Decal* dot, * enemy_ShootMe_tex,*bullet_tex,*wall_tex,*floor_tex, - *enemy_Sonar_tex,*hud,*exit_wall_tex,*enemy_IShoot_tex; + *enemy_Sonar_tex,*hud,*exit_wall_tex,*enemy_IShoot_tex, + *life4,*life3,*life2,*life1; vi2d MAP_SIZE; vi2d exitCoords = { 0,0 }; std::vector>map; @@ -245,6 +249,8 @@ class FaceBall : public PixelGameEngine float pitch = -PI / 6; Player player = { {3.7,0.3,0.7}, {{0.5,0.5},0.2} }; + int hp = 3; + int maxHP=hp; Object walls; Object exit; vec3d freeRoamCamera = { 1,0.5,1 }; @@ -256,6 +262,9 @@ class FaceBall : public PixelGameEngine float hudOffsetAcc = 0; float screenAlpha = 0; + EnemyID lastHitBy=EnemyID::NONE; + bool lastHitByBlinking = false; + int triRenderCount = 0; vec3d Matrix_MultiplyVector(mat4x4& m, vec3d& i); @@ -289,6 +298,7 @@ class FaceBall : public PixelGameEngine void LoadLevel(int level); void RenderBulletMesh(mat4x4& matView, std::vector& vecTrianglesToRaster, Bullet& b); void RenderMesh(mat4x4&matView, std::vector&vecTrianglesToRaster,Object&o); + void RenderMeshDeathScreen(mat4x4& matView, std::vector& vecTrianglesToRaster, Object& o); void RunEnemyAI(Enemy& e,float fElapsedTime); void RenderHud(float fElapsedTime); void ConvertBulletColor(Mesh& bullet, Pixel col); @@ -298,5 +308,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); + static bool CheckPlayerCollision(vec3d movementVector, vf2d pos, float radius); void SubtractTag(); + void HurtPlayer(EnemyID id, bool blinking = false); }; \ No newline at end of file