[Added] Start of enemies
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "services/AssetService.h"
|
||||
#include "entities/TextureWrapper.h"
|
||||
#include "entities/PBullet.h"
|
||||
|
||||
class Crate {
|
||||
public:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
+10
-5
@@ -9,6 +9,7 @@
|
||||
#include "services/InputService.h"
|
||||
#include "services/GameService.h"
|
||||
#include "services/CollectableService.h"
|
||||
#include "services/EnemyService.h"
|
||||
#include "entities/Player.h"
|
||||
#include "entities/Text.h"
|
||||
#include "entities/Bullet.h"
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
initHud();
|
||||
initPauseScreen();
|
||||
initGameOverScreen();
|
||||
EnemyService::getInstance().initEnemies();
|
||||
|
||||
InputService::getInstance().setKeysToWatch({KEY_A, KEY_W, KEY_S, KEY_D, KEY_ENTER}, {MOUSE_BUTTON_LEFT});
|
||||
AudioService::getInstance().setMusic(EMusic::GAME);
|
||||
@@ -89,6 +91,8 @@ public:
|
||||
GameService::getInstance().bulletLogic();
|
||||
CollectableService::getInstance().collectableLogic();
|
||||
|
||||
EnemyService::getInstance().enemyLogic();
|
||||
|
||||
this->player.logic();
|
||||
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)
|
||||
@@ -112,6 +116,7 @@ public:
|
||||
GameService::getInstance().drawBullets();
|
||||
this->map.draw();
|
||||
CollectableService::getInstance().drawCollectables();
|
||||
EnemyService::getInstance().drawEnemies();
|
||||
this->player.draw();
|
||||
|
||||
EndMode2D();
|
||||
@@ -130,11 +135,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// Camera2D camera;
|
||||
Background background;
|
||||
Map map;
|
||||
Player player;
|
||||
TextureWrapper crosshair;
|
||||
std::vector<Enemy> enemies;
|
||||
|
||||
std::vector<Text> pauseScreenButtons;
|
||||
int hoveredPauseScreenButton = 0;
|
||||
@@ -143,13 +148,13 @@ private:
|
||||
std::vector<Text> gameOverScreenButtons;
|
||||
int hoveredGameOverScreenButton = 0;
|
||||
|
||||
// Font hudJellyFont;
|
||||
Text hudJellyText;
|
||||
TextureWrapper hudJellyTexture;
|
||||
|
||||
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});
|
||||
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});
|
||||
}
|
||||
|
||||
void initPauseScreen()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "services/CollectableService.h"
|
||||
#include "services/AssetService.h"
|
||||
#include "services/EnemyService.h"
|
||||
#include "entities/Bullet.h"
|
||||
#include <iostream>
|
||||
|
||||
@@ -29,6 +30,22 @@ private:
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ private:
|
||||
for (auto &ammoPack : CollectableService::getInstance().getAmmoPacks())
|
||||
{
|
||||
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 < ammoPack.getObject().getPosition().y + ammoPack.getObject().getSize().y)
|
||||
{
|
||||
@@ -316,22 +316,24 @@ private:
|
||||
for (auto &healthPack : CollectableService::getInstance().getHealthPacks())
|
||||
{
|
||||
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 < healthPack.getObject().getPosition().y + healthPack.getObject().getSize().y)
|
||||
{
|
||||
if(health < max_health) {
|
||||
if (health < max_health)
|
||||
{
|
||||
healthPack.setPickedUp(true);
|
||||
AssetService::getInstance().playSound(ESound::HEAL_PICKUP);
|
||||
health = std::max(health+healthPack.getHealAmount(),(int)max_health);
|
||||
health = std::max(health + healthPack.getHealAmount(), (int)max_health);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks for collisions with powerups */
|
||||
for (auto &powerup : CollectableService::getInstance().getPowerups())
|
||||
{
|
||||
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 < powerup.getObject().getPosition().y + powerup.getObject().getSize().y)
|
||||
{
|
||||
@@ -344,6 +346,16 @@ private:
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/** 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()
|
||||
|
||||
@@ -15,7 +15,6 @@ class TextureWrapper {
|
||||
this->sourceRect = sourceRect;
|
||||
}
|
||||
~TextureWrapper() {
|
||||
|
||||
}
|
||||
|
||||
Texture2D getTexture() {
|
||||
|
||||
@@ -16,7 +16,8 @@ enum class ESprite {
|
||||
HUD_HEART,
|
||||
HUD_HEART_EMPTY,
|
||||
HUD_AMMO,
|
||||
CROSSHAIR
|
||||
CROSSHAIR,
|
||||
FLAG,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -6,13 +6,16 @@
|
||||
#include "services/MapService.h"
|
||||
#include "entities/Vector2i.h"
|
||||
#include "entities/Crate.h"
|
||||
#include "entities/PBullet.h"
|
||||
#include "entities/Jelly.h"
|
||||
#include "entities/AmmoPack.h"
|
||||
#include "entities/HealthPack.h"
|
||||
#include "entities/Powerup.h"
|
||||
#include "entities/Flag.h"
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Service that manages the collectables (jellies), consumables (Ammo, health, powerups), and the finish flag
|
||||
*/
|
||||
class CollectableService : public Service<CollectableService>
|
||||
{
|
||||
public:
|
||||
@@ -23,6 +26,7 @@ public:
|
||||
initAmmoPacks();
|
||||
initHealthPacks();
|
||||
initPowerups();
|
||||
initFlag();
|
||||
}
|
||||
|
||||
void collectableLogic()
|
||||
@@ -32,6 +36,7 @@ public:
|
||||
ammoPackLogic();
|
||||
healthPackLogic();
|
||||
powerupLogic();
|
||||
flag.logic();
|
||||
}
|
||||
|
||||
void drawCollectables()
|
||||
@@ -41,6 +46,7 @@ public:
|
||||
drawAmmoPacks();
|
||||
drawHealthpacks();
|
||||
drawPowerups();
|
||||
flag.draw();
|
||||
}
|
||||
|
||||
std::vector<Crate> &getCrates()
|
||||
@@ -62,6 +68,10 @@ public:
|
||||
return this->powerUps;
|
||||
}
|
||||
|
||||
Flag& getFlag() {
|
||||
return this->flag;
|
||||
}
|
||||
|
||||
int getMaxAmountOfJellies()
|
||||
{
|
||||
return this->amountOfCrates;
|
||||
@@ -82,6 +92,7 @@ private:
|
||||
std::vector<HealthPack> healthPacks;
|
||||
std::vector<Jelly> jellies;
|
||||
std::vector<Powerup> powerUps;
|
||||
Flag flag;
|
||||
|
||||
void initCrates()
|
||||
{
|
||||
@@ -146,6 +157,11 @@ private:
|
||||
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()
|
||||
{
|
||||
for (auto it = crates.begin(); it != crates.end();)
|
||||
|
||||
@@ -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
|
||||
@@ -58,25 +58,6 @@ public:
|
||||
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()
|
||||
{
|
||||
for (auto it = this->playerBullets.begin(); it != this->playerBullets.end();)
|
||||
|
||||
@@ -40,13 +40,6 @@ MainScreen::MainScreen()
|
||||
|
||||
void MainScreen::logic()
|
||||
{
|
||||
// Vector2 mouseD = GetMouseDelta();
|
||||
// std::cout << mouseD.y <<std::endl;
|
||||
// if (mouseD.x != 0.0f && mouseD.y != 0.0f)
|
||||
// {
|
||||
// mouseLogic();
|
||||
// }
|
||||
|
||||
keyboardLogic();
|
||||
|
||||
clickLogic();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -28,6 +28,9 @@ void AssetService::setAssets()
|
||||
sounds[ESound::HEAL_PICKUP] = loadSound("Audio/Sounds/healmag.wav");
|
||||
sounds[ESound::AMMO_PICKUP] = loadSound("Audio/Sounds/shotgunReload.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::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_AMMO] = loadTexture("Textures/bullet_hud.png");
|
||||
sprites[ESprite::CROSSHAIR] = loadTexture("Textures/crosshair_3.png");
|
||||
sprites[ESprite::FLAG] = loadTexture("Textures/flag.png");
|
||||
}
|
||||
|
||||
Font AssetService::getFont(EFont font, int fontSize)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "screens/MainScreen.h"
|
||||
#include "screens/TutorialScreen.h"
|
||||
#include "screens/GameScreen.h"
|
||||
#include "screens/GameOverScreen.h"
|
||||
#include "screens/VictoryScreen.h"
|
||||
#include <optional>
|
||||
|
||||
void StateService::setScreen(EScreen state)
|
||||
@@ -25,9 +25,9 @@ void StateService::setScreen(EScreen state)
|
||||
case EScreen::GAME:
|
||||
currentScreen = std::make_unique<GameScreen>();
|
||||
break;
|
||||
// case EScreen::GAMEOVER:
|
||||
// currentScreen = std::make_unique<GameOverScreen>();
|
||||
// break;
|
||||
case EScreen::VICTORY:
|
||||
currentScreen = std::make_unique<VictoryScreen>();
|
||||
break;
|
||||
case EScreen::CLOSE:
|
||||
gameRunning = false;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user