Compare commits

...

2 Commits

  1. 14
      Faceball2030/assets/map/map1.map
  2. 305
      Faceball2030/main.cpp
  3. 26
      Faceball2030/main.h

@ -19,26 +19,26 @@
8192
8194
8192
15632
8196
16272
16276
8193
2
25492
8201
16144
16272
8192
15508
16276
8197
8351
8197
8195
8198
273
15764
16276
8195
8602
8194
8202
8202
16018
15894
8194
16278

@ -112,16 +112,137 @@ bool Enemy::Update(float fElapsedTime) {
blinkingAmt = std::sinf(30 * aliveTime);
}
}
else {
if (!deathAnimationOver()) {
std::vector<Triangle>& tris = mesh.tris;
uint8_t darkenAmt = 0;
while (getColorFactor() >= 1) {
darkenAmt++;
decreaseColorFactor();
}
if (isExploded()) {
if (!flippedTriangles) {
flippedTriangles = true;
for (Triangle& t : tris) {
vec3d temp = t.p[1];
t.p[1] = t.p[2];
t.p[2] = t.p[1];
}
}
for (Triangle& t : tris) {
float dir = std::atan2f(t.p[0].z, t.p[0].x);
t.p[0].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
t.p[0].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
if (t.p[0].y > 0.041f) {
t.p[0].y = std::max(0.04f, t.p[0].y - 0.8f * fElapsedTime * 3);
}
dir = std::atan2f(t.p[1].z, t.p[1].x);
t.p[1].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
t.p[1].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
if (t.p[1].y > 0.041f) {
t.p[1].y = std::max(0.04f, t.p[1].y - 0.8f * fElapsedTime * 3);
}
dir = std::atan2f(t.p[2].z, t.p[2].x);
t.p[2].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3;
t.p[2].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3;
if (t.p[2].y > 0.041f) {
t.p[2].y = std::max(0.04f, t.p[2].y - 0.8f * fElapsedTime * 3);
}
if (darkenAmt > 0) {
t.col[0] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[1] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[2] -= {darkenAmt, darkenAmt, darkenAmt};
}
}
}
else {
for (Triangle& t : tris) {
if (t.p[0].y > 0.1) {
t.p[0].y = std::max(0.1f, t.p[0].y - 0.3f * fElapsedTime);
}
else {
float dir = std::atan2f(t.p[0].z, t.p[0].x);
t.p[0].x += std::cosf(dir) * 0.04f * fElapsedTime;
t.p[0].z += std::sinf(dir) * 0.04f * fElapsedTime;
}
if (t.p[1].y > 0.1) {
t.p[1].y = std::max(0.1f, t.p[1].y - 0.3f * fElapsedTime);
}
else {
float dir = std::atan2f(t.p[1].z, t.p[1].x);
t.p[1].x += std::cosf(dir) * 0.06f * fElapsedTime;
t.p[1].z += std::sinf(dir) * 0.06f * fElapsedTime;
}
if (t.p[2].y > 0.1) {
t.p[2].y = std::max(0.1f, t.p[2].y - 0.3f * fElapsedTime);
}
else {
float dir = std::atan2f(t.p[2].z, t.p[2].x);
t.p[2].x += std::cosf(dir) * 0.05f * fElapsedTime;
t.p[2].z += std::sinf(dir) * 0.05f * fElapsedTime;
}
if (darkenAmt > 0) {
t.col[0] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[1] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[2] -= {darkenAmt, darkenAmt, darkenAmt};
}
}
}
if (isExploded()) {
increaseDeathTimer(fElapsedTime * 3);
increaseColorFactor(fElapsedTime * 3);
}
else {
increaseDeathTimer(fElapsedTime);
increaseColorFactor(fElapsedTime);
}
}
else
if (!finishedAnimation) {
finishedAnimation = true;
if (isExploded()) {
for (Triangle& t : mesh.tris) {
t.p[0].y = 0.04f + game->restingTriangleYDepth;
t.p[1].y = 0.04f + game->restingTriangleYDepth;
t.p[2].y = 0.04f + game->restingTriangleYDepth;
game->restingTriangleYDepth += 0.000001f;
if (game->restingTriangleYDepth > 0.001f) {
game->restingTriangleYDepth = 0.f;
}
}
}
}
}
return true;
}
//Has Camo powerup code so camo masks the player position.
vf2d Enemy::GetPlayerPosition() {
if (game->PlayerHasCamo()) {
return { float(int(id) % game->MAP_SIZE.x) + 0.5f,float(int(id) % game->MAP_SIZE.y)+0.5f };
}
else {
return game->GetPlayerPos();
}
}
void Enemy::OnDeathEvent() {
game->AddScore(game->enemyData[id].health*10);
game->SubtractTag();
if (game->enemyData[id].powerupDrop != PowerupType::NONE) {
game->SpawnPowerup(game->enemyData[id].powerupDrop, pos);
}
}
vf2d FaceBall::GetPlayerPos() {
return { player.GetPos().x,player.GetPos().z };
}
bool FaceBall::PlayerHasCamo() {
return camoDuration >= 0;
}
void FaceBall::InitializeEnemyData() {
enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK };
enemyData[EXIT] = { "EXIT",undefined,GREEN };
@ -1301,6 +1422,9 @@ void FaceBall::HandleKeys(float fElapsedTime) {
else {
pitch = 0;
if (GetMouse(0).bPressed) {
if (bullets.size() >= shotLimit) {
bullets.erase(bullets.begin());
}
bullets.push_back({ bullet,{player.GetPos().x,player.GetPos().y - 0.15f, player.GetPos().z},fYaw,0.125f,{shotSpd * std::cosf(fYaw),shotSpd * std::sinf(fYaw)},GREEN,true });
}
}
@ -1321,7 +1445,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0?0.2f:0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), xMovement));
}
@ -1334,7 +1458,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), zMovement));
}
@ -1357,7 +1481,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), xMovement));
}
@ -1370,7 +1494,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), zMovement));
}
@ -1390,7 +1514,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), xMovement));
}
@ -1403,7 +1527,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), zMovement));
}
@ -1428,7 +1552,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), xMovement));
}
@ -1441,7 +1565,7 @@ void FaceBall::HandleKeys(float fElapsedTime) {
e.Hurt(999);
e.setExploded(true);
HurtPlayer(e.GetID(), 1, e.isBlinking());
hudShakeTime = 0.6f;
hudShakeTime = shieldDuration >= 0 ? 0.2f : 0.6f;
}
player.UpdatePos(Vector_Add(player.GetPos(), zMovement));
}
@ -1449,10 +1573,10 @@ void FaceBall::HandleKeys(float fElapsedTime) {
}
if (GetKey(olc::A).bHeld) {
if (freeRoam) {
freeRoamCamera_yaw -= 2 * fElapsedTime;
freeRoamCamera_yaw -= turnSpd * fElapsedTime;
}
else {
fYaw -= 2 * fElapsedTime;
fYaw -= turnSpd * fElapsedTime;
if (hudOffset < 20) {
hudOffset = std::min(20.f, hudOffset + 128 * fElapsedTime);
}
@ -1460,10 +1584,10 @@ void FaceBall::HandleKeys(float fElapsedTime) {
}
if (GetKey(olc::D).bHeld) {
if (freeRoam) {
freeRoamCamera_yaw += 2 * fElapsedTime;
freeRoamCamera_yaw += turnSpd * fElapsedTime;
}
else {
fYaw += 2 * fElapsedTime;
fYaw += turnSpd * fElapsedTime;
if (hudOffset > -20) {
hudOffset = std::max(-20.f,hudOffset-128 * fElapsedTime);
}
@ -1644,13 +1768,21 @@ bool Bullet::Update(float fElapsedTime) {
}
void FaceBall::HurtPlayer(EnemyID id,int damage,bool blinking) {
if (shieldDuration >= 0) {
damage = 0;
}
hp = std::max(0, hp - damage);
if (hp <= 0) {
respawnTimer = 3.0f;
}
lastHitBy = id;
lastHitByBlinking = blinking;
if (shieldDuration < 0) {
screenCol = enemyData[lastHitBy].col;
}
else {
screenCol = WHITE;
}
}
void FaceBall::Display3DKillerModel() {
@ -1797,6 +1929,14 @@ void FaceBall::RenderHud(float fElapsedTime) {
}
}
}
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
if (x != 0 && y != 0) {
DrawStringPropDecal(vf2d{ hudOffset + (float)(ScreenWidth() / 2 - GetTextSizeProp(std::to_string(score)).x * 4 / 2) + 32,(float)(36 - GetTextSizeProp(std::to_string(score)).y * 4) + 18 } + hudAdjustment + vf2d{float(x),float(y)}, std::to_string(score), VERY_DARK_RED, {4,4});
}
}
}
DrawStringPropDecal(vf2d{ hudOffset + (float)(ScreenWidth() / 2 - GetTextSizeProp(std::to_string(score)).x * 4 / 2) + 32,(float)(36 - GetTextSizeProp(std::to_string(score)).y * 4) + 18 } + hudAdjustment, std::to_string(score), { 192,96,96 }, { 4,4 });
DrawStringDecal(vf2d{ hudOffset + float(ScreenWidth() / 2 - GetTextSize(hudDisplayText).x / 2 * 4) + 32,float(ScreenHeight() - 128 - GetTextSize(hudDisplayText).y * 4) + 18 }, hudDisplayText, { 192,192,255 }, { 4,4 });
SetDecalMode(DecalMode::ADDITIVE);
DrawDecal({ float(ScreenWidth() / 2 - crosshair->sprite->width / 2),float(ScreenHeight() / 2 - crosshair->sprite->height / 2) }, crosshair, { 1,1 }, {255,255,255,128});
@ -1888,112 +2028,12 @@ void FaceBall::SubtractTag() {
}
void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime,int myIndex) {
if (e.isDead()) {
if (!e.deathAnimationOver()) {
std::vector<Triangle>& tris = e.mesh.tris;
uint8_t darkenAmt = 0;
while (e.getColorFactor() >= 1) {
darkenAmt++;
e.decreaseColorFactor();
}
if (e.isExploded()) {
if (!e.flippedTriangles) {
e.flippedTriangles = true;
for (Triangle& t : tris) {
vec3d temp=t.p[1];
t.p[1] = t.p[2];
t.p[2] = t.p[1];
}
}
for (Triangle& t : tris) {
float dir = std::atan2f(t.p[0].z, t.p[0].x);
t.p[0].x += std::cosf(dir+ (rand() % 200 / 200.f)- 1) * (rand() % 100/100.f) * fElapsedTime*3;
t.p[0].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
if (t.p[0].y > 0.041f) {
t.p[0].y = std::max(0.04f, t.p[0].y - 0.8f * fElapsedTime * 3);
}
dir = std::atan2f(t.p[1].z, t.p[1].x);
t.p[1].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
t.p[1].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 100 / 100.f) * fElapsedTime * 3;
if (t.p[1].y > 0.041f) {
t.p[1].y = std::max(0.04f, t.p[1].y - 0.8f * fElapsedTime * 3);
}
dir = std::atan2f(t.p[2].z, t.p[2].x);
t.p[2].x += std::cosf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3;
t.p[2].z += std::sinf(dir + (rand() % 200 / 200.f) - 1) * (rand() % 70 / 100.f) * fElapsedTime * 3;
if (t.p[2].y > 0.041f) {
t.p[2].y = std::max(0.04f, t.p[2].y - 0.8f * fElapsedTime * 3);
}
if (darkenAmt > 0) {
t.col[0] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[1] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[2] -= {darkenAmt, darkenAmt, darkenAmt};
}
}
}
else {
for (Triangle& t : tris) {
if (t.p[0].y > 0.1) {
t.p[0].y = std::max(0.1f, t.p[0].y - 0.3f * fElapsedTime);
}
else {
float dir = std::atan2f(t.p[0].z, t.p[0].x);
t.p[0].x += std::cosf(dir) * 0.04f * fElapsedTime;
t.p[0].z += std::sinf(dir) * 0.04f * fElapsedTime;
}
if (t.p[1].y > 0.1) {
t.p[1].y = std::max(0.1f, t.p[1].y - 0.3f * fElapsedTime);
}
else {
float dir = std::atan2f(t.p[1].z, t.p[1].x);
t.p[1].x += std::cosf(dir) * 0.06f * fElapsedTime;
t.p[1].z += std::sinf(dir) * 0.06f * fElapsedTime;
}
if (t.p[2].y > 0.1) {
t.p[2].y = std::max(0.1f, t.p[2].y - 0.3f * fElapsedTime);
}
else {
float dir = std::atan2f(t.p[2].z, t.p[2].x);
t.p[2].x += std::cosf(dir) * 0.05f * fElapsedTime;
t.p[2].z += std::sinf(dir) * 0.05f * fElapsedTime;
}
if (darkenAmt > 0) {
t.col[0] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[1] -= {darkenAmt, darkenAmt, darkenAmt};
t.col[2] -= {darkenAmt, darkenAmt, darkenAmt};
}
}
}
if (e.isExploded()) {
e.increaseDeathTimer(fElapsedTime*3);
e.increaseColorFactor(fElapsedTime*3);
}
else {
e.increaseDeathTimer(fElapsedTime);
e.increaseColorFactor(fElapsedTime);
}
}
else
if (!e.finishedAnimation){
e.finishedAnimation = true;
if (e.isExploded()) {
for (Triangle& t : e.mesh.tris) {
t.p[0].y = 0.04f+ restingTriangleYDepth;
t.p[1].y = 0.04f + restingTriangleYDepth;
t.p[2].y = 0.04f + restingTriangleYDepth;
restingTriangleYDepth += 0.000001f;
if (restingTriangleYDepth > 0.001f) {
restingTriangleYDepth = 0.f;
}
}
}
}
}
else {
if (!e.isDead()) {
EnemyData dat = enemyData[e.GetID()];
e.ReloadBullet(fElapsedTime);
switch (e.GetID()) {
case SHOOTME: {
case SHOOTME:
case SHOOTME_ARMOR: {
e.rot += 0.5 * fElapsedTime;
}break;
case SHOOTME2: {
@ -2074,13 +2114,13 @@ bool FaceBall::OnUserUpdate(float fElapsedTime)
switch (mode) {
case GAME: {
hudDisplayText = "";
if (stopDuration > 0) {
if (stopDuration >= 0) {
stopDuration -= fElapsedTime;
}
if (shieldDuration > 0) {
if (shieldDuration >= 0) {
shieldDuration -= fElapsedTime;
}
if (camoDuration > 0) {
if (camoDuration >= 0) {
camoDuration -= fElapsedTime;
}
for (std::vector<Bullet>::iterator it = bullets.begin(); it != bullets.end();) {
@ -2098,8 +2138,10 @@ bool FaceBall::OnUserUpdate(float fElapsedTime)
if (e.isLastHitTimerActive()) {
e.reduceLastHitTimer(fElapsedTime);
}
if (stopDuration < 0) {
RunEnemyAI(e, fElapsedTime, i);
}
}
for (std::vector<Powerup>::iterator it = powerups.begin(); it != powerups.end();) {
Powerup& p = *it;
if (!p.Update(fElapsedTime)) {
@ -2118,13 +2160,18 @@ bool FaceBall::OnUserUpdate(float fElapsedTime)
Powerup& power = powerups[lastPowerupCollidedWith];
switch (power.type) {
case PowerupType::ARMOR: {
armorUpgrades++;
armorUpgrades=std::min(maxArmorUpgrades,armorUpgrades+1);
maxHP = hp = armorUpgrades + baseHP;
}break;
case PowerupType::SPEED: {
speedUpgrades++;
speedUpgrades = std::min(maxSpeedUpgrades, speedUpgrades + 1);
moveSpd = baseMoveSpd + speedUpgrades * 0.5;
turnSpd = baseTurnSpd + speedUpgrades * 0.25;
shotSpd = baseShotSpd + speedUpgrades * 0.5;
}break;
case PowerupType::SHOTS: {
shotsUpgrades++;
shotsUpgrades = std::min(maxShotsUpgrades, shotsUpgrades + 1);
shotLimit = baseShotLimit + shotsUpgrades * 1;
}break;
case PowerupType::STOP: {
stopDuration = 20;
@ -2139,7 +2186,7 @@ bool FaceBall::OnUserUpdate(float fElapsedTime)
hasMapUpgrade = true;
}break;
case PowerupType::COIN: {
score += 1000;
AddScore(1000);
}break;
}
powerups.erase(powerups.begin() + lastPowerupCollidedWith);
@ -2201,6 +2248,20 @@ void FaceBall::OnTextEntryComplete(const std::string& sText) {
}
}
//This function adds to the game score and increments lives appropriately.
void FaceBall::AddScore(int score) {
this->score += score;
if (lastAwardedScore/10000 != this->score/10000) {
lives++;
lastAwardedScore = this->score;
}
}
void FaceBall::ResetScore() {
score = 0;
lastAwardedScore = 0;
}
int main()
{
FaceBall demo;

@ -249,6 +249,7 @@ struct Enemy : public Object {
bool isExploded();
bool Update(float fElapsedTime);
void OnDeathEvent();
vf2d GetPlayerPosition();
};
class FaceBall : public PixelGameEngine
@ -320,20 +321,29 @@ class FaceBall : public PixelGameEngine
};
Player player = { {3.7,0.3,0.7}, {{0.5,0.5},0.2} };
int hp = 3;
const int baseHP = 3;
int hp = baseHP;
int maxHP=hp;
int score = 0;
int lastAwardedScore = 0;
Object walls;
Object exit;
vec3d freeRoamCamera = { 1,0.5,1 };
float freeRoamCamera_pitch = pitch;
float freeRoamCamera_yaw = fYaw;
int armorUpgrades = 2, maxArmorUpgrades=20;
int speedUpgrades = 2, maxSpeedUpgrades=5;
int shotsUpgrades = 2, maxShotsUpgrades=3;
int armorUpgrades = 0, maxArmorUpgrades=20;
int speedUpgrades = 0, maxSpeedUpgrades=5;
int shotsUpgrades = 0, maxShotsUpgrades=3;
float moveSpd = 2.0f;
const float baseMoveSpd = 2.0f;
const float baseTurnSpd = 2.0f;
const float baseShotSpd = 4.0f;
int baseShotLimit = 2;
int shotLimit = baseShotLimit;
float moveSpd = baseMoveSpd;
float turnSpd = baseTurnSpd;
float hudOffset = 0;
float hudOffsetAcc = 0;
float hudShakeAmt = 0;
@ -386,13 +396,14 @@ class FaceBall : public PixelGameEngine
void ConvertBulletColor(Mesh& bullet, Pixel col);
void Display3DKillerModel();
int CheckPowerupCollision(vec3d movementVector, vf2d pos, float radius);
void ResetScore();
public:
vi2d MAP_SIZE;
float restingTriangleYDepth = 0.f;
std::vector<Bullet>bullets;
float hudShakeTime = 0;
Mesh bullet;
float shotSpd = 4.0f;
float shotSpd = baseShotSpd;
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);
@ -400,4 +411,7 @@ class FaceBall : public PixelGameEngine
void SubtractTag();
void HurtPlayer(EnemyID id, int damage=1,bool blinking = false);
void SpawnPowerup(PowerupType type, vec3d pos);
bool PlayerHasCamo();
vf2d GetPlayerPos();
void AddScore(int score);
};
Loading…
Cancel
Save