diff --git a/BEE_PLAYER.h b/BEE_PLAYER.h new file mode 100644 index 0000000..23bc321 --- /dev/null +++ b/BEE_PLAYER.h @@ -0,0 +1,18 @@ +// BEE_PLAYER.h +#ifndef BEE_PLAYER_H +#define BEE_PLAYER_H +#include +#include +#include "RAIN.h" // Include the definition +class RAIN; +class Obstacle; + +class BEE_PLAYER { +public: + virtual ~BEE_PLAYER() {} + virtual void attach(std::shared_ptr RAIN) = 0; + virtual void detach(RAIN* RAIN) =0; + virtual void notify(RAIN* RAIN, bool is_collision) =0; +}; + +#endif // BEE_PLAYER_H \ No newline at end of file diff --git a/GameManager.cpp b/GameManager.cpp new file mode 100644 index 0000000..dc591dd --- /dev/null +++ b/GameManager.cpp @@ -0,0 +1,52 @@ +// GameManager.cpp +#include "GameManager.h" +#include "splashkit.h" + +GameManager::GameManager() { + player = nullptr; +} + +void GameManager::setPlayer(Player* player) { + this->player = player; +} + +void GameManager::addObstacle(std::shared_ptr obstacle_ptr) { + obstacles.push_back(obstacle_ptr); + player->attach(obstacle_ptr); // Use shared_ptr instead of raw pointer +} + +void GameManager::checkCollisions() { + if (player == nullptr) return; + + for (const auto& obstacle_ptr : obstacles) { + Obstacle& obstacle = *obstacle_ptr; + if (player->get_x() < obstacle.get_x() + obstacle.get_width() && + player->get_x() + player->get_width() > obstacle.get_x() && + player->get_y() < obstacle.get_y() + obstacle.get_height() && + player->get_y() + player->get_height() > obstacle.get_y()) + { + // Notify player and obstacle about the collision + if (!obstacle.get_collision()) { // Collision started + player->notify(&obstacle, true); + Player::set_HP(Player::get_HP()-1); // Decrease player health on collision + } + draw_text("Collision detected!", COLOR_BLACK, "Arial", 24, player->get_x() + 10, player->get_y() - 50); + } + else { + if (obstacle.get_collision()) { // Collision ended + player->notify(&obstacle, false); + } + } + } +} + +void GameManager::updateGameObjects() { + for (const auto& obstacle_ptr : obstacles) { + Obstacle& obstacle = *obstacle_ptr; + obstacle.update(); + obstacle.draw(); + } +} + + + diff --git a/GameManager.h b/GameManager.h new file mode 100644 index 0000000..5a163f9 --- /dev/null +++ b/GameManager.h @@ -0,0 +1,24 @@ +// GameManager.h +#ifndef GAMEMANAGER_H +#define GAMEMANAGER_H + +#include "player.h" +#include "obstacle.h" +#include +#include + +class GameManager { +public: + GameManager(); + void addObstacle(std::shared_ptr obstacle_ptr); + void setPlayer(Player* player); + void checkCollisions(); + void updateGameObjects(); + void clear_Obstacles(){obstacles.clear();}; + +private: + Player* player; + std::vector> obstacles; +}; + +#endif // GAMEMANAGER_H diff --git a/Observer.h b/Observer.h deleted file mode 100644 index fe38c29..0000000 --- a/Observer.h +++ /dev/null @@ -1,12 +0,0 @@ -// observer.h -#ifndef OBSERVER_H -#define OBSERVER_H - -class Observer { -public: - virtual ~Observer() {} - virtual void CollisionUpdate(bool is_collision)=0; - virtual void deceaseSpeed(int newSpeed)=0; -}; - -#endif // OBSERVER_H \ No newline at end of file diff --git a/RAIN.h b/RAIN.h new file mode 100644 index 0000000..c6d7043 --- /dev/null +++ b/RAIN.h @@ -0,0 +1,12 @@ +// RAIN.h +#ifndef RAIN_H +#define RAIN_H + +class RAIN { +public: + virtual ~RAIN() {} + virtual void CollisionUpdate(bool is_collision)=0; + virtual void deceaseSpeed(int newSpeed)=0; +}; + +#endif // RAIN_H \ No newline at end of file diff --git a/Subject.h b/Subject.h deleted file mode 100644 index c7961d7..0000000 --- a/Subject.h +++ /dev/null @@ -1,16 +0,0 @@ -// Subject.h -#ifndef SUBJECT_H -#define SUBJECT_H -#include -class Observer; -class Obstacle; - -class Subject { -public: - virtual ~Subject() {} - virtual void attach(Observer* observer) =0; - virtual void detach(Observer* observer) =0; - virtual void notify(Observer* observer, bool is_collision) =0; -}; - -#endif // SUBJECT_H \ No newline at end of file diff --git a/game.exe b/game.exe index 0dee3e1..738a776 100644 Binary files a/game.exe and b/game.exe differ diff --git a/obstacle.cpp b/obstacle.cpp index 15b38a5..02aa8fa 100644 --- a/obstacle.cpp +++ b/obstacle.cpp @@ -33,7 +33,7 @@ void Obstacle::CollisionUpdate(bool is_collision) { void Obstacle::deceaseSpeed(int newSpeed){ this->speed = newSpeed; - std::cout << "The Speed equal to 2 now" << std::endl; + //std::cout << "The Speed equal to 2 now" << std::endl; } diff --git a/obstacle.h b/obstacle.h index 6d851fc..c2ed5c1 100644 --- a/obstacle.h +++ b/obstacle.h @@ -2,9 +2,9 @@ #ifndef OBSTACLE_H #define OBSTACLE_H -#include"Observer.h" +#include "RAIN.h" #include "player.h" -class Obstacle : public Observer { +class Obstacle : public RAIN { public: Obstacle(float x, float y,int speed); float get_x() { return x; } diff --git a/player.cpp b/player.cpp index 0838c8b..5296b83 100644 --- a/player.cpp +++ b/player.cpp @@ -27,30 +27,31 @@ void Player::move_left() { } -void Player::attach(Observer* observer) { - observers.push_back(observer); +void Player::attach(std::shared_ptr RAIN) { + RAINs.push_back(RAIN); } -void Player::detach(Observer* observer) { - auto it = std::remove(observers.begin(), observers.end(), observer); - if (it != observers.end()) { - std::cout << "Detaching observer" << std::endl; - observers.erase(it, observers.end()); - } +void Player::detach(RAIN* Rain) { + auto it = std::remove_if(RAINs.begin(), RAINs.end(), + [&Rain](const std::shared_ptr& o) { + return o.get() == Rain; // Compare the raw pointer + }); + RAINs.erase(it, RAINs.end()); } -void Player::notify(Observer* observer, bool is_collision) { - observer->CollisionUpdate(is_collision); // Call onCollision on the observer, passing this obstacle +void Player::notify(RAIN* RAIN, bool is_collision) { + RAIN->CollisionUpdate(is_collision); // Call onCollision on the RAIN, passing this obstacle } -void Player::notify_all_observers() { - std::cout << "Notifying all observers..." << std::endl; - for (Observer* observer : observers) { - if (observer == nullptr) { - std::cout << "Observer is null!" << std::endl; - continue; // Skip null observers +void Player::notify_all_RAINs() { + //std::cout << "Notifying all RAINs..." << std::endl; + for (auto& RAIN : RAINs) { + if (!RAIN) { + std::cout << "RAIN is null!" << std::endl; + continue; // Skip null RAINs } - observer->deceaseSpeed(1); + RAIN->deceaseSpeed(1); } } + diff --git a/player.h b/player.h index bd65d44..758b682 100644 --- a/player.h +++ b/player.h @@ -2,12 +2,12 @@ #ifndef PLAYER_H #define PLAYER_H -#include "Subject.h" +#include "BEE_PLAYER.h" #include "obstacle.h" #include -#include "Observer.h" +#include "RAIN.h" #include -class Player : public Subject { +class Player : public BEE_PLAYER { public: Player(float x, float y, float speed); @@ -20,14 +20,15 @@ class Player : public Subject { float get_speed() { return speed; } static int get_HP(){return HP;} static void set_HP(int hp){HP = hp;} - void attach(Observer* observer) override; - void detach(class Observer* observer) ; - void notify(class Observer* observer, bool is_collision); - void notify_all_observers(); + void attach(std::shared_ptr RAIN) override; + void detach(class RAIN* Rain) ; + void notify(class RAIN* RAIN, bool is_collision); + void notify_all_RAINs(); private: float x, y, speed, width, height; static int HP; - std::vector observers; + std::vector> RAINs; + }; #endif // PLAYER_H \ No newline at end of file diff --git a/program.cpp b/program.cpp index 9c36c87..1139c16 100644 --- a/program.cpp +++ b/program.cpp @@ -5,11 +5,12 @@ #include #include "player.h" #include "obstacle.h" -#include "Observer.h" -#include "Subject.h" +#include "RAIN.h" +#include "BEE_PLAYER.h" #include #include -//skm g++ program.cpp player.cpp obstacle.cpp -o game.exe +#include "GameManager.h" +//skm g++ program.cpp player.cpp obstacle.cpp GameManager.cpp -o game.exe bitmap background = bitmap_named("images/Background.jpg"); bitmap bee = bitmap_named("images/Bee.png"); @@ -35,9 +36,9 @@ void update_timer(); void display_timer(); void display_start_screen(); void player_move(Player* player); -void Spawn_obstacle(std::vector>& obstacles, Player* player, int& spawn_timer); -void render(std::vector>& obstacles, Player& player); -void check_game_over(std::vector>& obstacles,Player& player); +void Spawn_obstacle(GameManager& gameManager, int& spawn_timer); +void render(GameManager& gameManager, Player& player); +void check_game_over(GameManager& gameManager,Player& player); void display_game_over_screen(); void start_game() { @@ -64,14 +65,14 @@ void display_start_screen() { draw_text("Press SPACE to Start", COLOR_BLACK, "Arial", 200, 550, 200); } -void check_game_over(std::vector>& obstacles,Player& player) { +void check_game_over(GameManager& gameManager,Player& player) { if (Player::get_HP() == 1) { - player.notify_all_observers(); + player.notify_all_RAINs(); } else if (Player::get_HP() <= 0) { game_over = true; game_started = false; // Stop the game - obstacles.clear(); + gameManager.clear_Obstacles(); } } @@ -80,38 +81,6 @@ void display_game_over_screen() { draw_text("Press SPACE to Restart", COLOR_WHITE, "Arial", 32, 510, 500); } -template -bool is_colliding(T& obj1, U& obj2) { - float x1 = obj1.get_x(); - float y1 = obj1.get_y(); - float w1 = obj1.get_width(); - float h1 = obj1.get_height(); - - float x2 = obj2.get_x(); - float y2 = obj2.get_y(); - float w2 = obj2.get_width(); - float h2 = obj2.get_height(); - - // Check for collision - return (x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2); -} - -// Function to handle collision between two objects -template -void handle_collision(T& subject, U& observer) { - if (is_colliding(subject, observer)) { - if (!observer.get_collision()) { // Collision started - subject.notify(&observer, true); - Player::set_HP(Player::get_HP()-1); // Decrease player health on collision - } - draw_text("Collision detected!", COLOR_BLACK, "Arial", 24, subject.get_x() + 10, subject.get_y() - 50); - } else { - if (observer.get_collision()) { // Collision ended - subject.notify(&observer, false); - } - } -} - void player_move(Player* player) { if (key_down(RIGHT_KEY) && player->get_x() <= RIGHT_BOUNDARY) { player->move_right(); @@ -121,19 +90,19 @@ void player_move(Player* player) { } } -void Spawn_obstacle(std::vector>& obstacles, Player* player, int& spawn_timer) { +void Spawn_obstacle(GameManager& gameManager, int& spawn_timer) { spawn_timer++; if (spawn_timer >= spawn_interval) { spawn_timer = 0; int spawn_x = rand() % RIGHT_BOUNDARY; // Random x-coordinate between 0 and RIGHT_BOUNDARY - auto newObstacle = std::make_unique(spawn_x, 0, 2); - player->attach(newObstacle.get()); // Attach the newly created obstacle - obstacles.push_back(std::move(newObstacle)); // Move the smart pointer into the vector + std::shared_ptr obstacle = std::make_shared(spawn_x, 0, 2); + gameManager.addObstacle(obstacle); + } } -void render(std::vector>& obstacles, Player& player) { +void render(GameManager& gameManager,Player& player) { // Redrawing the bitmap after every clear background and bee double center_x = player.get_x()+(player.get_width()/2); double center_y = player.get_y()+(player.get_height()/2); @@ -149,14 +118,7 @@ void render(std::vector>& obstacles, Player& player) { // Draw the circle for debugging draw_circle(COLOR_RED,scaled_bee_circle); - // Update and draw obstacles - for (const auto& obstacle_ptr : obstacles) { - // Dereference the unique_ptr to access the Obstacle object - Obstacle& obstacle = *obstacle_ptr; - obstacle.update(); - obstacle.draw(); - handle_collision(player, obstacle); - } + gameManager.updateGameObjects(); } @@ -164,8 +126,10 @@ int main() { open_window("BeeFall", WINDOW_WIDTH, WINDOW_HEIGHT); // Named window beefall and window size hide_mouse(); // Hide mouse while cursor is over the game window Player player(player_posx, player_posy, 10.0f); // Initialize player - std::vector> obstacles; // List of obstacles - + // Create game manager and add game objects + GameManager gameManager; + gameManager.setPlayer(&player); + // Timer for obstacle spawning int spawn_timer = 0; @@ -203,15 +167,19 @@ int main() { player_move(&player); // Spawn obstacles - Spawn_obstacle(obstacles, &player, spawn_timer); + Spawn_obstacle(gameManager, spawn_timer); + + // Render game objects - render(obstacles, player); + render(gameManager,player); + gameManager.checkCollisions(); // Update game elements + update_timer(); display_timer(); - check_game_over(obstacles,player); + check_game_over(gameManager,player); refresh_screen(60); }