diff --git a/Space-Invaders/Header/Bullet/BulletConfig.h b/Space-Invaders/Header/Bullet/BulletConfig.h new file mode 100644 index 000000000..3d40244af --- /dev/null +++ b/Space-Invaders/Header/Bullet/BulletConfig.h @@ -0,0 +1,16 @@ +#pragma once +namespace Bullet +{ + enum class BulletType + { + LASER_BULLET, + TORPEDO, + FROST_BULLET, + }; + + enum class MovementDirection + { + UP, //player needs to shoot in upward direction + DOWN, // enemies always shoot in downward direction + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/BulletController.h b/Space-Invaders/Header/Bullet/BulletController.h new file mode 100644 index 000000000..d8c97559b --- /dev/null +++ b/Space-Invaders/Header/Bullet/BulletController.h @@ -0,0 +1,35 @@ +#pragma once +#include "../../Header/Projectile/IProjectile.h" +#include "../../Header/Bullet/BulletConfig.h" + +namespace Bullet +{ + class BulletView; + class BulletModel; + enum class BulletType; + + class BulletController : public Projectile::IProjectile + { + protected: + + BulletView* bullet_view; + BulletModel* bullet_model; + + void updateProjectilePosition() override; + + void moveUp(); + void moveDown(); + void handleOutOfBounds(); + + public: + + BulletController(BulletType type); + virtual ~BulletController() override; + void initialize(sf::Vector2f position, Bullet::MovementDirection direction) override; + void update() override; + void render() override; + + sf::Vector2f getProjectilePosition() override; + BulletType getBulletType(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/BulletModel.h b/Space-Invaders/Header/Bullet/BulletModel.h new file mode 100644 index 000000000..a6d9a45e2 --- /dev/null +++ b/Space-Invaders/Header/Bullet/BulletModel.h @@ -0,0 +1,37 @@ +#pragma once +#include + +namespace Bullet +{ + enum class BulletType; + enum class MovementDirection; + + class BulletModel + { + private: + float movement_speed = 300.f; + sf::Vector2f bullet_position; + + BulletType bullet_type; + MovementDirection movement_direction; + + public: + + BulletModel(BulletType type); + ~BulletModel(); + + void initialize(sf::Vector2f position, MovementDirection direction); + + sf::Vector2f getBulletPosition(); + void setBulletPosition(sf::Vector2f position); + + BulletType getBulletType(); + void setBulletType(BulletType type); + + MovementDirection getMovementDirection(); + void setMovementDirection(MovementDirection direction); + + float getMovementSpeed(); + void setMovementSpeed(float speed); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/BulletService.h b/Space-Invaders/Header/Bullet/BulletService.h new file mode 100644 index 000000000..cc8939bb6 --- /dev/null +++ b/Space-Invaders/Header/Bullet/BulletService.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include "SFML/System/Vector2.hpp" +#include "../../Header/Projectile/IProjectile.h" + +namespace Bullet +{ + class BulletController; + enum class BulletType; + enum class MovementDirection; + + class BulletService + { + private: + + std::vector bullet_list; + + BulletController* createBullet(BulletType bullet_type); + void destroy(); + + public: + BulletService(); + virtual ~BulletService(); + + void initialize(); + void update(); + void render(); + + BulletController* spawnBullet(BulletType bullet_type, sf::Vector2f position, MovementDirection direction); + void destroyBullet(BulletController* bullet_controller); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/BulletView.h b/Space-Invaders/Header/Bullet/BulletView.h new file mode 100644 index 000000000..bbe639119 --- /dev/null +++ b/Space-Invaders/Header/Bullet/BulletView.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "../../Header/Bullet/BulletController.h" + +namespace Bullet +{ + class BulletController; + enum class BulletType; + + class BulletView + { + private: + const float bullet_sprite_width = 18.f; + const float bullet_sprite_height = 18.f; + + sf::RenderWindow* game_window; + sf::Texture bullet_texture; + sf::Sprite bullet_sprite; + + BulletController* bullet_controller; + + void initializeImage(BulletType type); + void scaleImage(); + + public: + BulletView(); + ~BulletView(); + + void initialize(BulletController* controller); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/Controllers/FrostBulletController.h b/Space-Invaders/Header/Bullet/Controllers/FrostBulletController.h new file mode 100644 index 000000000..3188333d9 --- /dev/null +++ b/Space-Invaders/Header/Bullet/Controllers/FrostBulletController.h @@ -0,0 +1,20 @@ +#pragma once +#include "../../Header/Bullet/BulletController.h" + +namespace Bullet +{ + namespace Controller + { + class FrostBulletController : public BulletController + { + private: + const float torpedo_movement_speed = 500.f; + + public: + FrostBulletController(BulletType type); + ~FrostBulletController(); + + void initialize(sf::Vector2f position, MovementDirection direction) override; + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/Controllers/LaserBulletController.h b/Space-Invaders/Header/Bullet/Controllers/LaserBulletController.h new file mode 100644 index 000000000..67a48b89f --- /dev/null +++ b/Space-Invaders/Header/Bullet/Controllers/LaserBulletController.h @@ -0,0 +1,17 @@ +#pragma once +#include "../../Header/Bullet/BulletController.h" + +namespace Bullet +{ + namespace Controller + { + class LaserBulletController : public BulletController + { + public: + LaserBulletController(BulletType type); + ~LaserBulletController(); + + void initialize(sf::Vector2f position, MovementDirection direction) override; + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Bullet/Controllers/TorpedoController.h b/Space-Invaders/Header/Bullet/Controllers/TorpedoController.h new file mode 100644 index 000000000..99ac2d88a --- /dev/null +++ b/Space-Invaders/Header/Bullet/Controllers/TorpedoController.h @@ -0,0 +1,20 @@ +#pragma once +#include "../../Header/Bullet/BulletController.h" + +namespace Bullet +{ + namespace Controller + { + class TorpedoController : public BulletController + { + private: + const float torpedo_movement_speed = 200.f; + + public: + TorpedoController(BulletType type); + ~TorpedoController(); + + void initialize(sf::Vector2f position, MovementDirection direction) override; + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Collectible/ICollectible.h b/Space-Invaders/Header/Collectible/ICollectible.h new file mode 100644 index 000000000..d1405aa13 --- /dev/null +++ b/Space-Invaders/Header/Collectible/ICollectible.h @@ -0,0 +1,17 @@ +#pragma once +#include + +namespace Collectible +{ + class ICollectible + { + public: + virtual void onCollected() = 0; + virtual void initialize(sf::Vector2f position) = 0; + virtual void update() = 0; + virtual void render() = 0; + virtual sf::Vector2f getCollectiblePosition() = 0; + + virtual ~ICollectible() {}; + }; +} diff --git a/Space-Invaders/Header/Element/Bunker/BunkerController.h b/Space-Invaders/Header/Element/Bunker/BunkerController.h new file mode 100644 index 000000000..3370da4b2 --- /dev/null +++ b/Space-Invaders/Header/Element/Bunker/BunkerController.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "../../header/Element/Bunker/BunkerModel.h" + +namespace Element +{ + namespace Bunker + { + class BunkerView; + + class BunkerController + { + private: + BunkerView* bunker_view; + BunkerData bunker_data; + + public: + BunkerController(); + ~BunkerController(); + + void initialize(BunkerData data); + void update(); + void render(); + + sf::Vector2f getBunkerPosition(); + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Element/Bunker/BunkerModel.h b/Space-Invaders/Header/Element/Bunker/BunkerModel.h new file mode 100644 index 000000000..7ae912814 --- /dev/null +++ b/Space-Invaders/Header/Element/Bunker/BunkerModel.h @@ -0,0 +1,15 @@ +#pragma once +#include + +namespace Element +{ + namespace Bunker + { + struct BunkerData + { + sf::Vector2f position; + BunkerData(); + BunkerData(sf::Vector2f position); + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Element/Bunker/BunkerView.h b/Space-Invaders/Header/Element/Bunker/BunkerView.h new file mode 100644 index 000000000..acc163094 --- /dev/null +++ b/Space-Invaders/Header/Element/Bunker/BunkerView.h @@ -0,0 +1,36 @@ +#pragma once +#include + +namespace Element +{ + namespace Bunker + { + class BunkerController; + + class BunkerView + { + private: + const float bunker_sprite_width = 80.f; + const float bunker_sprite_height = 80.f; + + BunkerController* bunker_controller; + sf::RenderWindow* game_window; + + sf::Texture bunker_texture; + sf::Sprite bunker_sprite; + + //const sf::String bunker_texture_path = "assets/textures/bunker.png"; + + void scaleSprite(); + void initializeImage(); + + public: + BunkerView(); + ~BunkerView(); + + void initialize(BunkerController* controller); + void update(); + void render(); + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Element/ElementService.h b/Space-Invaders/Header/Element/ElementService.h new file mode 100644 index 000000000..e9c4c8719 --- /dev/null +++ b/Space-Invaders/Header/Element/ElementService.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include "../../header/Element/Bunker/BunkerController.h" +#include "../../header/Element/Bunker/BunkerModel.h" + +namespace Element +{ + class BunkerController; + + class ElementService + { + private: + //const vector so that the default values will not be changed down the road by mistake. + const std::vector bunker_data_list = { Bunker::BunkerData(sf::Vector2f(130.f, 800.f)), + Bunker::BunkerData(sf::Vector2f(430.0f, 800.f)), + Bunker::BunkerData(sf::Vector2f(730.0f, 800.f)), + Bunker::BunkerData(sf::Vector2f(1130.0f, 800.f)), + Bunker::BunkerData(sf::Vector2f(1430.0f, 800.f)), + Bunker::BunkerData(sf::Vector2f(1730.0f, 800.f)) }; + + std::vector bunker_list; + + void destroy(); + + public: + ElementService(); + virtual ~ElementService(); + + void initialize(); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/Controllers/SubZeroController.h b/Space-Invaders/Header/Enemy/Controllers/SubZeroController.h new file mode 100644 index 000000000..d27ae5a7f --- /dev/null +++ b/Space-Invaders/Header/Enemy/Controllers/SubZeroController.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../header/Enemy/EnemyController.h" + +namespace Enemy +{ + namespace Controller + { + class SubzeroController : public EnemyController + { + private: + + float vertical_movement_speed = 100.f; + const float subzero_rate_of_fire = 2.f; + + void move() override; + void moveDown(); + + void fireBullet() override; + + public: + + SubzeroController(EnemyType type); + ~SubzeroController(); + + void initialize() override; + + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/Controllers/ZapperController.h b/Space-Invaders/Header/Enemy/Controllers/ZapperController.h new file mode 100644 index 000000000..fc5a3b414 --- /dev/null +++ b/Space-Invaders/Header/Enemy/Controllers/ZapperController.h @@ -0,0 +1,31 @@ +#pragma once + +#include "../../header/Enemy/EnemyController.h" + +namespace Enemy +{ + namespace Controller + { + class ZapperController : public EnemyController + { + private: + + float vertical_travel_distance = 100.f; + + void move() override; + void moveLeft(); + void moveRight(); + void moveDown(); + + void fireBullet() override; + + public: + + ZapperController(EnemyType type); + ~ZapperController(); + + void initialize() override; + + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/EnemyConfig.h b/Space-Invaders/Header/Enemy/EnemyConfig.h new file mode 100644 index 000000000..0c54f1ba5 --- /dev/null +++ b/Space-Invaders/Header/Enemy/EnemyConfig.h @@ -0,0 +1,26 @@ +#pragma once + +namespace Enemy +{ + enum class EnemyType + { + ZAPPER, + SUBZERO, + //UFO, + //THUNDER_SNAKE, + }; + + enum class EnemyState + { + PATROLLING, + ATTACK, + DEAD, + }; + + enum class MovementDirection + { + LEFT, + RIGHT, + DOWN, + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/EnemyController.h b/Space-Invaders/Header/Enemy/EnemyController.h new file mode 100644 index 000000000..7b2a2a3c0 --- /dev/null +++ b/Space-Invaders/Header/Enemy/EnemyController.h @@ -0,0 +1,47 @@ +#pragma once +#include + +namespace Enemy +{ + class EnemyView; + class EnemyModel; + + enum class EnemyType; + enum class EnemyState; + + class EnemyController + { + + protected: + + float vertical_movement_speed = 30.f; + float horizontal_movement_speed = 200.0f; + + float rate_of_fire = 3.f; //we want to fire the bullet every 3 seconds + float elapsed_fire_duration = 0.f; //variable to check how long it has been since we last fired + + EnemyView* enemy_view; + EnemyModel* enemy_model; + + void updateFireTimer(); + void processBulletFire(); + virtual void fireBullet() = 0; + + virtual void move() = 0; + + sf::Vector2f getRandomInitialPosition(); + void handleOutOfBounds(); + + public: + EnemyController(EnemyType type); + virtual ~EnemyController(); + + virtual void initialize(); + void update(); + void render(); + + sf::Vector2f getEnemyPosition(); + EnemyState getEnemyState(); + EnemyType getEnemyType(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/EnemyModel.h b/Space-Invaders/Header/Enemy/EnemyModel.h new file mode 100644 index 000000000..57a4cdb4f --- /dev/null +++ b/Space-Invaders/Header/Enemy/EnemyModel.h @@ -0,0 +1,46 @@ +#pragma once +#include + +namespace Enemy +{ + enum class EnemyType; + enum class MovementDirection; + enum class EnemyState; + + class EnemyModel + { + private: + sf::Vector2f reference_position = sf::Vector2f(50.f, 50.f); + sf::Vector2f enemy_position; + + MovementDirection movement_direction; + EnemyType enemy_type; + EnemyState enemy_state; + + public: + EnemyModel(EnemyType type); + ~EnemyModel(); + + //const settings for enemy + const sf::Vector2f left_most_position = sf::Vector2f(50.f, 50.f); + const sf::Vector2f right_most_position = sf::Vector2f(1800.f, 50.f); + const sf::Vector2f barrel_position_offset = sf::Vector2f(20.f, 50.f); + + const float vertical_travel_distance = 100.f; + const float enemy_movement_speed = 250.0f; + + void initialize(); + + // Getters and Setters + sf::Vector2f getEnemyPosition(); + void setEnemyPosition(sf::Vector2f position); + sf::Vector2f getReferencePosition(); + void setReferencePosition(sf::Vector2f position); + EnemyState getEnemyState(); + void setEnemyState(EnemyState state); + EnemyType getEnemyType(); + void setEnemyType(EnemyType type); + MovementDirection getMovementDirection(); + void setMovementDirection(MovementDirection direction); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/EnemyService.h b/Space-Invaders/Header/Enemy/EnemyService.h new file mode 100644 index 000000000..8f9dd776f --- /dev/null +++ b/Space-Invaders/Header/Enemy/EnemyService.h @@ -0,0 +1,35 @@ +#pragma once +#include + +namespace Enemy +{ + class EnemyController; + enum class EnemyType; + + class EnemyService + { + private: + + const float spawn_interval = 2.f; + + std::vector enemy_list; + float spawn_timer; + + void updateSpawnTimer(); + void processEnemySpawn(); + EnemyType getRandomEnemyType(); + EnemyController* createEnemy(EnemyType enemy_type); + void destroy(); + + public: + EnemyService(); + ~EnemyService(); + + void initialize(); + void update(); + void render(); + + EnemyController* spawnEnemy(); // Function to spawn enemy + void destroyEnemy(EnemyController* enemy_controller); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Enemy/EnemyView.h b/Space-Invaders/Header/Enemy/EnemyView.h new file mode 100644 index 000000000..b89b046a7 --- /dev/null +++ b/Space-Invaders/Header/Enemy/EnemyView.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include "../../Header/Enemy/EnemyConfig.h" + +namespace Enemy +{ + class EnemyController; + + class EnemyView + { + private: + //const sf::String subzero_texture_path = "assets/textures/subzero.png"; + //const sf::String zapper_texture_path = "assets/textures/zapper.png"; + + const float enemy_sprite_width = 60.f; + const float enemy_sprite_height = 60.f; + + EnemyController* enemy_controller; + + sf::RenderWindow* game_window; + sf::Texture enemy_texture; + sf::Sprite enemy_sprite; + + void initializeEnemySprite(EnemyType type); + void scaleEnemySprite(); + + public: + EnemyView(); + ~EnemyView(); + + void initialize(EnemyController* controller); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Event/EventService.h b/Space-Invaders/Header/Event/EventService.h new file mode 100644 index 000000000..ebecfd5d6 --- /dev/null +++ b/Space-Invaders/Header/Event/EventService.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +namespace Event +{ + enum class ButtonState + { + PRESSED, + HELD, + RELEASED, + }; + + class EventService + { + private: + sf::Event game_event; //event var + sf::RenderWindow* game_window; //ptr to our game window + + bool isGameWindowOpen(); + bool gameWindowWasClosed(); //for the condition we already had - the title bar cross. + bool hasQuitGame(); //for our new 'ESC' condition + + //Button States + ButtonState left_mouse_button_state; + ButtonState right_mouse_button_state; + ButtonState left_arrow_button_state; + ButtonState right_arrow_button_state; + ButtonState A_button_state; + ButtonState D_button_state; + + //Button and mouse state functions + void updateMouseButtonsState(ButtonState& current_button_state, sf::Mouse::Button mouse_button); + void updateKeyboardButtonsState(ButtonState& current_button_state, sf::Keyboard::Key keyboard_button); + + + public: + EventService(); + ~EventService(); + + void initialize(); + void update(); + void processEvents(); // while window is open we will check for events + bool pressedEscapeKey(); + bool isKeyboardEvent(); + bool pressedLeftKey(); // getting inputs for the player + bool pressedRightKey(); + bool pressedLeftMouseButton(); // Mouse inputs for the player + bool pressedRightMouseButton(); + bool pressedAKey(); // AD held check + bool pressedDKey(); + + }; +} + diff --git a/Space-Invaders/Header/Gameplay/GameplayController.h b/Space-Invaders/Header/Gameplay/GameplayController.h new file mode 100644 index 000000000..76b6fcf24 --- /dev/null +++ b/Space-Invaders/Header/Gameplay/GameplayController.h @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace Gameplay +{ + class GameplayView; + + class GameplayController + { + private: + GameplayView* gameplay_view; + + public: + GameplayController(); + ~GameplayController(); + + void initialize(); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Gameplay/GameplayService.h b/Space-Invaders/Header/Gameplay/GameplayService.h new file mode 100644 index 000000000..53efd34a5 --- /dev/null +++ b/Space-Invaders/Header/Gameplay/GameplayService.h @@ -0,0 +1,19 @@ +#pragma once +namespace Gameplay +{ + class GameplayController; + + class GameplayService + { + private: + GameplayController* gameplay_controller; + + public: + GameplayService(); + ~GameplayService(); + + void initialize(); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Gameplay/GameplayView.h b/Space-Invaders/Header/Gameplay/GameplayView.h new file mode 100644 index 000000000..e6675b5db --- /dev/null +++ b/Space-Invaders/Header/Gameplay/GameplayView.h @@ -0,0 +1,26 @@ +#pragma once +#include + +namespace Gameplay +{ + class GameplayView + { + private: + //const sf::String background_texture_path = "assets/textures/space_invaders_bg.png"; + + sf::RenderWindow* game_window; + sf::Texture background_texture; + sf::Sprite background_sprite; + + void initializeBackgroundSprite(); + void scaleBackgroundSprite(); + + public: + GameplayView(); + ~GameplayView(); + + void initialize(); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Global/Config.h b/Space-Invaders/Header/Global/Config.h new file mode 100644 index 000000000..385d119df --- /dev/null +++ b/Space-Invaders/Header/Global/Config.h @@ -0,0 +1,39 @@ +#pragma once +#include + +namespace Global +{ + class Config + { + public: + static const sf::String outscal_logo_texture_path; + static const sf::String background_texture_path; + static const sf::String player_texture_path; + + static const sf::String zapper_texture_path; + static const sf::String thunder_snake_texture_path; + static const sf::String subzero_texture_path; + static const sf::String ufo_texture_path; + static const sf::String bunker_texture_path; + + static const sf::String shield_texture_path; + static const sf::String tripple_laser_texture_path; + static const sf::String rapid_fire_texture_path; + static const sf::String outscal_bomb_texture_path; + + static const sf::String laser_bullet_texture_path; + static const sf::String torpedoe_texture_path; + static const sf::String frost_beam_texture_path; + + static const sf::String play_button_texture_path; + static const sf::String instructions_button_texture_path; + static const sf::String quit_button_texture_path; + static const sf::String menu_button_texture_path; + + static const sf::String bubble_bobble_font_path; + static const sf::String DS_DIGIB_font_path; + + static const sf::String background_music_path; + static const sf::String button_click_sound_path; + }; +} diff --git a/Space-Invaders/Header/Global/ServiceLocator.h b/Space-Invaders/Header/Global/ServiceLocator.h new file mode 100644 index 000000000..14f4faf36 --- /dev/null +++ b/Space-Invaders/Header/Global/ServiceLocator.h @@ -0,0 +1,64 @@ +#pragma once +#include "../../Header/Graphic/GraphicService.h" +#include "../../Header/Event/EventService.h" +#include "../../Header/Player/PlayerService.h" +#include "../../Header/Time/TimeService.h" +#include "../../Header/UI/UIService.h" +#include "../../Header/Enemy/EnemyService.h" +#include "../../Header/Gameplay/GameplayService.h" +#include "../../Header/Element/ElementService.h" +#include "../../Header/Sound/SoundService.h" +#include "../../Header/Bullet/BulletService.h" + + +// ServiceLocator Class Summary: This class manages access to various services in the application. +// include relevant headers files + +namespace Global +{ + class ServiceLocator + { + private: + + // Private Attributes: + Graphics::GraphicService* graphic_service; + Event::EventService* event_service; + Player::PlayerService* player_service; + Time::TimeService* time_service; + UI::UIService* ui_service; + Enemy::EnemyService* enemy_service; + Gameplay::GameplayService* gameplay_service; + Element::ElementService* element_service; + Sound::SoundService* sound_service; + Bullet::BulletService* bullet_service; + + // Public Methods + ServiceLocator(); + ~ServiceLocator(); + + // Private Methods: + void createServices(); + void clearAllServices(); + + public: + + // Public Methods: + static ServiceLocator* getInstance(); + void initialize(); // Initializes the ServiceLocator. + void update(); // Updates all services. + void render(); // Renders using the services. + + // Methods to Get Specific Services: + Event::EventService* getEventService(); // Retrieve the EventService instance + Graphics::GraphicService* getGraphicService(); // Retrieve the GraphicService instance + Player::PlayerService* getPlayerService(); // Retrieve the PlayerService instance + Time::TimeService* getTimeService(); // Retrieve the TimeService instance + UI::UIService* getUIService(); // Retrive the UIService instance + Enemy::EnemyService* getEnemyService(); // Retrive the EnemyService instance + Gameplay::GameplayService* getGameplayService(); // Retrive the GameplayService instance + Element::ElementService* getElementService(); // Retrive the ElementService instance + Sound::SoundService* getSoundService(); // Retrive the SoundService instance + Bullet::BulletService* getBulletService(); // Retrive the BulletService instance + void deleteServiceLocator(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Graphic/GraphicService.h b/Space-Invaders/Header/Graphic/GraphicService.h new file mode 100644 index 000000000..a0514d024 --- /dev/null +++ b/Space-Invaders/Header/Graphic/GraphicService.h @@ -0,0 +1,41 @@ +#pragma once +#include + +namespace Graphics +{ + class GraphicService + { + private: + + const std::string game_window_title = "Alien Invader"; + + const int game_window_width = 1920; + const int game_window_height = 1080; + + const int frame_rate = 60; + + const sf::Color window_color = sf::Color::Black; + + sf::VideoMode* video_mode; // ptr to video mode + sf::RenderWindow* game_window; // ptr to a RenderWindow + + void setVideoMode(); // Method for setting our video mode + void onDestroy(); // method to run when window is deleted + + public: + GraphicService(); + ~GraphicService(); //cleanup + + //method to create the game window. returns a pointer to an instance of the game window + sf::RenderWindow* createGameWindow(); + + + void initialize(); //lifecycle functions + void update(); //.. + void render(); //.. + bool isGameWindowOpen(); //check if the window is open + + sf::RenderWindow* getGameWindow(); //getter for the game window instance + sf::Color getWindowColor();//get the color + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Main/GameService.h b/Space-Invaders/Header/Main/GameService.h new file mode 100644 index 000000000..5671190cb --- /dev/null +++ b/Space-Invaders/Header/Main/GameService.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include "../../header/Global/ServiceLocator.h" + +namespace Main +{ + enum class GameState + { + BOOT, + MAIN_MENU, + GAMEPLAY, + }; + + class ServiceLocator; + + class GameService + { + private: + + static GameState current_state; + + Global::ServiceLocator* service_locator; + sf::RenderWindow* game_window; + + + void initialize(); // Handles game initialization. + void initializeVariables();// Handles game initialization. + void destroy(); // Handles cleanup tasks. + void showMainMenu(); + + public: + GameService(); // Constructor for initializing the GameService object. + ~GameService(); // Destructor for cleaning up resources upon object deletion. + + void ignite(); // Initiates the game. + void update(); // Updates the game logic and game state. + void render(); // Renders each frame of the game. + bool isRunning(); // Checks if the game is currently running. + static void setGameState(GameState new_state); + static GameState getGameState(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Player/PlayerController.h b/Space-Invaders/Header/Player/PlayerController.h new file mode 100644 index 000000000..09c3098fd --- /dev/null +++ b/Space-Invaders/Header/Player/PlayerController.h @@ -0,0 +1,33 @@ +#pragma once +#include + +namespace Player +{ + class PlayerView; + class PlayerModel; + enum class PlayerState; + + class PlayerController + { + private: + + PlayerView* player_view; + PlayerModel* player_model; + + void processPlayerInput(); + void moveLeft(); + void moveRight(); + + void fireBullet(); + + public: + PlayerController(); + ~PlayerController(); + + void initialize(); + void update(); + void render(); + + sf::Vector2f getPlayerPosition(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Player/PlayerModel.h b/Space-Invaders/Header/Player/PlayerModel.h new file mode 100644 index 000000000..4cb5016dc --- /dev/null +++ b/Space-Invaders/Header/Player/PlayerModel.h @@ -0,0 +1,47 @@ +#pragma once +#include + +namespace Player +{ + enum class PlayerState //Our Enum + { + ALIVE, + DEAD, + // we will add more states later + }; + + class PlayerModel + { + private: + const sf::Vector2f initial_player_position = sf::Vector2f(950.f, 950.f); + + sf::Vector2f player_position; + PlayerState player_state; //Declaration + int player_score; + + public: + const sf::Vector2f left_most_position = sf::Vector2f(50.f, 950.f); + const sf::Vector2f right_most_position = sf::Vector2f(1800.f, 950.f); + const sf::Vector2f barrel_position_offset = sf::Vector2f(20.f, 50.f); + + const float player_movement_speed = 600.0f; + + PlayerModel(); + ~PlayerModel(); + + void initialize(); + void reset(); + + sf::Vector2f getPlayerPosition(); + void setPlayerPosition(sf::Vector2f position); + + int getPlayerScore(); + void setPlayerScore(int score); + + //new getter and setter + PlayerState getPlayerState(); + void setPlayerState(PlayerState state); + + + }; +} diff --git a/Space-Invaders/Header/Player/PlayerService.h b/Space-Invaders/Header/Player/PlayerService.h new file mode 100644 index 000000000..a978d53c5 --- /dev/null +++ b/Space-Invaders/Header/Player/PlayerService.h @@ -0,0 +1,19 @@ +#pragma once +#include "../../Header/Player/PlayerController.h" + +namespace Player +{ + class PlayerService + { + private: + PlayerController* player_controller; + + public: + PlayerService(); + ~PlayerService(); + + void initialize(); + void update(); + void render(); + }; +} diff --git a/Space-Invaders/Header/Player/PlayerView.h b/Space-Invaders/Header/Player/PlayerView.h new file mode 100644 index 000000000..00fd6efa6 --- /dev/null +++ b/Space-Invaders/Header/Player/PlayerView.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "../../Header/Player/PlayerController.h" + +namespace Player +{ + class PlayerView + { + private: + + //const sf::String player_texture_path = "assets/textures/player_ship.png"; + const float player_sprite_width = 60.f; + const float player_sprite_height = 60.f; + + sf::RenderWindow* game_window; + + sf::Texture player_texture; + sf::Sprite player_sprite; + + void initializePlayerSprite(); + void scalePlayerSprite(); + + PlayerController* player_controller; // ptr to player controller + + public: + PlayerView(); + ~PlayerView(); + + void initialize(); + void update(); + void render(); + void initialize(PlayerController* controller); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Projectile/IProjectile.h b/Space-Invaders/Header/Projectile/IProjectile.h new file mode 100644 index 000000000..770b0e973 --- /dev/null +++ b/Space-Invaders/Header/Projectile/IProjectile.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include "../../Header/Bullet/BulletConfig.h" + +namespace Projectile +{ + enum class MovementDirection; + + class IProjectile + { + public: + virtual void initialize(sf::Vector2f position, Bullet::MovementDirection direction) = 0; + virtual void update() = 0; + virtual void render() = 0; + + virtual void updateProjectilePosition() = 0; + virtual sf::Vector2f getProjectilePosition() = 0; + + virtual ~IProjectile() {}; + }; +} diff --git a/Space-Invaders/Header/Sound/SoundService.h b/Space-Invaders/Header/Sound/SoundService.h new file mode 100644 index 000000000..93b0dd509 --- /dev/null +++ b/Space-Invaders/Header/Sound/SoundService.h @@ -0,0 +1,29 @@ +#pragma once +#include "SFML/Audio.hpp" + +namespace Sound +{ + enum class SoundType + { + BUTTON_CLICK, + }; + + class SoundService + { + private: + const int background_music_volume = 30; + + sf::Music background_music; + sf::Sound sound_effect; + sf::SoundBuffer buffer_button_click; + + void loadBackgroundMusicFromFile(); + void loadSoundFromFile(); + + public: + void initialize(); + + void playSound(SoundType soundType); + void playBackgroundMusic(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Header/Time/TimeService.h b/Space-Invaders/Header/Time/TimeService.h new file mode 100644 index 000000000..71184c46e --- /dev/null +++ b/Space-Invaders/Header/Time/TimeService.h @@ -0,0 +1,32 @@ +#pragma once +#include + + // The TimeService class helps keep track of time in game and calculate delta time. + // Utilizes the library to calculate delta time. + +namespace Time +{ + class TimeService + { + private: + + // A point in time which indicates the starting time of previous frame. + std::chrono::time_point previous_time; + + float delta_time; //to store the detla time + + void updateDeltaTime(); // method to update time + float calculateDeltaTime(); //calculate time by subtracting the previous time from the current time + void updatePreviousTime(); // finally update the current time to be previous time + + public: + + //lifecycle methods + void initialize(); + void update(); + + //getter + float getDeltaTime(); + }; +} + diff --git a/Space-Invaders/Header/UI/MainMenu/MainMenuUIController.h b/Space-Invaders/Header/UI/MainMenu/MainMenuUIController.h new file mode 100644 index 000000000..daa45b4bf --- /dev/null +++ b/Space-Invaders/Header/UI/MainMenu/MainMenuUIController.h @@ -0,0 +1,58 @@ +#pragma once +#include + +namespace UI +{ + namespace MainMenu + { + class MainMenuUIController + { + + private: + //const sf::String background_texture_path = "assets/textures/space_invaders_bg.png"; + //const sf::String play_button_texture_path = "assets/textures/play_button.png"; + //const sf::String instructions_button_texture_path = "assets/textures/instructions_button.png"; + //const sf::String quit_button_texture_path = "assets/textures/quit_button.png"; + + // Constants: + const float button_width = 400.f; + const float button_height = 140.f; + + sf::RenderWindow* game_window; + + // Textures: + sf::Texture background_texture; + sf::Sprite background_sprite; + + sf::Texture play_button_texture; + sf::Sprite play_button_sprite; + + sf::Texture instructions_button_texture; + sf::Sprite instructions_button_sprite; + + sf::Texture quit_button_texture; + sf::Sprite quit_button_sprite; + + // Buttons and scaling + void initializeBackgroundImage(); + void scaleBackgroundImage(); + void initializeButtons(); + bool loadButtonTexturesFromFile(); + void setButtonSprites(); + void scaleAllButttons(); + void scaleButton(sf::Sprite* button_to_scale); + void positionButtons(); + // Which button and function + void processButtonInteractions(); + bool clickedButton(sf::Sprite*, sf::Vector2f); + + public: + MainMenuUIController(); + + void initialize(); + void update(); + void render(); + + }; + } +} \ No newline at end of file diff --git a/Space-Invaders/Header/UI/UIService.h b/Space-Invaders/Header/UI/UIService.h new file mode 100644 index 000000000..2f8856ee3 --- /dev/null +++ b/Space-Invaders/Header/UI/UIService.h @@ -0,0 +1,23 @@ +#pragma once +#include "../../Header/UI/MainMenu/MainMenuUIController.h" + +namespace UI +{ + class UIService + { + private: + MainMenu::MainMenuUIController* main_menu_controller; + + void createControllers(); + void initializeControllers(); + void destroy(); + + public: + UIService(); + ~UIService(); + + void initialize(); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Source/Bullet/BulletController.cpp b/Space-Invaders/Source/Bullet/BulletController.cpp new file mode 100644 index 000000000..d7f4f8500 --- /dev/null +++ b/Space-Invaders/Source/Bullet/BulletController.cpp @@ -0,0 +1,92 @@ +#include "../../Header/Bullet/BulletController.h" +#include "../../Header/Bullet/BulletView.h" +#include "../../Header/Bullet/BulletModel.h" +#include "../../Header/Bullet/BulletConfig.h" +#include "../../Header/Global/ServiceLocator.h" + +namespace Bullet +{ + using namespace Global; + + void Bullet::BulletController::updateProjectilePosition() + { + switch (bullet_model->getMovementDirection()) + { + case::Bullet::MovementDirection::UP: + moveUp(); + break; + + case::Bullet::MovementDirection::DOWN: + moveDown(); + break; + } + } + + void Bullet::BulletController::moveUp() + { + sf::Vector2f currentPosition = bullet_model->getBulletPosition(); + currentPosition.y -= bullet_model->getMovementSpeed() * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + bullet_model->setBulletPosition(currentPosition); + } + + void Bullet::BulletController::moveDown() + { + sf::Vector2f currentPosition = bullet_model->getBulletPosition(); + currentPosition.y += bullet_model->getMovementSpeed() * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + bullet_model->setBulletPosition(currentPosition); + } + + void Bullet::BulletController::handleOutOfBounds() + { + sf::Vector2f bulletPosition = getProjectilePosition(); + sf::Vector2u windowSize = ServiceLocator::getInstance()->getGraphicService()->getGameWindow()->getSize(); + + if (bulletPosition.x < 0 || bulletPosition.x > windowSize.x || + bulletPosition.y < 0 || bulletPosition.y > windowSize.y) + { + ServiceLocator::getInstance()->getBulletService()->destroyBullet(this); + } + } + + BulletController::BulletController(BulletType type) + { + bullet_view = new BulletView(); + bullet_model = new BulletModel(type); + } + + BulletController::~BulletController() + { + delete (bullet_view); + delete (bullet_model); + } + + void BulletController::initialize(sf::Vector2f position, Bullet::MovementDirection direction) + { + bullet_view->initialize(this); + bullet_model->initialize(position, direction); + } + + void BulletController::update() + { + updateProjectilePosition(); + bullet_view->update(); + handleOutOfBounds(); + } + + void BulletController::render() + { + bullet_view->render(); + } + + sf::Vector2f BulletController::getProjectilePosition() + { + return bullet_model->getBulletPosition(); + } + + BulletType BulletController::getBulletType() + { + return bullet_model->getBulletType(); + } +} diff --git a/Space-Invaders/Source/Bullet/BulletModel.cpp b/Space-Invaders/Source/Bullet/BulletModel.cpp new file mode 100644 index 000000000..ed80e5b04 --- /dev/null +++ b/Space-Invaders/Source/Bullet/BulletModel.cpp @@ -0,0 +1,57 @@ +#include "../../Header/Bullet/BulletModel.h" + +namespace Bullet +{ + BulletModel::BulletModel(BulletType type) + { + bullet_type = type; + } + + BulletModel::~BulletModel() { } + + void BulletModel::initialize(sf::Vector2f position, MovementDirection direction) + { + movement_direction = direction; + bullet_position = position; + } + + sf::Vector2f BulletModel::getBulletPosition() + { + return bullet_position; + } + + void BulletModel::setBulletPosition(sf::Vector2f position) + { + bullet_position = position; + } + + BulletType BulletModel::getBulletType() + { + return bullet_type; + } + + void BulletModel::setBulletType(BulletType type) + { + bullet_type = type; + } + + MovementDirection BulletModel::getMovementDirection() + { + return movement_direction; + } + + void BulletModel::setMovementDirection(MovementDirection direction) + { + movement_direction = direction; + } + + float BulletModel::getMovementSpeed() + { + return movement_speed; + } + + void BulletModel::setMovementSpeed(float speed) + { + movement_speed = speed; + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Bullet/BulletService.cpp b/Space-Invaders/Source/Bullet/BulletService.cpp new file mode 100644 index 000000000..897d61a83 --- /dev/null +++ b/Space-Invaders/Source/Bullet/BulletService.cpp @@ -0,0 +1,63 @@ +#include "../../Header/Bullet/BulletService.h" +#include "../../Header/Bullet/BulletController.h" +#include "../../Header/Bullet/BulletConfig.h" +#include "../../Header/Bullet/Controllers/FrostBulletController.h" +#include "../../Header/Bullet/Controllers/LaserBulletController.h" +#include "../../Header/Bullet/Controllers/TorpedoController.h" + +namespace Bullet +{ + using namespace Controller; + using namespace Projectile; + + BulletService::BulletService() { } + + BulletService::~BulletService() { destroy(); } + + void BulletService::initialize() { } + + void BulletService::update() + { + for (int i = 0; i < bullet_list.size(); i++) bullet_list[i]->update(); + } + + void BulletService::render() + { + for (int i = 0; i < bullet_list.size(); i++) bullet_list[i]->render(); + } + + BulletController* BulletService::createBullet(BulletType bullet_type) + { + switch (bullet_type) + { + case::Bullet::BulletType::LASER_BULLET: + return new LaserBulletController(Bullet::BulletType::LASER_BULLET); + + case::Bullet::BulletType::FROST_BULLET: + return new FrostBulletController(Bullet::BulletType::FROST_BULLET); + + case::Bullet::BulletType::TORPEDO: + return new TorpedoController(Bullet::BulletType::TORPEDO); + } + } + + void BulletService::destroy() + { + for (int i = 0; i < bullet_list.size(); i++) delete (bullet_list[i]); + } + + BulletController* BulletService::spawnBullet(BulletType bullet_type, sf::Vector2f position, MovementDirection direction) + { + BulletController* bullet_controller = createBullet(bullet_type); + + bullet_controller->initialize(position, direction); + bullet_list.push_back(bullet_controller); + return bullet_controller; + } + + void BulletService::destroyBullet(BulletController* bullet_controller) + { + bullet_list.erase(std::remove(bullet_list.begin(), bullet_list.end(), bullet_controller), bullet_list.end()); + delete(bullet_controller); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Bullet/BulletView.cpp b/Space-Invaders/Source/Bullet/BulletView.cpp new file mode 100644 index 000000000..4d50a07dd --- /dev/null +++ b/Space-Invaders/Source/Bullet/BulletView.cpp @@ -0,0 +1,67 @@ +#include "../../Header/Bullet/BulletView.h" +#include "../../Header/Bullet/BulletController.h" +#include "../../Header/Global/ServiceLocator.h" +#include "../../Header/Global/Config.h" +#include "../../Header/Bullet/BulletConfig.h" + +namespace Bullet +{ + using namespace Global; + + BulletView::BulletView() { } + + BulletView::~BulletView() { } + + void BulletView::initialize(BulletController* controller) + { + bullet_controller = controller; + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializeImage(bullet_controller->getBulletType()); + } + + void BulletView::initializeImage(BulletType type) + { + switch (type) + { + case::Bullet::BulletType::LASER_BULLET: + if (bullet_texture.loadFromFile(Config::laser_bullet_texture_path)) + { + bullet_sprite.setTexture(bullet_texture); + scaleImage(); + } + break; + case::Bullet::BulletType::FROST_BULLET: + if (bullet_texture.loadFromFile(Config::frost_beam_texture_path)) + { + bullet_sprite.setTexture(bullet_texture); + scaleImage(); + } + break; + case::Bullet::BulletType::TORPEDO: + if (bullet_texture.loadFromFile(Config::torpedoe_texture_path)) + { + bullet_sprite.setTexture(bullet_texture); + scaleImage(); + } + break; + } + } + + void BulletView::scaleImage() + { + bullet_sprite.setScale( + static_cast(bullet_sprite_width) / bullet_sprite.getTexture()->getSize().x, + static_cast(bullet_sprite_height) / bullet_sprite.getTexture()->getSize().y + ); + } + + void BulletView::update() + { + bullet_sprite.setPosition(bullet_controller->getProjectilePosition()); + } + + void BulletView::render() + { + game_window->draw(bullet_sprite); + } +} diff --git a/Space-Invaders/Source/Bullet/Controllers/FrostBulletController.cpp b/Space-Invaders/Source/Bullet/Controllers/FrostBulletController.cpp new file mode 100644 index 000000000..3cd929822 --- /dev/null +++ b/Space-Invaders/Source/Bullet/Controllers/FrostBulletController.cpp @@ -0,0 +1,18 @@ +#include "../../Header/Bullet/Controllers/FrostBulletController.h" +#include "../../Header/Bullet/BulletModel.h" + +namespace Bullet +{ + namespace Controller + { + FrostBulletController::FrostBulletController(BulletType type) : BulletController(type) { } + + FrostBulletController::~FrostBulletController() { } + + void FrostBulletController::initialize(sf::Vector2f position, MovementDirection direction) + { + BulletController::initialize(position, direction); + bullet_model->setMovementSpeed(torpedo_movement_speed); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Bullet/Controllers/LaserBulletController.cpp b/Space-Invaders/Source/Bullet/Controllers/LaserBulletController.cpp new file mode 100644 index 000000000..170970514 --- /dev/null +++ b/Space-Invaders/Source/Bullet/Controllers/LaserBulletController.cpp @@ -0,0 +1,16 @@ +#include "../../Header/Bullet/Controllers/LaserBulletController.h" + +namespace Bullet +{ + namespace Controller + { + LaserBulletController::LaserBulletController(BulletType type) : BulletController(type) { } + + LaserBulletController::~LaserBulletController() { } + + void LaserBulletController::initialize(sf::Vector2f position, MovementDirection direction) + { + BulletController::initialize(position, direction); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Bullet/Controllers/TorpedoController.cpp b/Space-Invaders/Source/Bullet/Controllers/TorpedoController.cpp new file mode 100644 index 000000000..712702699 --- /dev/null +++ b/Space-Invaders/Source/Bullet/Controllers/TorpedoController.cpp @@ -0,0 +1,18 @@ +#include "../../Header/Bullet/Controllers/TorpedoController.h" +#include "../../Header/Bullet/BulletModel.h" + +namespace Bullet +{ + namespace Controller + { + TorpedoController::TorpedoController(BulletType type) : BulletController(type) { } + + TorpedoController::~TorpedoController() { } + + void TorpedoController::initialize(sf::Vector2f position, MovementDirection direction) + { + BulletController::initialize(position, direction); + bullet_model->setMovementSpeed(torpedo_movement_speed); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Element/Bunker/BunkerController.cpp b/Space-Invaders/Source/Element/Bunker/BunkerController.cpp new file mode 100644 index 000000000..8e3d95064 --- /dev/null +++ b/Space-Invaders/Source/Element/Bunker/BunkerController.cpp @@ -0,0 +1,24 @@ +#include "../../header/Element/Bunker/BunkerController.h" +#include "../../header/Element/Bunker/BunkerView.h" + +namespace Element +{ + namespace Bunker + { + BunkerController::BunkerController() { bunker_view = new BunkerView(); } + + BunkerController::~BunkerController() { delete(bunker_view); } + + void BunkerController::initialize(BunkerData data) + { + bunker_data = data; + bunker_view->initialize(this); + } + + void BunkerController::update() { bunker_view->update(); } + + void BunkerController::render() { bunker_view->render(); } + + sf::Vector2f BunkerController::getBunkerPosition() { return bunker_data.position; } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Element/Bunker/BunkerModel.cpp b/Space-Invaders/Source/Element/Bunker/BunkerModel.cpp new file mode 100644 index 000000000..04d29b58d --- /dev/null +++ b/Space-Invaders/Source/Element/Bunker/BunkerModel.cpp @@ -0,0 +1,14 @@ +#include "../../header/Element/Bunker/BunkerModel.h" + +namespace Element +{ + namespace Bunker + { + BunkerData::BunkerData() { }; + + BunkerData::BunkerData(sf::Vector2f position) + { + this->position = position; + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Element/Bunker/BunkerView.cpp b/Space-Invaders/Source/Element/Bunker/BunkerView.cpp new file mode 100644 index 000000000..5cd03623a --- /dev/null +++ b/Space-Invaders/Source/Element/Bunker/BunkerView.cpp @@ -0,0 +1,53 @@ +#include "../../header/Element/Bunker/BunkerView.h" +#include "../../header/Global/ServiceLocator.h" +#include "../../header/Element/Bunker/BunkerController.h" +#include "../../Header/Global/Config.h" + +namespace Element +{ + namespace Bunker + { + using namespace Global; + + BunkerView::BunkerView() { } + + BunkerView::~BunkerView() { } + + void BunkerView::initialize(BunkerController* controller) + { + bunker_controller = controller; + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializeImage(); + } + + void BunkerView::initializeImage() + { + if (bunker_texture.loadFromFile(Config::bunker_texture_path)) + { + bunker_sprite.setTexture(bunker_texture); + scaleSprite(); + } + } + + + void BunkerView::scaleSprite() + { + bunker_sprite.setScale( + static_cast(bunker_sprite_width) / bunker_sprite.getTexture()->getSize().x, + static_cast(bunker_sprite_height) / bunker_sprite.getTexture()->getSize().y + ); + } + + + void BunkerView::update() + { + bunker_sprite.setPosition(bunker_controller->getBunkerPosition()); + } + + void BunkerView::render() + { + game_window->draw(bunker_sprite); + } + + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Element/ElementService.cpp b/Space-Invaders/Source/Element/ElementService.cpp new file mode 100644 index 000000000..1aeff50b4 --- /dev/null +++ b/Space-Invaders/Source/Element/ElementService.cpp @@ -0,0 +1,34 @@ +#include "../../header/Element/ElementService.h" + +namespace Element +{ + ElementService::ElementService() { } + + ElementService::~ElementService() { destroy(); } + + void ElementService::initialize() + { + for (int i = 0; i < bunker_data_list.size(); i++) + { + Bunker::BunkerController* bunker_controller = new Bunker::BunkerController(); + + bunker_controller->initialize(bunker_data_list[i]); + bunker_list.push_back(bunker_controller); + } + } + + void ElementService::update() + { + for (int i = 0; i < bunker_list.size(); i++) bunker_list[i]->update(); + } + + void ElementService::render() + { + for (int i = 0; i < bunker_list.size(); i++) bunker_list[i]->render(); + } + + void ElementService::destroy() + { + for (int i = 0; i < bunker_list.size(); i++) delete(bunker_list[i]); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Enemy/Controllers/SubZeroController.cpp b/Space-Invaders/Source/Enemy/Controllers/SubZeroController.cpp new file mode 100644 index 000000000..5c6fbcd0e --- /dev/null +++ b/Space-Invaders/Source/Enemy/Controllers/SubZeroController.cpp @@ -0,0 +1,49 @@ +#include "../../Header/Enemy/Controllers/SubZeroController.h" +#include "../../Header/Enemy/EnemyModel.h" +#include "../../header/Enemy/EnemyConfig.h" +#include "../../Header/Global/ServiceLocator.h" + +namespace Enemy +{ + using namespace Global; + using namespace Bullet; + + namespace Controller + { + SubzeroController::SubzeroController(EnemyType type):EnemyController(type) { } + + SubzeroController::~SubzeroController() { } + + void SubzeroController::initialize() + { + EnemyController::initialize(); + enemy_model->setMovementDirection(MovementDirection::DOWN); + rate_of_fire = subzero_rate_of_fire; + } + + void SubzeroController::move() + { + switch (enemy_model->getMovementDirection()) + { + case::Enemy::MovementDirection::DOWN: + moveDown(); + break; + } + } + + void SubzeroController::moveDown() + { + sf::Vector2f currentPosition = enemy_model->getEnemyPosition(); + currentPosition.y += vertical_movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + enemy_model->setEnemyPosition(currentPosition); + } + + void SubzeroController::fireBullet() + { + ServiceLocator::getInstance()->getBulletService()->spawnBullet(BulletType::FROST_BULLET, + enemy_model->getEnemyPosition() + enemy_model->barrel_position_offset, + Bullet::MovementDirection::DOWN); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Enemy/Controllers/ZapperController.cpp b/Space-Invaders/Source/Enemy/Controllers/ZapperController.cpp new file mode 100644 index 000000000..baa90a730 --- /dev/null +++ b/Space-Invaders/Source/Enemy/Controllers/ZapperController.cpp @@ -0,0 +1,126 @@ +#include "../../Header/Enemy/Controllers/ZapperController.h" +#include "../../Header/Enemy/EnemyModel.h" +#include "../../Header/Enemy/EnemyConfig.h" +#include "../../Header/Global/ServiceLocator.h" +#include "../../Header/Bullet/BulletConfig.h" + +namespace Enemy +{ + using namespace Global; + using namespace Bullet; + + namespace Controller + { + ZapperController::ZapperController(EnemyType type) : EnemyController(type){ } + + ZapperController::~ZapperController() { } + + void ZapperController::initialize() + { + EnemyController::initialize();; + } + + void ZapperController::move() + { + // Switch statement based on the movement direction of the enemy + switch (enemy_model->getMovementDirection()) + { + // If the movement direction is LEFT + case::Enemy::MovementDirection::LEFT: + moveLeft(); + break; + + // If the movement direction is RIGHT + case::Enemy::MovementDirection::RIGHT: + moveRight(); + break; + + // If the movement direction is DOWN + case::Enemy::MovementDirection::DOWN: + moveDown(); + break; + } + } + + void ZapperController::moveLeft() + { + // Get the current position of the enemy + sf::Vector2f currentPosition = enemy_model->getEnemyPosition(); + + // Update the position to move left + currentPosition.x -= enemy_model->enemy_movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + // Check if the enemy reached the leftmost position + if (currentPosition.x <= enemy_model->left_most_position.x) + { + // Set movement direction to DOWN and update reference position + enemy_model->setMovementDirection(MovementDirection::DOWN); + enemy_model->setReferencePosition(currentPosition); + } + else + { + // Update the enemy position + enemy_model->setEnemyPosition(currentPosition); + } + } + + void ZapperController::moveRight() + { + // Get the current position of the enemy + sf::Vector2f currentPosition = enemy_model->getEnemyPosition(); + + // Update the position to move right + currentPosition.x += enemy_model->enemy_movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + // Check if the enemy reached the rightmost position + if (currentPosition.x >= enemy_model->right_most_position.x) + { + // Set movement direction to DOWN and update reference position + enemy_model->setMovementDirection(MovementDirection::DOWN); + enemy_model->setReferencePosition(currentPosition); + } + else + { + // Update the enemy position + enemy_model->setEnemyPosition(currentPosition); + } + } + + void ZapperController::moveDown() + { + // Get the current position of the enemy + sf::Vector2f currentPosition = enemy_model->getEnemyPosition(); + + // Update the position to move down + currentPosition.y += enemy_model->enemy_movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + // Check if the enemy reached the reference position plus vertical travel distance + if (currentPosition.y >= enemy_model->getReferencePosition().y + vertical_travel_distance) + { + // Check if the enemy reference position is on the left side + if (enemy_model->getReferencePosition().x <= enemy_model->left_most_position.x) + { + // Set movement direction to RIGHT + enemy_model->setMovementDirection(MovementDirection::RIGHT); + } + else + { + // Set movement direction to LEFT + enemy_model->setMovementDirection(MovementDirection::LEFT); + } + } + else + { + // Update the enemy position + enemy_model->setEnemyPosition(currentPosition); + } + } + + void ZapperController::fireBullet() + { + ServiceLocator::getInstance()->getBulletService()->spawnBullet(BulletType::LASER_BULLET, + enemy_model->getEnemyPosition() + enemy_model->barrel_position_offset, + Bullet::MovementDirection::DOWN); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Enemy/EnemyController.cpp b/Space-Invaders/Source/Enemy/EnemyController.cpp new file mode 100644 index 000000000..b89da8838 --- /dev/null +++ b/Space-Invaders/Source/Enemy/EnemyController.cpp @@ -0,0 +1,114 @@ +#include "../../header/Enemy/EnemyController.h" +#include "../../header/Enemy/EnemyView.h" +#include "../../header/Enemy/EnemyModel.h" +#include "../../header/Global/ServiceLocator.h" +#include "../../header/Event/EventService.h" + +namespace Enemy +{ + using namespace Global; + using namespace Event; + using namespace Time; + using namespace Bullet; + + EnemyController::EnemyController(EnemyType type) + { + enemy_view = new EnemyView(); + enemy_model = new EnemyModel(type); + } + + EnemyController::~EnemyController() + { + delete (enemy_view); + delete (enemy_model); + } + + void EnemyController::initialize() + { + enemy_model->initialize(); + enemy_model->setEnemyPosition(getRandomInitialPosition()); + enemy_view->initialize(this); + } + + void EnemyController::update() + { + move(); + updateFireTimer(); //new + processBulletFire(); //new + enemy_view->update(); + handleOutOfBounds(); + } + + void EnemyController::render() + { + enemy_view->render(); + } + + /*void EnemyController::move() + { + switch (enemy_model->getMovementDirection()) + { + case::Enemy::MovementDirection::LEFT: + moveLeft(); + break; + + case::Enemy::MovementDirection::RIGHT: + moveRight(); + break; + + case::Enemy::MovementDirection::DOWN: + moveDown(); + break; + } + }*/ + + void EnemyController::updateFireTimer() + { + elapsed_fire_duration += ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); //update the elapsed duration + } + + void EnemyController::processBulletFire() //if elapsed duration is equal to or more than the amount of time we want to wait until firing than call the fire method. + { + if (elapsed_fire_duration >= rate_of_fire) + { + fireBullet(); + elapsed_fire_duration = 0.f; //set elapsed duration back to 0. + } + } + + sf::Vector2f EnemyController::getRandomInitialPosition() + { + float x_offset_distance = (std::rand() % static_cast(enemy_model->right_most_position.x - enemy_model->left_most_position.x)); + float x_position = enemy_model->left_most_position.x + x_offset_distance; + float y_position = enemy_model->left_most_position.y; + + return sf::Vector2f(x_position, y_position); + } + + void EnemyController::handleOutOfBounds() + { + sf::Vector2f enemyPosition = getEnemyPosition(); + sf::Vector2u windowSize = ServiceLocator::getInstance()->getGraphicService()->getGameWindow()->getSize(); + + if (enemyPosition.x < 0 || enemyPosition.x > windowSize.x || + enemyPosition.y < 0 || enemyPosition.y > windowSize.y) + { + ServiceLocator::getInstance()->getEnemyService()->destroyEnemy(this); + } + } + + sf::Vector2f EnemyController::getEnemyPosition() + { + return enemy_model->getEnemyPosition(); + } + + EnemyState EnemyController::getEnemyState() + { + return enemy_model->getEnemyState(); + } + + EnemyType EnemyController::getEnemyType() + { + return enemy_model->getEnemyType(); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Enemy/EnemyModel.cpp b/Space-Invaders/Source/Enemy/EnemyModel.cpp new file mode 100644 index 000000000..052bffabc --- /dev/null +++ b/Space-Invaders/Source/Enemy/EnemyModel.cpp @@ -0,0 +1,67 @@ +#include "../../Header/Enemy/EnemyModel.h" +#include "../../Header/Enemy/EnemyConfig.h" + +namespace Enemy +{ + EnemyModel::EnemyModel(EnemyType type) { enemy_type = type; } + + EnemyModel::~EnemyModel() { } + + void EnemyModel::initialize() + { + enemy_state = EnemyState::PATROLLING; + movement_direction = MovementDirection::RIGHT; + enemy_position = reference_position; + } + + sf::Vector2f EnemyModel::getEnemyPosition() + { + return enemy_position; + } + + void EnemyModel::setEnemyPosition(sf::Vector2f position) + { + enemy_position = position; + } + + sf::Vector2f EnemyModel::getReferencePosition() + { + return reference_position; + } + + void EnemyModel::setReferencePosition(sf::Vector2f position) + { + reference_position = position; + } + + EnemyState EnemyModel::getEnemyState() + { + return enemy_state; + } + + void EnemyModel::setEnemyState(EnemyState state) + { + enemy_state = state; + } + + EnemyType EnemyModel::getEnemyType() + { + return enemy_type; + } + + void EnemyModel::setEnemyType(EnemyType type) + { + enemy_type = type; + } + + MovementDirection EnemyModel::getMovementDirection() + { + return movement_direction; + } + + void EnemyModel::setMovementDirection(MovementDirection direction) + { + movement_direction = direction; + } + +} \ No newline at end of file diff --git a/Space-Invaders/Source/Enemy/EnemyService.cpp b/Space-Invaders/Source/Enemy/EnemyService.cpp new file mode 100644 index 000000000..4dfff0ffe --- /dev/null +++ b/Space-Invaders/Source/Enemy/EnemyService.cpp @@ -0,0 +1,98 @@ +#include "../../Header/Enemy/EnemyService.h" +#include "../../Header/Enemy/EnemyController.h" +#include "../../Header/Global/ServiceLocator.h" +#include "../../Header/Time/TimeService.h" +#include "../../Header/Enemy/EnemyConfig.h" +#include "../../Header/Enemy/Controllers/SubZeroController.h" +#include "../../Header/Enemy/Controllers/ZapperController.h" + +namespace Enemy +{ + using namespace Global; + using namespace Time; + using namespace Controller; + + EnemyService::EnemyService() { std::srand(static_cast(std::time(nullptr))); } + + EnemyService::~EnemyService() { destroy(); } + + void EnemyService::initialize() + { + spawn_timer = spawn_interval; + } + + void EnemyService::update() + { + updateSpawnTimer(); + processEnemySpawn(); + + for (int i = 0; i < enemy_list.size(); i++) enemy_list[i]->update(); + } + + void EnemyService::render() + { + for (int i = 0; i < enemy_list.size(); i++) enemy_list[i]->render(); + } + + EnemyController* EnemyService::spawnEnemy() + { + // The base class pointer will be pointing to a child class object + EnemyController* enemy_controller = createEnemy(getRandomEnemyType()); + + enemy_controller->initialize(); + enemy_list.push_back(enemy_controller); + + return enemy_controller; + } + + void EnemyService::destroyEnemy(EnemyController* enemy_controller) + { + enemy_list.erase(std::remove(enemy_list.begin(), enemy_list.end(), enemy_controller), enemy_list.end()); + + // Delete the enemy_controller object from memory to free up resources. + delete(enemy_controller); + } + + void EnemyService::updateSpawnTimer() + { + spawn_timer += ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); // increase timer + } + + void EnemyService::processEnemySpawn() + { + if (spawn_timer >= spawn_interval) + { + spawnEnemy(); //spawn + spawn_timer = 0.0f; // reset + } + } + + EnemyType EnemyService::getRandomEnemyType() + { + int randomType = std::rand() % 2; //since we only have 2 enemies right now + return static_cast(randomType); + } + + EnemyController* EnemyService::createEnemy(EnemyType enemy_type) + { + switch (enemy_type) + { + case::Enemy::EnemyType::ZAPPER: + return new ZapperController(Enemy::EnemyType::ZAPPER); + + /*case::Enemy::EnemyType::THUNDER_SNAKE: + return new ThunderSnakeController(Enemy::EnemyType::THUNDER_SNAKE);*/ + + case::Enemy::EnemyType::SUBZERO: + return new SubzeroController(Enemy::EnemyType::SUBZERO); + + /*case::Enemy::EnemyType::UFO: + return new UFOController(Enemy::EnemyType::UFO);*/ + } + } + + void EnemyService::destroy() + { + for (int i = 0; i < enemy_list.size(); i++) delete (enemy_list[i]); //delete all enemies + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Enemy/EnemyView.cpp b/Space-Invaders/Source/Enemy/EnemyView.cpp new file mode 100644 index 000000000..70e3cd142 --- /dev/null +++ b/Space-Invaders/Source/Enemy/EnemyView.cpp @@ -0,0 +1,63 @@ +#include "../../Header/Enemy/EnemyView.h" +#include "../../Header/Global/ServiceLocator.h" +#include "../../Header/Graphic/GraphicService.h" +#include "../../Header/Enemy/EnemyController.h" +#include"../../Header/Enemy/EnemyConfig.h" +#include "../../Header/Global/Config.h" + +namespace Enemy +{ + using namespace Global; + using namespace Graphics; + + EnemyView::EnemyView() { } + + EnemyView::~EnemyView() { } + + void EnemyView::initialize(EnemyController* controller) + { + enemy_controller = controller; + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializeEnemySprite(enemy_controller->getEnemyType()); + } + + void EnemyView::initializeEnemySprite(EnemyType type) + { + switch (type) + { + case::Enemy::EnemyType::SUBZERO: + if (enemy_texture.loadFromFile(Config::subzero_texture_path)) + { + enemy_sprite.setTexture(enemy_texture); + scaleEnemySprite(); + } + break; + case::Enemy::EnemyType::ZAPPER: + if (enemy_texture.loadFromFile(Config::zapper_texture_path)) + { + enemy_sprite.setTexture(enemy_texture); + scaleEnemySprite(); + } + break; + } + } + + void EnemyView::scaleEnemySprite() + { + // method to scale the Sprite according to our set dimensions. Don't worry about the static_cast, that will be discussed later. + enemy_sprite.setScale( + static_cast(enemy_sprite_width) / enemy_sprite.getTexture()->getSize().x, + static_cast(enemy_sprite_height) / enemy_sprite.getTexture()->getSize().y + ); + } + + void EnemyView::update() + { + enemy_sprite.setPosition(enemy_controller->getEnemyPosition()); + } + + void EnemyView::render() + { + game_window->draw(enemy_sprite); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Event/EventService.cpp b/Space-Invaders/Source/Event/EventService.cpp new file mode 100644 index 000000000..cd456eff0 --- /dev/null +++ b/Space-Invaders/Source/Event/EventService.cpp @@ -0,0 +1,118 @@ +#include "../../Header/Event/EventService.h" +#include "../../Header/Main/GameService.h" +#include "../../Header/Graphic/GraphicService.h" +#include "../../Header/Global/ServiceLocator.h" + +namespace Event +{ + + EventService::EventService() { game_window = nullptr; } + + EventService::~EventService() = default; //calls the default destructor + + using namespace Global; + + void EventService::initialize() + { + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + } + + void EventService::update() + { + updateMouseButtonsState(left_mouse_button_state, sf::Mouse::Left); + updateMouseButtonsState(right_mouse_button_state, sf::Mouse::Right); + updateKeyboardButtonsState(left_arrow_button_state, sf::Keyboard::Left); + updateKeyboardButtonsState(right_arrow_button_state, sf::Keyboard::Right); + updateKeyboardButtonsState(A_button_state, sf::Keyboard::A); + updateKeyboardButtonsState(D_button_state, sf::Keyboard::D); + } + + void EventService::processEvents() + { + if (isGameWindowOpen()) { + while (game_window->pollEvent(game_event)) { + // Check for window closure + if (gameWindowWasClosed() || hasQuitGame()) + { + game_window->close(); + } + } + } + } + + void EventService::updateMouseButtonsState(ButtonState& current_button_state, sf::Mouse::Button mouse_button) + { + if (sf::Mouse::isButtonPressed(mouse_button)) + { + switch (current_button_state) + { + case ButtonState::RELEASED: + current_button_state = ButtonState::PRESSED; + break; + case ButtonState::PRESSED: + current_button_state = ButtonState::HELD; + break; + } + } + else + { + current_button_state = ButtonState::RELEASED; + } + } + + void EventService::updateKeyboardButtonsState(ButtonState& current_button_state, sf::Keyboard::Key keyboard_button) + { + if (sf::Keyboard::isKeyPressed(keyboard_button)) + { + switch (current_button_state) + { + case ButtonState::RELEASED: + current_button_state = ButtonState::PRESSED; + break; + case ButtonState::PRESSED: + current_button_state = ButtonState::HELD; + break; + } + } + else + { + current_button_state = ButtonState::RELEASED; + } + } + + bool EventService::hasQuitGame() { return (isKeyboardEvent() && pressedEscapeKey()); } // only true if the ESC key is pressed and a keyboard event has been registered + + //checks for if a keyboard key has been pressed + bool EventService::isKeyboardEvent() { return game_event.type == sf::Event::KeyPressed; } + + //control click on the SFML functions to see what they do internally + bool EventService::pressedEscapeKey() { return game_event.key.code == sf::Keyboard::Escape; } + bool EventService::isGameWindowOpen() { return game_window != nullptr; } + bool EventService::gameWindowWasClosed() { return game_event.type == sf::Event::Closed; } + + // Player inputs + bool EventService::pressedLeftKey() { return left_arrow_button_state == ButtonState::HELD; } + + bool EventService::pressedRightKey() { return right_arrow_button_state == ButtonState::HELD; } + + bool EventService::pressedAKey() { return A_button_state == ButtonState::HELD; } + + bool EventService::pressedDKey() { return D_button_state == ButtonState::HELD; } + + bool EventService::pressedLeftMouseButton() { return left_mouse_button_state == ButtonState::PRESSED; } + + bool EventService::pressedRightMouseButton() { return right_mouse_button_state == ButtonState::PRESSED; } + + /*bool EventService::pressedLeftKey() { return game_event.key.code == sf::Keyboard::Left; } + bool EventService::pressedRightKey() { return game_event.key.code == sf::Keyboard::Right; } + bool EventService::pressedLeftMouseButton() + { + // check if a mouse button was pressed and which mouse button it was + return game_event.type == sf::Event::MouseButtonPressed && game_event.mouseButton.button == sf::Mouse::Left; + } + + bool EventService::pressedRightMouseButton() + { + return game_event.type == sf::Event::MouseButtonPressed && game_event.mouseButton.button == sf::Mouse::Right; + }*/ +} \ No newline at end of file diff --git a/Space-Invaders/Source/Gameplay/GameplayController.cpp b/Space-Invaders/Source/Gameplay/GameplayController.cpp new file mode 100644 index 000000000..ceb231491 --- /dev/null +++ b/Space-Invaders/Source/Gameplay/GameplayController.cpp @@ -0,0 +1,15 @@ +#include "../../header/Gameplay/GameplayController.h" +#include "../../header/Gameplay/GameplayView.h" + +namespace Gameplay +{ + GameplayController::GameplayController() { gameplay_view = new GameplayView(); } + + GameplayController::~GameplayController() { delete (gameplay_view); } + + void GameplayController::initialize() { gameplay_view->initialize(); } + + void GameplayController::update() { gameplay_view->update(); } + + void GameplayController::render() { gameplay_view->render(); } +} diff --git a/Space-Invaders/Source/Gameplay/GameplayService.cpp b/Space-Invaders/Source/Gameplay/GameplayService.cpp new file mode 100644 index 000000000..91b7e9761 --- /dev/null +++ b/Space-Invaders/Source/Gameplay/GameplayService.cpp @@ -0,0 +1,15 @@ +#include "../../header/Gameplay/GameplayService.h" +#include "../../header/Gameplay/GameplayController.h" + +namespace Gameplay +{ + GameplayService::GameplayService() { gameplay_controller = new GameplayController(); } + + GameplayService::~GameplayService() { delete (gameplay_controller); } + + void GameplayService::initialize() { gameplay_controller->initialize(); } + + void GameplayService::update() { gameplay_controller->update(); } + + void GameplayService::render() { gameplay_controller->render(); } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Gameplay/GameplayView.cpp b/Space-Invaders/Source/Gameplay/GameplayView.cpp new file mode 100644 index 000000000..48af47575 --- /dev/null +++ b/Space-Invaders/Source/Gameplay/GameplayView.cpp @@ -0,0 +1,41 @@ +#include "../../header/Gameplay/GameplayView.h" +#include "../../header/Global/ServiceLocator.h" +#include "../../header/Graphic/GraphicService.h" +#include "../../Header/Global/Config.h" + +namespace Gameplay +{ + using namespace Global; + using namespace Graphics; + + GameplayView::GameplayView() { } + + GameplayView::~GameplayView() { } + + void GameplayView::initialize() + { + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializeBackgroundSprite(); + } + + void GameplayView::initializeBackgroundSprite() + { + if (background_texture.loadFromFile(Config::background_texture_path)) + { + background_sprite.setTexture(background_texture); + scaleBackgroundSprite(); + } + } + + void GameplayView::scaleBackgroundSprite() + { + background_sprite.setScale( + static_cast(game_window->getSize().x) / background_sprite.getTexture()->getSize().x, + static_cast(game_window->getSize().y) / background_sprite.getTexture()->getSize().y + ); + } + + void GameplayView::update() { } + + void GameplayView::render() { game_window->draw(background_sprite); } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Global/Config.cpp b/Space-Invaders/Source/Global/Config.cpp new file mode 100644 index 000000000..bc8151e53 --- /dev/null +++ b/Space-Invaders/Source/Global/Config.cpp @@ -0,0 +1,56 @@ +#include "../../header/Global/Config.h" + +namespace Global +{ + const sf::String Config::outscal_logo_texture_path = "assets/textures/outscal_logo.png"; + + const sf::String Config::background_texture_path = "assets/textures/space_invaders_bg.png"; + + const sf::String Config::player_texture_path = "assets/textures/player_ship.png"; + + + const sf::String Config::zapper_texture_path = "assets/textures/zapper.png"; + + const sf::String Config::thunder_snake_texture_path = "assets/textures/thunder_snake.png"; + + const sf::String Config::subzero_texture_path = "assets/textures/subzero.png"; + + const sf::String Config::ufo_texture_path = "assets/textures/ufo.png"; + + const sf::String Config::bunker_texture_path = "assets/textures/bunker.png"; + + + const sf::String Config::shield_texture_path = "assets/textures/shield.png"; + + const sf::String Config::tripple_laser_texture_path = "assets/textures/tripple_laser.png"; + + const sf::String Config::rapid_fire_texture_path = "assets/textures/rapid_fire.png"; + + const sf::String Config::outscal_bomb_texture_path = "assets/textures/outscal_bomb.png"; + + + const sf::String Config::laser_bullet_texture_path = "assets/textures/laser_bullet.png"; + + const sf::String Config::torpedoe_texture_path = "assets/textures/torpedoe.png"; + + const sf::String Config::frost_beam_texture_path = "assets/textures/frost_beam.png"; + + + const sf::String Config::play_button_texture_path = "assets/textures/play_button.png"; + + const sf::String Config::instructions_button_texture_path = "assets/textures/instructions_button.png"; + + const sf::String Config::quit_button_texture_path = "assets/textures/quit_button.png"; + + const sf::String Config::menu_button_texture_path = "assets/textures/menu_button.png"; + + + const sf::String Config::bubble_bobble_font_path = "assets/fonts/bubbleBobble.ttf"; + + const sf::String Config::DS_DIGIB_font_path = "assets/fonts/DS_DIGIB.ttf"; + + + const sf::String Config::background_music_path = "assets/sounds/background_music.mp3"; + + const sf::String Config::button_click_sound_path = "assets/sounds/button_click_sound.wav"; +} \ No newline at end of file diff --git a/Space-Invaders/Source/Global/ServiceLocator.cpp b/Space-Invaders/Source/Global/ServiceLocator.cpp new file mode 100644 index 000000000..e6cd7d7d9 --- /dev/null +++ b/Space-Invaders/Source/Global/ServiceLocator.cpp @@ -0,0 +1,138 @@ +#include "../../Header/Global/ServiceLocator.h" +#include "../../header/Main/GameService.h" + +namespace Global +{ + using namespace Main; + using namespace Graphics; + using namespace Event; + using namespace Time; + using namespace Player; + using namespace UI; + using namespace Enemy; + using namespace Gameplay; + using namespace Element; + using namespace Sound; + using namespace Bullet; + + + ServiceLocator::ServiceLocator() + { + graphic_service = nullptr; + event_service = nullptr; + player_service = nullptr; + time_service = nullptr; + ui_service = nullptr; + enemy_service = nullptr; + gameplay_service = nullptr; + element_service = nullptr; + sound_service = nullptr; + bullet_service = nullptr; + createServices(); + } + ServiceLocator::~ServiceLocator() + { + clearAllServices(); + } + + void ServiceLocator::createServices() + { + graphic_service = new GraphicService(); + event_service = new EventService(); + player_service = new PlayerService(); + time_service = new TimeService(); + ui_service = new UIService(); + enemy_service = new EnemyService(); + gameplay_service = new GameplayService(); + element_service = new ElementService(); + sound_service = new SoundService(); + bullet_service = new BulletService(); + } + + void ServiceLocator::clearAllServices() + { + delete(graphic_service); + delete(event_service); + delete(player_service); + delete(time_service); + delete(ui_service); + delete(enemy_service); + delete(gameplay_service); + delete(element_service); + delete(sound_service); + delete(bullet_service); + } + + ServiceLocator* ServiceLocator::getInstance() + { + static ServiceLocator instance; + return &instance; + } + + void ServiceLocator::initialize() + { + graphic_service->initialize(); + event_service->initialize(); + player_service->initialize(); + time_service->initialize(); + ui_service->initialize(); + enemy_service->initialize(); + gameplay_service->initialize(); + element_service->initialize(); + sound_service->initialize(); + bullet_service->initialize(); + } + + void ServiceLocator::update() + { + graphic_service->update(); + time_service->update(); + event_service->update(); + + if (GameService::getGameState() == GameState::GAMEPLAY) + { + gameplay_service->update(); + player_service->update(); + enemy_service->update(); + bullet_service->update(); + element_service->update(); + } + + ui_service->update(); + } + + void ServiceLocator::render() + { + graphic_service->render(); + + if (GameService::getGameState() == GameState::GAMEPLAY) + { + gameplay_service->render(); + player_service->render(); + enemy_service->render(); + bullet_service->render(); + element_service->render(); + } + + ui_service->render(); + //no event service because nothing to render + //no time service because nothing to render + } + + GraphicService* ServiceLocator::getGraphicService() { return graphic_service; } + EventService* ServiceLocator::getEventService() { return event_service; } + PlayerService* ServiceLocator::getPlayerService() { return player_service; } + TimeService* ServiceLocator::getTimeService() { return time_service; } + UIService* ServiceLocator::getUIService() { return ui_service; } + EnemyService* ServiceLocator::getEnemyService() { return enemy_service; } + GameplayService* ServiceLocator::getGameplayService() { return gameplay_service; } + ElementService* ServiceLocator::getElementService() { return element_service; } + SoundService* ServiceLocator::getSoundService() { return sound_service; } + BulletService* ServiceLocator::getBulletService() { return bullet_service; } + + void ServiceLocator::deleteServiceLocator() + { + delete(this); + } + +} \ No newline at end of file diff --git a/Space-Invaders/Source/Graphic/GraphicService.cpp b/Space-Invaders/Source/Graphic/GraphicService.cpp new file mode 100644 index 000000000..98ab5cc20 --- /dev/null +++ b/Space-Invaders/Source/Graphic/GraphicService.cpp @@ -0,0 +1,59 @@ +#include "../../Header/Graphic/GraphicService.h" + +namespace Graphics +{ + // Constructor: Initializes game window and video mode pointers to null. + GraphicService::GraphicService() { + game_window = nullptr; // Initializes game window pointer to null + video_mode = nullptr; // Initializes video mode pointer to null + } + + // Destructor: Cleans up resources by calling onDestroy. + GraphicService::~GraphicService() { + onDestroy(); // Calls onDestroy method to clean up resources + } + + // Initializes the graphic service by creating a new game window. + void GraphicService::initialize() { + game_window = createGameWindow(); // Assigns a new game window + game_window->setFramerateLimit(frame_rate); // setting a frame rate limit + } + + // Creates a new SFML RenderWindow object with specified video mode and title. + sf::RenderWindow* GraphicService::createGameWindow() { + setVideoMode(); // Sets up the video mode for the window + return new sf::RenderWindow(*video_mode, game_window_title, sf::Style::Fullscreen); // Creates and returns a new RenderWindow object + } + + // Sets up the video mode for the game window using specified dimensions and system's color depth. + void GraphicService::setVideoMode() { + video_mode = new sf::VideoMode(game_window_width, game_window_height, sf::VideoMode::getDesktopMode().bitsPerPixel); // Allocates and sets the video mode + } + + // Cleans up allocated memory for video mode and game window to avoid memory leaks. + void GraphicService::onDestroy() { + delete(video_mode); // Deletes the video mode object + delete(game_window); // Deletes the game window object + } + + // Placeholder function for game update logic. + void GraphicService::update() { } + + // Placeholder function for game rendering logic. + void GraphicService::render() { } + + // Checks if the game window is currently open. + bool GraphicService::isGameWindowOpen() { + return game_window->isOpen(); // Returns the open status of the game window + } + + // Returns a pointer to the game window object. + sf::RenderWindow* GraphicService::getGameWindow() { + return game_window; + } + + // Returns the configured window background color. + sf::Color GraphicService::getWindowColor() { + return window_color; + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Main/GameService.cpp b/Space-Invaders/Source/Main/GameService.cpp new file mode 100644 index 000000000..0118a4dab --- /dev/null +++ b/Space-Invaders/Source/Main/GameService.cpp @@ -0,0 +1,83 @@ +#include "../../Header/Main/GameService.h" +#include "../../Header/Graphic/GraphicService.h" +#include "../../Header/Global/ServiceLocator.h" + +namespace Main +{ + using namespace Global; + using namespace Graphics; + using namespace Event; + + GameState GameService::current_state = GameState::BOOT; + + // Constructor: Initializes pointers to null. + GameService::GameService() { + service_locator = nullptr; // Set service locator to null + game_window = nullptr; // Set game window to null + } + + // Destructor: Calls the destroy function to clean up resources. + GameService::~GameService() { + destroy(); // Clean up and release resources + } + + // Prepares the game service for use by obtaining the service locator instance and initializing services. + void GameService::ignite() { + service_locator = Global::ServiceLocator::getInstance(); // Get ServiceLocator + initialize(); // Initialize services. + } + + //initialize service locator and other variables + void GameService::initialize() + { + service_locator->initialize(); + initializeVariables(); + // set the gamestate to main menu + showMainMenu(); + } + + void GameService::initializeVariables() + { + game_window = service_locator->getGraphicService()->getGameWindow(); //set game window (it was null before this) + } + + void GameService::destroy() + { + // don't need to do anything here for now. + } + + void GameService::showMainMenu() + { + setGameState(GameState::MAIN_MENU); + } + + // Updates the game logic by delegating to the service locator's update method. + void GameService::update() { + + service_locator->getEventService()->processEvents(); + + service_locator->update(); // Call update on the service locator which then updates all its managed services + } + + // Clears the window then display it. + void GameService::render() { + // Clears the game window with the background color provided by the graphic service + game_window->clear(service_locator->getGraphicService()->getWindowColor()); + service_locator->render(); // Render the current frame using the service locator + game_window->display(); // Display the rendered frame on the game window + } + + // Checks if the game is still running by querying the graphic service's window open status. + bool GameService::isRunning() { + // Returns true if the game window is open, indicating the game is still running + return service_locator->getGraphicService()->isGameWindowOpen(); + } + + // Setter function foro the game state + void GameService::setGameState(GameState new_state) { current_state = new_state; } + + // Getter function for the current game state + GameState GameService::getGameState() { return current_state; } +} + + diff --git a/Space-Invaders/Source/Player/PlayerController.cpp b/Space-Invaders/Source/Player/PlayerController.cpp new file mode 100644 index 000000000..49ac671f9 --- /dev/null +++ b/Space-Invaders/Source/Player/PlayerController.cpp @@ -0,0 +1,96 @@ +#include "../../Header/Player/PlayerController.h" +#include "../../Header/Player/PlayerModel.h" +#include "../../Header/Player/PlayerView.h" +#include "../../Header/Event/EventService.h" +#include "../../Header/Global/ServiceLocator.h" +#include + +namespace Player +{ + using namespace Global; + using namespace Event; + using namespace Time; + using namespace Bullet; + + PlayerController::PlayerController() + { + player_view = new PlayerView(); + player_model = new PlayerModel(); + } + + PlayerController::~PlayerController() + { + delete (player_view); + delete (player_model); + } + //the controller is responsible for calling the lifecycle methods for the other two + void PlayerController::initialize() + { + player_model->initialize(); + + //This will give an error right now since we haven't included the controller in the view. + player_view->initialize(this); // 'this' refers to the class we are currently inside + } + + void PlayerController::update() + { + processPlayerInput(); + player_view->update(); // we update() the view + } + + void PlayerController::render() + { + player_view->render(); // render the view + } + + sf::Vector2f PlayerController::getPlayerPosition() + { + return player_model->getPlayerPosition(); + } + + void PlayerController::processPlayerInput() + { + + EventService* event_service = ServiceLocator::getInstance()->getEventService(); + + if (event_service->pressedLeftKey() || event_service->pressedAKey()) + { + moveLeft(); + } + + if (event_service->pressedRightKey() || event_service->pressedDKey()) + { + moveRight(); + } + + if (event_service->pressedLeftMouseButton()) + { + fireBullet(); + } + } + + void PlayerController::moveLeft() + { + sf::Vector2f currentPosition = player_model->getPlayerPosition(); + currentPosition.x -= player_model->player_movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + currentPosition.x = std::max(currentPosition.x, player_model->left_most_position.x); + player_model->setPlayerPosition(currentPosition); + } + + void PlayerController::moveRight() + { + sf::Vector2f currentPosition = player_model->getPlayerPosition(); + currentPosition.x += player_model->player_movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); + + currentPosition.x = std::min(currentPosition.x, player_model->right_most_position.x); + player_model->setPlayerPosition(currentPosition); + } + + void PlayerController::fireBullet() + { + ServiceLocator::getInstance()->getBulletService()->spawnBullet(BulletType::LASER_BULLET, + player_model->getPlayerPosition() + player_model->barrel_position_offset, + Bullet::MovementDirection::UP); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Player/PlayerModel.cpp b/Space-Invaders/Source/Player/PlayerModel.cpp new file mode 100644 index 000000000..3f519eb06 --- /dev/null +++ b/Space-Invaders/Source/Player/PlayerModel.cpp @@ -0,0 +1,48 @@ +#include "../../Header/Player/PlayerModel.h" + +namespace Player +{ + PlayerModel::PlayerModel() { } + + PlayerModel::~PlayerModel() { } + + void PlayerModel::initialize() { reset(); } // remember to call reset() + + void PlayerModel::reset() + { + player_state = PlayerState::ALIVE; // set state to alive + player_position = initial_player_position; + player_score = 0; + } + + sf::Vector2f PlayerModel::getPlayerPosition() + { + return player_position; + } + + void PlayerModel::setPlayerPosition(sf::Vector2f position) + { + player_position = position; + } + + int PlayerModel::getPlayerScore() + { + return player_score; + } + + void PlayerModel::setPlayerScore(int score) + { + player_score = score; + } + + //.. + PlayerState PlayerModel::getPlayerState() + { + return player_state; + } + + void PlayerModel::setPlayerState(PlayerState state) + { + player_state = state; + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Player/PlayerService.cpp b/Space-Invaders/Source/Player/PlayerService.cpp new file mode 100644 index 000000000..e5ccd9d05 --- /dev/null +++ b/Space-Invaders/Source/Player/PlayerService.cpp @@ -0,0 +1,30 @@ +#include "../../Header/Player/PlayerService.h" +#include "../../Header/Player/PlayerController.h" + +namespace Player +{ + PlayerService::PlayerService() + { + player_controller = new PlayerController(); + } + + PlayerService::~PlayerService() + { + delete (player_controller); + } + + void PlayerService::initialize() + { + player_controller->initialize(); + } + + void PlayerService::update() + { + player_controller->update(); + } + + void PlayerService::render() + { + player_controller->render(); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Player/PlayerView.cpp b/Space-Invaders/Source/Player/PlayerView.cpp new file mode 100644 index 000000000..96e287e72 --- /dev/null +++ b/Space-Invaders/Source/Player/PlayerView.cpp @@ -0,0 +1,55 @@ +#include "../../Header/Player/PlayerView.h" +#include "../../Header/Global/ServiceLocator.h" +#include "../../Header/Global/Config.h" + +namespace Player +{ + using namespace Global; + PlayerView::PlayerView() { } + + PlayerView::~PlayerView() { } + + void PlayerView::initialize() + { + + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializePlayerSprite(); + } + + void PlayerView::initialize(PlayerController* controller) + { + player_controller = controller; //to later use it for setting position + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializePlayerSprite(); + } + + void PlayerView::initializePlayerSprite() + { + if (player_texture.loadFromFile(Config::player_texture_path)) + { + player_sprite.setTexture(player_texture); + scalePlayerSprite(); + } + } + + void PlayerView::scalePlayerSprite() + { + // setScale is an inbuilt method of the sprite class that takes two floats to scale the sprite. it scales the sprite to our desired height + player_sprite.setScale( + //Here we find the factor to scale our sprites with. Ignore the static_cast for now, we will discuss it later. + static_cast(player_sprite_width) / player_sprite.getTexture()->getSize().x, + static_cast(player_sprite_height) / player_sprite.getTexture()->getSize().y + ); + } + + void PlayerView::update() + { + //set the updated position before we render + player_sprite.setPosition(player_controller->getPlayerPosition()); + } + + void PlayerView::render() + { + game_window->draw(player_sprite); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Sound/SoundService.cpp b/Space-Invaders/Source/Sound/SoundService.cpp new file mode 100644 index 000000000..2db4a00bd --- /dev/null +++ b/Space-Invaders/Source/Sound/SoundService.cpp @@ -0,0 +1,50 @@ +#include "../../header/Sound/SoundService.h" +#include "../../header/Global/Config.h" + +namespace Sound +{ + using namespace Global; + + void SoundService::initialize() + { + loadBackgroundMusicFromFile(); + loadSoundFromFile(); + } + + void SoundService::loadBackgroundMusicFromFile() + { + if (!background_music.openFromFile(Config::background_music_path)) + { + printf("Error loading background music file"); + } + } + + void SoundService::loadSoundFromFile() + { + if (!buffer_button_click.loadFromFile(Config::button_click_sound_path)) + { + printf("Error loading background music file"); + } + } + + void SoundService::playSound(SoundType soundType) + { + switch (soundType) + { + case SoundType::BUTTON_CLICK: + sound_effect.setBuffer(buffer_button_click); + break; + default: + printf("Invalid sound type"); + return; + } + sound_effect.play(); + } + + void SoundService::playBackgroundMusic() + { + background_music.setLoop(true); + background_music.setVolume(background_music_volume); + background_music.play(); + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/Time/TimeService.cpp b/Space-Invaders/Source/Time/TimeService.cpp new file mode 100644 index 000000000..718d1fa8c --- /dev/null +++ b/Space-Invaders/Source/Time/TimeService.cpp @@ -0,0 +1,42 @@ +#include "../../Header/Time/TimeService.h" + +namespace Time +{ + void TimeService::initialize() + { + previous_time = std::chrono::steady_clock::now(); + delta_time = 0; + } + + void TimeService::update() + { + updateDeltaTime(); + } + + float TimeService::getDeltaTime() + { + return delta_time; + } + + void TimeService::updateDeltaTime() + { + delta_time = calculateDeltaTime(); + updatePreviousTime(); + } + + float TimeService::calculateDeltaTime() + { + // Calculate time difference in microseconds between the current and previous frame. + int delta = std::chrono::duration_cast( + std::chrono::steady_clock::now() - previous_time).count(); + + // The cast is used to convert delta time from microseconds into seconds. + return static_cast(delta) / static_cast(1000000); + } + + // Update previous_time to the current time + void TimeService::updatePreviousTime() + { + previous_time = std::chrono::steady_clock::now(); + } +} diff --git a/Space-Invaders/Source/UI/MainMenu/MainMenuUIController.cpp b/Space-Invaders/Source/UI/MainMenu/MainMenuUIController.cpp new file mode 100644 index 000000000..4e2a876f6 --- /dev/null +++ b/Space-Invaders/Source/UI/MainMenu/MainMenuUIController.cpp @@ -0,0 +1,136 @@ +#include "../../Header/UI/MainMenu/MainMenuUIController.h" +#include "../../Header/UI/MainMenu/MainMenuUIController.h" +#include "../../Header/Main/GameService.h" +#include "../../Header/Global/ServiceLocator.h" +#include "../../Header/Graphic/GraphicService.h" +#include "../../Header/Global/Config.h" + +namespace UI +{ + namespace MainMenu //nested namespace since everything in MainMenu exists inside UI + { + using namespace Global; + using namespace Main; + using namespace Graphics; + using namespace Event; + using namespace Sound; + + MainMenuUIController::MainMenuUIController() { game_window = nullptr; } + + void MainMenuUIController::initialize() + { + game_window = Global::ServiceLocator::getInstance()->getGraphicService()->getGameWindow();// added global to access + initializeBackgroundImage(); + initializeButtons(); + } + + void MainMenuUIController::initializeBackgroundImage() + { //check if a texture loaded properly + if (background_texture.loadFromFile(Config::background_texture_path)) + { //if it did then set the bg image and scale it + background_sprite.setTexture(background_texture); + scaleBackgroundImage(); + } + } + + void MainMenuUIController::scaleBackgroundImage() + { + background_sprite.setScale( + static_cast(game_window->getSize().x) / background_sprite.getTexture()->getSize().x, + static_cast(game_window->getSize().y) / background_sprite.getTexture()->getSize().y + ); + } + + void MainMenuUIController::initializeButtons() + { + // check if the tectures loaded + if (loadButtonTexturesFromFile()) + { + // order of function calls matter + setButtonSprites(); + scaleAllButttons(); + positionButtons(); + } + } + // only returns true if all tectures are loaded + bool MainMenuUIController::loadButtonTexturesFromFile() + { + return play_button_texture.loadFromFile(Config::play_button_texture_path) && + instructions_button_texture.loadFromFile(Config::instructions_button_texture_path) && + quit_button_texture.loadFromFile(Config::quit_button_texture_path); + } + + void MainMenuUIController::setButtonSprites() + { + play_button_sprite.setTexture(play_button_texture); + instructions_button_sprite.setTexture(instructions_button_texture); + quit_button_sprite.setTexture(quit_button_texture); + } + + + void MainMenuUIController::scaleAllButttons() + { + scaleButton(&play_button_sprite); + scaleButton(&instructions_button_sprite); + scaleButton(&quit_button_sprite); + } + + void MainMenuUIController::scaleButton(sf::Sprite* button_to_scale) + { + button_to_scale->setScale( + button_width / button_to_scale->getTexture()->getSize().x, + button_height / button_to_scale->getTexture()->getSize().y + ); + } + + void MainMenuUIController::positionButtons() + { + float x_position = (static_cast(game_window->getSize().x) / 2) - button_width / 2; + + play_button_sprite.setPosition({ x_position, 500.f }); + instructions_button_sprite.setPosition({ x_position, 700.f }); + quit_button_sprite.setPosition({ x_position, 900.f }); + } + + void MainMenuUIController::processButtonInteractions() + { + sf::Vector2f mouse_position = sf::Vector2f(sf::Mouse::getPosition(*game_window)); + + if (clickedButton(&play_button_sprite, mouse_position)) + { + Global::ServiceLocator::getInstance()->getSoundService()->playSound(SoundType::BUTTON_CLICK); //play button sound + Global::ServiceLocator::getInstance()->getSoundService()->playBackgroundMusic(); //play background music + GameService::setGameState(GameState::GAMEPLAY); + } + + if (clickedButton(&instructions_button_sprite, mouse_position)) + { + printf("Clicked Instruction Button \\n"); + } + + if (clickedButton(&quit_button_sprite, mouse_position)) + { + game_window->close(); + } + } + + bool MainMenuUIController::clickedButton(sf::Sprite* button_sprite, sf::Vector2f mouse_position) + { + EventService* event_service = Global::ServiceLocator::getInstance()->getEventService(); + return event_service->pressedLeftMouseButton() && button_sprite->getGlobalBounds().contains(mouse_position); + } + + void MainMenuUIController::update() + { + processButtonInteractions(); + } + + void MainMenuUIController::render() + { + game_window->draw(background_sprite); + game_window->draw(play_button_sprite); + game_window->draw(instructions_button_sprite); + game_window->draw(quit_button_sprite); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/Source/UI/UIService.cpp b/Space-Invaders/Source/UI/UIService.cpp new file mode 100644 index 000000000..3e60dec73 --- /dev/null +++ b/Space-Invaders/Source/UI/UIService.cpp @@ -0,0 +1,61 @@ +#include "../../Header/UI/UIService.h" +#include "../../Header/Main/GameService.h" + +namespace UI +{ + using namespace Main; + using namespace MainMenu; + + UIService::UIService() + { + main_menu_controller = nullptr; + + createControllers(); + } + + void UIService::createControllers() + { + main_menu_controller = new MainMenuUIController(); + } + + UIService::~UIService() + { + destroy(); + } + + void UIService::initialize() + { + initializeControllers(); + + } + + void UIService::update() + { + switch (GameService::getGameState()) + { + case GameState::MAIN_MENU: + return main_menu_controller->update();; + break; + } + } + + void UIService::render() + { + switch (GameService::getGameState()) + { + case GameState::MAIN_MENU: + return main_menu_controller->render(); + break; + } + } + + void UIService::initializeControllers() + { + main_menu_controller->initialize(); + } + + void UIService::destroy() + { + delete(main_menu_controller); + } +} \ No newline at end of file diff --git a/Space-Invaders/Space-Invaders.vcxproj b/Space-Invaders/Space-Invaders.vcxproj index 6f7fa388d..3dd5235bd 100644 --- a/Space-Invaders/Space-Invaders.vcxproj +++ b/Space-Invaders/Space-Invaders.vcxproj @@ -1,140 +1,160 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 17.0 - Win32Proj - {ab3664cd-9870-4359-8811-b481db3b55a0} - SpaceInvaders - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)sfml\include;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)sfml\lib;%(AdditionalLibraryDirectories) - sfml-graphics-d.lib;sfml-window-d.lib;sfml-network-d.lib;sfml-audio-d.lib;sfml-system-d.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)sfml\include;%(AdditionalIncludeDirectories) - - - Console - true - true - true - $(SolutionDir)sfml\lib;%(AdditionalLibraryDirectories) - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {ab3664cd-9870-4359-8811-b481db3b55a0} + SpaceInvaders + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)sfml\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)sfml\lib;%(AdditionalLibraryDirectories) + sfml-graphics-d.lib;sfml-window-d.lib;sfml-network-d.lib;sfml-audio-d.lib;sfml-system-d.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)sfml\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + $(SolutionDir)sfml\lib;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Space-Invaders/Space-Invaders.vcxproj.filters b/Space-Invaders/Space-Invaders.vcxproj.filters index ce0c35ccf..8ae369c39 100644 --- a/Space-Invaders/Space-Invaders.vcxproj.filters +++ b/Space-Invaders/Space-Invaders.vcxproj.filters @@ -1,22 +1,78 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + \ No newline at end of file diff --git a/Space-Invaders/Space-Invaders.vcxproj.user b/Space-Invaders/Space-Invaders.vcxproj.user index 966b4ffb6..429333de9 100644 --- a/Space-Invaders/Space-Invaders.vcxproj.user +++ b/Space-Invaders/Space-Invaders.vcxproj.user @@ -1,6 +1,6 @@ - - - - true - + + + + true + \ No newline at end of file diff --git a/Space-Invaders/main.cpp b/Space-Invaders/main.cpp index 7d5f90dff..db819e86b 100644 --- a/Space-Invaders/main.cpp +++ b/Space-Invaders/main.cpp @@ -1,5 +1,17 @@ - -int main() -{ - return 0; -} \ No newline at end of file +#include "../../header/Main/GameService.h" + +int main() +{ + using namespace Main; + + GameService* game_service = new GameService(); + game_service->ignite(); + + while (game_service->isRunning()) + { + game_service->update(); + game_service->render(); + } + + return 0; +}