[Added] Start of enemies

This commit is contained in:
Ninjaws
2024-12-16 22:27:06 +01:00
parent 5af531a08b
commit e8c78770b5
17 changed files with 580 additions and 101 deletions
-1
View File
@@ -3,7 +3,6 @@
#include "services/AssetService.h" #include "services/AssetService.h"
#include "entities/TextureWrapper.h" #include "entities/TextureWrapper.h"
#include "entities/PBullet.h"
class Crate { class Crate {
public: public:
+223
View File
@@ -0,0 +1,223 @@
#ifndef ENEMY_H
#define ENEMY_H
#include "raylib.h"
#include "services/MapService.h"
#include "services/AssetService.h"
#include "entities/TextureWrapper.h"
#include <cmath>
class Enemy
{
public:
Enemy()
{
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::ENEMY), {32, 32});
this->gunRight = TextureWrapper(AssetService::getInstance().getSprite(ESprite::ENEMY_GUN_RIGHT), {97, 27});
this->gunLeft = TextureWrapper(AssetService::getInstance().getSprite(ESprite::ENEMY_GUN_LEFT), {97, 27});
prevFrame = GetTime();
/** Randomizes between 0 and 1 (+1 to get Left and Right in directions), so they dont all move in the same direction */
int randDir = (int)((int)(GetTime() * 1000000) % 2);
spriteAnimation = {0, randDir + 1};
health = maxHealth;
}
Enemy(Vector2 startPos)
{
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::ENEMY), {32, 32}, startPos);
prevFrame = GetTime();
int randDir = (int)((int)(GetTime() * 1000000) % 2);
spriteAnimation = {0, randDir + 1};
health = maxHealth;
}
void logic()
{
if (health == 0)
{
fall();
}
else
{
walk();
checkForCollision();
animate();
// if (!hasCollided)
// {
// }
}
texture.move(velocity);
}
void draw()
{
drawGun();
drawHealthBar();
DrawTextureRec(this->texture.getTexture(), this->texture.getSourceRect(), this->texture.getPosition(), WHITE);
}
TextureWrapper &getObject()
{
return this->texture;
}
u_int8_t getHealth()
{
return this->health;
}
void takeDamage()
{
this->health = std::max(health - 1, 0);
}
private:
TextureWrapper texture;
TextureWrapper gunLeft;
TextureWrapper gunRight;
u_int8_t health;
u_int8_t maxHealth = 5;
Vector2 velocity = {0, 0};
float spottingRange = 300; // From how far away enemies can spot the player
float gravity = 0.6f;
float moveSpeed = 1.5f;
float animationDelay = 0.2f; // In seconds
double prevFrame; // Time since the last frame
bool hasCollided = false;
Vector2i spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Enemy direction
enum Direction
{
Down,
Left,
Right,
Up
}; // Used in conjuction with spriteAnimation, makes sure sprite direction matches with enemy direction
void walk()
{
if (spriteAnimation.y == Left)
{
velocity.x = -moveSpeed;
}
else
{
velocity.x = moveSpeed;
}
}
void checkForCollision()
{
std::vector corners = getCorners();
std::vector<std::vector<int>> colMap = MapService::getInstance().getMap().getColMap();
hasCollided = false;
if (colMap[corners[2].y][corners[2].x] == 0 || colMap[corners[3].y][corners[3].x] == 0) // No ground below enemy
{
hasCollided = true;
}
else if (colMap[corners[0].y][corners[0].x] == 1 || colMap[corners[1].y][corners[1].x] == 1)
{
hasCollided = true;
}
if (hasCollided)
{
if (spriteAnimation.y == Left)
spriteAnimation.y = Right;
else
spriteAnimation.y = Left;
velocity.x *= -1;
}
}
std::vector<Vector2i> getCorners()
{
float bottom = texture.getPosition().y + texture.getSize().y + velocity.y;
float left = texture.getPosition().x + velocity.x;
float right = texture.getPosition().x + texture.getSize().x + velocity.x;
float top = texture.getPosition().y + velocity.y;
int tileSize = MapService::getInstance().getMap().getTileSize();
// Vector2i leftTop(Vector2i((int)left / tileSize, (int)(top + 5) / tileSize));
// Vector2i leftBottom(Vector2i((int)left / tileSize, (int)(bottom - 5) / tileSize));
Vector2i leftCenter = Vector2i((int)left / tileSize, (int)(bottom - texture.getSize().y / 2.0) / tileSize);
// Vector2i rightTop(Vector2i((int)right / tileSize, (int)(top + 5) / tileSize));
// Vector2i rightBottom(Vector2i((int)right / tileSize, (int)(bottom - 5) / tileSize));
Vector2i rightCenter = Vector2i((int)right / tileSize, (int)(bottom - texture.getSize().y / 2.0) / tileSize);
Vector2i bottomLeft(Vector2i((int)(left + 5) / tileSize, (int)bottom / tileSize)); // +5 to separate bottom from side
Vector2i bottomRight(Vector2i((int)(right - 5) / tileSize, (int)bottom / tileSize)); // -5 to separate bottom from side
std::vector<Vector2i> corners;
corners.push_back(leftCenter);
corners.push_back(rightCenter);
// corners.push_back(leftBottom);
// corners.push_back(rightTop);
// corners.push_back(rightBottom);
corners.push_back(bottomLeft);
corners.push_back(bottomRight);
return corners;
}
void animate()
{
if (GetTime() - prevFrame > animationDelay || hasCollided)
{
spriteAnimation.x = std::fmod(spriteAnimation.x + 1, 3);
Rectangle sourceRect = this->texture.getSourceRect();
sourceRect.x = spriteAnimation.x * this->texture.getSize().x;
sourceRect.y = spriteAnimation.y * this->texture.getSize().y;
// sourceRect.x = std::fmod(sourceRect.x, 3 * this->texture.getSize().x);
this->texture.setSourceRect(sourceRect);
prevFrame = GetTime();
}
}
void drawHealthBar()
{
float barLength = (this->texture.getSize().x / maxHealth) * health;
DrawRectangle(this->texture.getPosition().x, this->texture.getPosition().y - 12.0f, barLength, 3, RED);
}
void drawGun()
{
if (this->spriteAnimation.y == Right)
{
DrawTexturePro(
this->gunRight.getTexture(),
{0, 0, this->gunRight.getSize().x, this->gunRight.getSize().y},
{this->texture.getPosition().x + this->texture.getSize().x / 2.0f,
this->texture.getPosition().y + this->texture.getSize().y / 2.0f,
this->gunRight.getSize().x,
this->gunRight.getSize().y},
{this->gunRight.getSize().x / 3.0f, this->gunRight.getSize().y / 2.0f},
this->gunRight.getRotation(),
WHITE);
}
else if (this->spriteAnimation.y == Left)
{
DrawTexturePro(
this->gunLeft.getTexture(),
{0, 0, this->gunLeft.getSize().x, this->gunLeft.getSize().y},
{this->texture.getPosition().x + this->texture.getSize().x / 2.0f,
this->texture.getPosition().y + this->texture.getSize().y / 2.0f,
this->gunLeft.getSize().x,
this->gunLeft.getSize().y},
{this->gunLeft.getSize().x - this->gunLeft.getSize().x / 3.0f, this->gunLeft.getSize().y / 2.0f},
this->gunLeft.getRotation(),
WHITE);
}
}
void fall()
{
velocity.y += gravity;
}
};
#endif
+48
View File
@@ -0,0 +1,48 @@
#ifndef FLAG_H
#define FLAG_H
#include "raylib.h"
#include "services/AssetService.h"
#include "services/StateService.h"
#include "entities/TextureWrapper.h"
class Flag
{
public:
Flag()
{
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::FLAG), {40, 40});
}
Flag(Vector2 startPos)
{
this->texture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::FLAG), {40, 40}, startPos);
}
void logic()
{
if (touched)
{
StateService::getInstance().setScreen(EScreen::VICTORY);
}
}
void draw()
{
DrawTextureEx(texture.getTexture(), texture.getPosition(), 0.0f, texture.getSize().x/texture.getTexture().width, WHITE);
}
TextureWrapper &getObject()
{
return this->texture;
}
void setTouched(bool touched) {
this->touched = touched;
}
private:
TextureWrapper texture;
bool touched = false; // Whether the player has touched the flag
};
#endif
+11 -6
View File
@@ -9,6 +9,7 @@
#include "services/InputService.h" #include "services/InputService.h"
#include "services/GameService.h" #include "services/GameService.h"
#include "services/CollectableService.h" #include "services/CollectableService.h"
#include "services/EnemyService.h"
#include "entities/Player.h" #include "entities/Player.h"
#include "entities/Text.h" #include "entities/Text.h"
#include "entities/Bullet.h" #include "entities/Bullet.h"
@@ -54,6 +55,7 @@ public:
initHud(); initHud();
initPauseScreen(); initPauseScreen();
initGameOverScreen(); initGameOverScreen();
EnemyService::getInstance().initEnemies();
InputService::getInstance().setKeysToWatch({KEY_A, KEY_W, KEY_S, KEY_D, KEY_ENTER}, {MOUSE_BUTTON_LEFT}); InputService::getInstance().setKeysToWatch({KEY_A, KEY_W, KEY_S, KEY_D, KEY_ENTER}, {MOUSE_BUTTON_LEFT});
AudioService::getInstance().setMusic(EMusic::GAME); AudioService::getInstance().setMusic(EMusic::GAME);
@@ -89,8 +91,10 @@ public:
GameService::getInstance().bulletLogic(); GameService::getInstance().bulletLogic();
CollectableService::getInstance().collectableLogic(); CollectableService::getInstance().collectableLogic();
EnemyService::getInstance().enemyLogic();
this->player.logic(); this->player.logic();
if (this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f) && if (this->player.getTexture().getPosition().x > (StateService::getInstance().getScreenSize().x / 2.0f) &&
this->player.getTexture().getPosition().x + (StateService::getInstance().getScreenSize().x / 2.0f) < background.getBackgroundSize().x) this->player.getTexture().getPosition().x + (StateService::getInstance().getScreenSize().x / 2.0f) < background.getBackgroundSize().x)
{ {
GameService::getInstance().getCamera().offset = {(StateService::getInstance().getScreenSize().x / 2.0f) + ((StateService::getInstance().getScreenSize().x / 2.0f) - this->player.getTexture().getPosition().x), StateService::getInstance().getScreenSize().y / 2.0f}; GameService::getInstance().getCamera().offset = {(StateService::getInstance().getScreenSize().x / 2.0f) + ((StateService::getInstance().getScreenSize().x / 2.0f) - this->player.getTexture().getPosition().x), StateService::getInstance().getScreenSize().y / 2.0f};
@@ -112,6 +116,7 @@ public:
GameService::getInstance().drawBullets(); GameService::getInstance().drawBullets();
this->map.draw(); this->map.draw();
CollectableService::getInstance().drawCollectables(); CollectableService::getInstance().drawCollectables();
EnemyService::getInstance().drawEnemies();
this->player.draw(); this->player.draw();
EndMode2D(); EndMode2D();
@@ -130,11 +135,11 @@ public:
} }
private: private:
// Camera2D camera;
Background background; Background background;
Map map; Map map;
Player player; Player player;
TextureWrapper crosshair; TextureWrapper crosshair;
std::vector<Enemy> enemies;
std::vector<Text> pauseScreenButtons; std::vector<Text> pauseScreenButtons;
int hoveredPauseScreenButton = 0; int hoveredPauseScreenButton = 0;
@@ -143,13 +148,13 @@ private:
std::vector<Text> gameOverScreenButtons; std::vector<Text> gameOverScreenButtons;
int hoveredGameOverScreenButton = 0; int hoveredGameOverScreenButton = 0;
// Font hudJellyFont;
Text hudJellyText; Text hudJellyText;
TextureWrapper hudJellyTexture; TextureWrapper hudJellyTexture;
void initHud() { void initHud()
hudJellyTexture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY),{32,32},{500,5}); {
hudJellyText = Text("0/3",EFont::SANSATION,30,0,RED,{hudJellyTexture.getPosition().x + hudJellyTexture.getSize().x*1.5f, hudJellyTexture.getPosition().y+5}); hudJellyTexture = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY), {32, 32}, {500, 5});
hudJellyText = Text("0/3", EFont::SANSATION, 30, 0, RED, {hudJellyTexture.getPosition().x + hudJellyTexture.getSize().x * 1.5f, hudJellyTexture.getPosition().y + 5});
} }
void initPauseScreen() void initPauseScreen()
+17
View File
@@ -3,6 +3,7 @@
#include "services/CollectableService.h" #include "services/CollectableService.h"
#include "services/AssetService.h" #include "services/AssetService.h"
#include "services/EnemyService.h"
#include "entities/Bullet.h" #include "entities/Bullet.h"
#include <iostream> #include <iostream>
@@ -29,6 +30,22 @@ private:
this->hasCollided = true; this->hasCollided = true;
} }
} }
for (auto &enemy : EnemyService::getInstance().getEnemies())
{
/** If the enemy is already falling of the map, dont allow bullets to hit it anymore */
if(enemy.getHealth() == 0)
continue;
if(this->position.x + this->size > enemy.getObject().getPosition().x && this->position.x-this->size < enemy.getObject().getPosition().x + enemy.getObject().getSize().x &&
this->position.y + this->size > enemy.getObject().getPosition().y && this->position.y-this->size < enemy.getObject().getPosition().y + enemy.getObject().getSize().y) {
enemy.takeDamage();
if(enemy.getHealth() == 0) {
AssetService::getInstance().playSound(ESound::ENEMY_DEFEATED);
}
this->hasCollided = true;
}
}
} }
}; };
+40 -28
View File
@@ -28,7 +28,7 @@ public:
this->prevShot = GetTime(); this->prevShot = GetTime();
this->health = max_health; this->health = max_health;
} }
~Player() ~Player()
{ {
} }
@@ -82,28 +82,28 @@ private:
float jumpPower = 7.2f; float jumpPower = 7.2f;
float moveSpeed = 5.0f; float moveSpeed = 5.0f;
float gravity = 0.6f; float gravity = 0.6f;
float animationDelay = 0.2f; // In seconds float animationDelay = 0.2f; // In seconds
double prevFrame; // Time since the last frame double prevFrame; // Time since the last frame
Vector2i spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Player direction Vector2i spriteAnimation; // Keeps track of (1) Sprite cycling and (2) Player direction
enum Direction enum Direction
{ {
Down, Down,
Left, Left,
Right, Right,
Up Up
}; // Used in conjuction with spriteAnimation, makes sure sprite direction matches with player direction }; // Used in conjuction with spriteAnimation, makes sure sprite direction matches with player direction
std::vector<Vector2i> tiles; // Holds eight points of the player for accurate collision std::vector<Vector2i> tiles; // Holds eight points of the player for accurate collision
std::vector<unsigned int> timesCollision; // Holds the amount of times the player has collided with a tile, and which corner of the player is touching a tile std::vector<unsigned int> timesCollision; // Holds the amount of times the player has collided with a tile, and which corner of the player is touching a tile
bool groundCollision; // Keeps track of whether or not the player has collided with the ground bool groundCollision; // Keeps track of whether or not the player has collided with the ground
bool crateTopCollision; // Whether the player is standing on top of a crate bool crateTopCollision; // Whether the player is standing on top of a crate
uint8_t ammo; // Current ammo of the player uint8_t ammo; // Current ammo of the player
uint8_t max_ammo = 100; // Max ammo of the player uint8_t max_ammo = 100; // Max ammo of the player
float firingRate = 0.2f; // Delay in seconds float firingRate = 0.2f; // Delay in seconds
double prevShot; // The last time the player fired a bullet double prevShot; // The last time the player fired a bullet
uint8_t health; // Current health of the player uint8_t health; // Current health of the player
uint8_t max_health = 10; // Max health of the player uint8_t max_health = 10; // Max health of the player
bool gainedPowerup = false; bool gainedPowerup = false;
void applyGravity() void applyGravity()
@@ -301,9 +301,9 @@ private:
/** Check for collisions with ammo packs */ /** Check for collisions with ammo packs */
for (auto &ammoPack : CollectableService::getInstance().getAmmoPacks()) for (auto &ammoPack : CollectableService::getInstance().getAmmoPacks())
{ {
if (this->texture.getPosition().x + this->texture.getSize().x > ammoPack.getObject().getPosition().x && if (this->texture.getPosition().x + this->texture.getSize().x > ammoPack.getObject().getPosition().x &&
this->texture.getPosition().x < ammoPack.getObject().getPosition().x + ammoPack.getObject().getSize().x && this->texture.getPosition().x<ammoPack.getObject().getPosition().x + ammoPack.getObject().getSize().x &&
this->texture.getPosition().y + this->texture.getSize().y> ammoPack.getObject().getPosition().y && this->texture.getPosition().y + this->texture.getSize().y> ammoPack.getObject().getPosition().y &&
this->texture.getPosition().y < ammoPack.getObject().getPosition().y + ammoPack.getObject().getSize().y) this->texture.getPosition().y < ammoPack.getObject().getPosition().y + ammoPack.getObject().getSize().y)
{ {
ammoPack.setPickedUp(true); ammoPack.setPickedUp(true);
@@ -315,35 +315,47 @@ private:
/** Check for collisions with health packs */ /** Check for collisions with health packs */
for (auto &healthPack : CollectableService::getInstance().getHealthPacks()) for (auto &healthPack : CollectableService::getInstance().getHealthPacks())
{ {
if (this->texture.getPosition().x + this->texture.getSize().x > healthPack.getObject().getPosition().x && if (this->texture.getPosition().x + this->texture.getSize().x > healthPack.getObject().getPosition().x &&
this->texture.getPosition().x < healthPack.getObject().getPosition().x + healthPack.getObject().getSize().x && this->texture.getPosition().x<healthPack.getObject().getPosition().x + healthPack.getObject().getSize().x &&
this->texture.getPosition().y + this->texture.getSize().y> healthPack.getObject().getPosition().y && this->texture.getPosition().y + this->texture.getSize().y> healthPack.getObject().getPosition().y &&
this->texture.getPosition().y < healthPack.getObject().getPosition().y + healthPack.getObject().getSize().y) this->texture.getPosition().y < healthPack.getObject().getPosition().y + healthPack.getObject().getSize().y)
{ {
if(health < max_health) { if (health < max_health)
{
healthPack.setPickedUp(true); healthPack.setPickedUp(true);
AssetService::getInstance().playSound(ESound::HEAL_PICKUP); AssetService::getInstance().playSound(ESound::HEAL_PICKUP);
health = std::max(health+healthPack.getHealAmount(),(int)max_health); health = std::max(health + healthPack.getHealAmount(), (int)max_health);
} }
} }
} }
for (auto &powerup : CollectableService::getInstance().getPowerups()) /** Checks for collisions with powerups */
for (auto &powerup : CollectableService::getInstance().getPowerups())
{ {
if (this->texture.getPosition().x + this->texture.getSize().x > powerup.getObject().getPosition().x && if (this->texture.getPosition().x + this->texture.getSize().x > powerup.getObject().getPosition().x &&
this->texture.getPosition().x < powerup.getObject().getPosition().x + powerup.getObject().getSize().x && this->texture.getPosition().x<powerup.getObject().getPosition().x + powerup.getObject().getSize().x &&
this->texture.getPosition().y + this->texture.getSize().y> powerup.getObject().getPosition().y && this->texture.getPosition().y + this->texture.getSize().y> powerup.getObject().getPosition().y &&
this->texture.getPosition().y < powerup.getObject().getPosition().y + powerup.getObject().getSize().y) this->texture.getPosition().y < powerup.getObject().getPosition().y + powerup.getObject().getSize().y)
{ {
// if(health < max_health) { // if(health < max_health) {
powerup.setPickedUp(true); powerup.setPickedUp(true);
AssetService::getInstance().playSound(ESound::POWERUP); AssetService::getInstance().playSound(ESound::POWERUP);
jumpPower += powerup.getExtraJumpPower(); jumpPower += powerup.getExtraJumpPower();
gainedPowerup = true; gainedPowerup = true;
// health = std::max(health+powerup.getHealAmount(),(int)max_health); // health = std::max(health+powerup.getHealAmount(),(int)max_health);
// } // }
} }
} }
/** Checks for collisions with the finish flag */
auto &flag = CollectableService::getInstance().getFlag();
if (this->texture.getPosition().x + this->texture.getSize().x > flag.getObject().getPosition().x &&
this->texture.getPosition().x<flag.getObject().getPosition().x + flag.getObject().getSize().x &&
this->texture.getPosition().y + this->texture.getSize().y> flag.getObject().getPosition().y &&
this->texture.getPosition().y < flag.getObject().getPosition().y + flag.getObject().getSize().y)
{
flag.setTouched(true);
}
} }
void outofboundsCheck() void outofboundsCheck()
-1
View File
@@ -15,7 +15,6 @@ class TextureWrapper {
this->sourceRect = sourceRect; this->sourceRect = sourceRect;
} }
~TextureWrapper() { ~TextureWrapper() {
} }
Texture2D getTexture() { Texture2D getTexture() {
+2 -1
View File
@@ -16,7 +16,8 @@ enum class ESprite {
HUD_HEART, HUD_HEART,
HUD_HEART_EMPTY, HUD_HEART_EMPTY,
HUD_AMMO, HUD_AMMO,
CROSSHAIR CROSSHAIR,
FLAG,
}; };
#endif #endif
-33
View File
@@ -1,33 +0,0 @@
#ifndef GAME_OVER_SCREEN_H
#define GAME_OVER_SCREEN_H
#include "screens/Screen.h"
#include "raylib.h"
#include "services/AudioService.h"
class GameOverScreen : public Screen
{
public:
GameOverScreen()
{
AudioService::getInstance().setMusic(EMusic::GAME_OVER);
AudioService::getInstance().playMusic();
}
void logic() override
{
}
void draw() override
{
BeginDrawing();
// ClearBackground((Color){255,0,0,100});
DrawRectangle(0, 0, 640, 544, (Color){255,0,0,65});
EndDrawing();
}
private:
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#ifndef VICTORY_SCREEN_H
#define VICTORY_SCREEN_H
#include "raylib.h"
#include "screens/Screen.h"
#include "services/AssetService.h"
#include "entities/TextureWrapper.h"
#include "entities/Text.h"
#include "entities/Background.h"
#include <vector>
class VictoryScreen : public Screen
{
public:
VictoryScreen();
void logic() override;
void draw() override;
private:
std::vector<Text> text;
std::vector<TextureWrapper> textures;
std::vector<Text> buttons;
int hoveredButton = 0;
Background background;
};
#endif
+17 -1
View File
@@ -6,13 +6,16 @@
#include "services/MapService.h" #include "services/MapService.h"
#include "entities/Vector2i.h" #include "entities/Vector2i.h"
#include "entities/Crate.h" #include "entities/Crate.h"
#include "entities/PBullet.h"
#include "entities/Jelly.h" #include "entities/Jelly.h"
#include "entities/AmmoPack.h" #include "entities/AmmoPack.h"
#include "entities/HealthPack.h" #include "entities/HealthPack.h"
#include "entities/Powerup.h" #include "entities/Powerup.h"
#include "entities/Flag.h"
#include <vector> #include <vector>
/**
* Service that manages the collectables (jellies), consumables (Ammo, health, powerups), and the finish flag
*/
class CollectableService : public Service<CollectableService> class CollectableService : public Service<CollectableService>
{ {
public: public:
@@ -23,6 +26,7 @@ public:
initAmmoPacks(); initAmmoPacks();
initHealthPacks(); initHealthPacks();
initPowerups(); initPowerups();
initFlag();
} }
void collectableLogic() void collectableLogic()
@@ -32,6 +36,7 @@ public:
ammoPackLogic(); ammoPackLogic();
healthPackLogic(); healthPackLogic();
powerupLogic(); powerupLogic();
flag.logic();
} }
void drawCollectables() void drawCollectables()
@@ -41,6 +46,7 @@ public:
drawAmmoPacks(); drawAmmoPacks();
drawHealthpacks(); drawHealthpacks();
drawPowerups(); drawPowerups();
flag.draw();
} }
std::vector<Crate> &getCrates() std::vector<Crate> &getCrates()
@@ -62,6 +68,10 @@ public:
return this->powerUps; return this->powerUps;
} }
Flag& getFlag() {
return this->flag;
}
int getMaxAmountOfJellies() int getMaxAmountOfJellies()
{ {
return this->amountOfCrates; return this->amountOfCrates;
@@ -82,6 +92,7 @@ private:
std::vector<HealthPack> healthPacks; std::vector<HealthPack> healthPacks;
std::vector<Jelly> jellies; std::vector<Jelly> jellies;
std::vector<Powerup> powerUps; std::vector<Powerup> powerUps;
Flag flag;
void initCrates() void initCrates()
{ {
@@ -146,6 +157,11 @@ private:
powerUps[0].getObject().setPosition({41.0f * tileSize+8, 10.0f * tileSize-25}); powerUps[0].getObject().setPosition({41.0f * tileSize+8, 10.0f * tileSize-25});
} }
void initFlag() {
int tileSize = MapService::getInstance().getMap().getTileSize();
this->flag = Flag({118.0f*tileSize-tileSize/2.0f, 3.0f * tileSize-8});
}
void crateLogic() void crateLogic()
{ {
for (auto it = crates.begin(); it != crates.end();) for (auto it = crates.begin(); it != crates.end();)
+67
View File
@@ -0,0 +1,67 @@
#ifndef ENEMY_SERVICE_H
#define ENEMY_SERVICE_H
#include "raylib.h"
#include "services/Service.h"
#include "services/AssetService.h"
#include "entities/Enemy.h"
#include <optional>
class EnemyService : public Service<EnemyService>
{
public:
void initEnemies()
{
this->enemies.clear();
const int AMNT_OF_ENEMIES = 8;
int tileSize = MapService::getInstance().getMap().getTileSize();
for (int i = 0; i < AMNT_OF_ENEMIES; i++)
{
enemies.push_back(Enemy());
}
this->enemies[0].getObject().setPosition({31.0f * tileSize, 15.0f * tileSize});
this->enemies[1].getObject().setPosition({51.0f * tileSize, 10.0f * tileSize});
this->enemies[2].getObject().setPosition({56.0f * tileSize, 5.0f * tileSize});
this->enemies[3].getObject().setPosition({78.0f * tileSize, 10.0f * tileSize});
this->enemies[4].getObject().setPosition({82.0f * tileSize, 15.0f * tileSize});
this->enemies[5].getObject().setPosition({88.0f * tileSize, 4.0f * tileSize});
this->enemies[6].getObject().setPosition({98.0f * tileSize, 11.0f * tileSize});
this->enemies[7].getObject().setPosition({103.0f * tileSize, 15.0f * tileSize});
}
void enemyLogic()
{
for (auto it = enemies.begin(); it != enemies.end();)
{
auto &enemy = *it;
if (enemy.getObject().getPosition().y < 0)
{
it = enemies.erase(it);
}
else
{
enemy.logic();
++it;
}
}
}
void drawEnemies()
{
for (int i = 0; i < enemies.size(); i++)
{
enemies[i].draw();
}
}
std::vector<Enemy> &getEnemies()
{
return this->enemies;
}
protected:
private:
std::vector<Enemy> enemies;
};
#endif
-19
View File
@@ -58,25 +58,6 @@ public:
this->playerBullets.push_back(bullet); this->playerBullets.push_back(bullet);
} }
// std::list<PBullet>& getPlayerBullets() {
// return this->playerBullets;
// }
// void removeCollidedBullets()
// {
// for (auto it = playerBullets.begin(); it != playerBullets.end(); /* no increment here */)
// {
// if (it->getHasCollided())
// {
// it = playerBullets.erase(it); // Remove element and get the next valid iterator
// }
// else
// {
// ++it; // Only increment if no removal happens
// }
// }
// }
void bulletLogic() void bulletLogic()
{ {
for (auto it = this->playerBullets.begin(); it != this->playerBullets.end();) for (auto it = this->playerBullets.begin(); it != this->playerBullets.end();)
-7
View File
@@ -40,13 +40,6 @@ MainScreen::MainScreen()
void MainScreen::logic() void MainScreen::logic()
{ {
// Vector2 mouseD = GetMouseDelta();
// std::cout << mouseD.y <<std::endl;
// if (mouseD.x != 0.0f && mouseD.y != 0.0f)
// {
// mouseLogic();
// }
keyboardLogic(); keyboardLogic();
clickLogic(); clickLogic();
+119
View File
@@ -0,0 +1,119 @@
#include "screens/VictoryScreen.h"
#include "services/InputService.h"
#include "services/AudioService.h"
#include "services/CollectableService.h"
#include <string>
#include <sstream>
VictoryScreen::VictoryScreen()
{
AudioService::getInstance().stopMusic();
AssetService::getInstance().playSound(ESound::VICTORY);
Text victory = Text("victory", EFont::GTEK, 50, 0, {255, 0, 0, 255});
victory.setPosition({(float)(GetScreenWidth() - victory.getDimensions().x) / 2.0f,
(float)(GetScreenHeight() - victory.getDimensions().y) / 2.5f});
int amntOfJelliesRescued = CollectableService::getInstance().getAmountOfJelliesFreed();
int maxAmntOfJellies = CollectableService::getInstance().getMaxAmountOfJellies();
std::string rescuedString;
if (amntOfJelliesRescued == maxAmntOfJellies)
{
rescuedString = "You have rescued all of the jellies!";
}
else
{
std::stringstream stream;
stream << "You have rescued ";
stream << amntOfJelliesRescued;
stream << " of the ";
stream << maxAmntOfJellies;
stream << " jellies";
rescuedString = stream.str();
}
Text rescued = Text(rescuedString, EFont::SANSATION, 30, 0, WHITE);
rescued.setPosition({(float)(GetScreenWidth() - rescued.getDimensions().x) / 2.0f,
(float)(GetScreenHeight() - rescued.getDimensions().y) / 1.5f});
this->text.push_back(victory);
this->text.push_back(rescued);
const int TOP_POS = GetScreenHeight()/1.2;
const int X_GAP = 70;
const int AMNT_OF_BUTTONS = 2;
const int TOTAL_SPACE = GetScreenWidth() - X_GAP * 2;
const int SPACE_PER_ITEM = TOTAL_SPACE / AMNT_OF_BUTTONS;
for (int i = 0; i < AMNT_OF_BUTTONS; i++)
{
Text txt = Text("Play Again", EFont::SANSATION, 30, 0, WHITE);
buttons.push_back(txt);
}
buttons[0].setColor(RED);
buttons[1].setText("Return to Main Menu");
buttons[0].setPosition({(float)X_GAP, (float)TOP_POS});
buttons[1].setPosition({(float)GetScreenWidth() - X_GAP - buttons[1].getDimensions().x, (float)TOP_POS});
const int x_gap = 50;
const int available_space = GetScreenWidth() - x_gap * 2;
const int space_per_jelly = available_space / maxAmntOfJellies;
for (int i = 0; i < amntOfJelliesRescued; i++)
{
TextureWrapper wrapper = TextureWrapper(AssetService::getInstance().getSprite(ESprite::JELLY), {32, 32});
wrapper.setPosition({(float)x_gap + space_per_jelly * i + space_per_jelly / 2.0f - wrapper.getSize().x / 2.0f, GetScreenHeight() / 2.0f});
textures.push_back(wrapper);
}
this->background = Background(EBackground::VICTORY);
InputService::getInstance().setKeysToWatch({KEY_ENTER, KEY_A, KEY_D}, {});
}
void VictoryScreen::logic()
{
if (InputService::getInstance().isKeyPressed(KEY_D) || InputService::getInstance().isKeyPressed(KEY_A))
{
buttons[hoveredButton].setColor(WHITE);
hoveredButton = ((hoveredButton - (InputService::getInstance().isKeyPressed(KEY_D) ? -1 : 1)) + buttons.size()) % buttons.size();
buttons[hoveredButton].setColor(RED);
}
if (InputService::getInstance().isKeyPressed(KEY_ENTER))
{
std::string selectedButton = buttons[hoveredButton].getText();
if (selectedButton == "Play Again")
{
StateService::getInstance().setScreen(EScreen::GAME);
}
else if (selectedButton == "Return to Main Menu")
{
StateService::getInstance().setScreen(EScreen::MAIN);
}
}
}
void VictoryScreen::draw()
{
BeginDrawing();
this->background.draw();
for (int t = 0; t < text.size(); t++)
{
text[t].draw();
}
for (int t = 0; t < buttons.size(); t++)
{
buttons[t].draw();
}
for (int t = 0; t < textures.size(); t++)
{
DrawTexture(textures[t].getTexture(), textures[t].getPosition().x, textures[t].getPosition().y, WHITE);
}
EndDrawing();
}
+4
View File
@@ -28,6 +28,9 @@ void AssetService::setAssets()
sounds[ESound::HEAL_PICKUP] = loadSound("Audio/Sounds/healmag.wav"); sounds[ESound::HEAL_PICKUP] = loadSound("Audio/Sounds/healmag.wav");
sounds[ESound::AMMO_PICKUP] = loadSound("Audio/Sounds/shotgunReload.wav"); sounds[ESound::AMMO_PICKUP] = loadSound("Audio/Sounds/shotgunReload.wav");
sounds[ESound::POWERUP] = loadSound("Audio/Sounds/powerUpSound.wav"); sounds[ESound::POWERUP] = loadSound("Audio/Sounds/powerUpSound.wav");
sounds[ESound::VICTORY] = loadSound("Audio/Sounds/victorySound.wav");
sounds[ESound::PLAYER_DAMAGE] = loadSound("Audio/Sounds/WaterBalloon.wav");
sounds[ESound::ENEMY_DEFEATED] = loadSound("Audio/Sounds/pain.wav");
backgrounds[EBackground::TUTORIAL] = loadTexture("Textures/TutorialBackground2.png"); backgrounds[EBackground::TUTORIAL] = loadTexture("Textures/TutorialBackground2.png");
backgrounds[EBackground::GAME1] = loadTexture("Textures/GameBackground_1.png"); backgrounds[EBackground::GAME1] = loadTexture("Textures/GameBackground_1.png");
@@ -53,6 +56,7 @@ void AssetService::setAssets()
sprites[ESprite::HUD_HEART_EMPTY] = loadTexture("Textures/heart_empty.png"); sprites[ESprite::HUD_HEART_EMPTY] = loadTexture("Textures/heart_empty.png");
sprites[ESprite::HUD_AMMO] = loadTexture("Textures/bullet_hud.png"); sprites[ESprite::HUD_AMMO] = loadTexture("Textures/bullet_hud.png");
sprites[ESprite::CROSSHAIR] = loadTexture("Textures/crosshair_3.png"); sprites[ESprite::CROSSHAIR] = loadTexture("Textures/crosshair_3.png");
sprites[ESprite::FLAG] = loadTexture("Textures/flag.png");
} }
Font AssetService::getFont(EFont font, int fontSize) Font AssetService::getFont(EFont font, int fontSize)
+4 -4
View File
@@ -6,7 +6,7 @@
#include "screens/MainScreen.h" #include "screens/MainScreen.h"
#include "screens/TutorialScreen.h" #include "screens/TutorialScreen.h"
#include "screens/GameScreen.h" #include "screens/GameScreen.h"
#include "screens/GameOverScreen.h" #include "screens/VictoryScreen.h"
#include <optional> #include <optional>
void StateService::setScreen(EScreen state) void StateService::setScreen(EScreen state)
@@ -25,9 +25,9 @@ void StateService::setScreen(EScreen state)
case EScreen::GAME: case EScreen::GAME:
currentScreen = std::make_unique<GameScreen>(); currentScreen = std::make_unique<GameScreen>();
break; break;
// case EScreen::GAMEOVER: case EScreen::VICTORY:
// currentScreen = std::make_unique<GameOverScreen>(); currentScreen = std::make_unique<VictoryScreen>();
// break; break;
case EScreen::CLOSE: case EScreen::CLOSE:
gameRunning = false; gameRunning = false;
break; break;