diff --git a/Space-Invaders/Headers/EVENT/EventService.h b/Space-Invaders/Headers/EVENT/EventService.h new file mode 100644 index 000000000..7da3d125e --- /dev/null +++ b/Space-Invaders/Headers/EVENT/EventService.h @@ -0,0 +1,60 @@ +#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 + + + 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; + + //....some other code + 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(); + bool pressedRightKey(); + bool leftmousebutton(); + bool rightmousebutton(); + + bool pressedLeftMouseButton(); + bool pressedRightMouseButton(); + + bool pressedAKey(); + bool pressedDKey(); + + }; +} \ No newline at end of file diff --git a/Space-Invaders/Headers/Global/ServiceLocator.h b/Space-Invaders/Headers/Global/ServiceLocator.h new file mode 100644 index 000000000..a1f61be32 --- /dev/null +++ b/Space-Invaders/Headers/Global/ServiceLocator.h @@ -0,0 +1,47 @@ +#pragma once + +#include"../Graphic/GraphicService.h" +#include"../EVENT/EventService.h" +#include"../player/PlayerService.h" +#include"../TIME/TimeService .h" +#include"../../UI/UISERVICE.h" +namespace Global { + using namespace player; + using namespace Graphic; + using namespace event; + using namespace UI; + + class ServiceLocator + { + private: + // Private Attributes: + GraphicService* graphic_service; + EventService* event_service; + PlayerService* player_service; + TimeService* time_Service; + UiService* ui_service; + + // Private Constructor and Destructor: + ServiceLocator(); + // Constructor for initializing the ServiceLocator. + ~ServiceLocator(); // Destructor for cleaning up resources upon object deletion. + + // Private Methods: + void createServices(); // Creates instances of all services. + void clearAllServices(); // Deletes and deallocates memory for all services. + + public: + // Public Methods: + static ServiceLocator* getInstance(); // Provides a method to access the unique ServiceLocator instance (object). + void initialize(); // Initializes the ServiceLocator. + void update(); // Updates all services. + void render(); // Renders using the services. + + // Methods to Get Specific Services: + GraphicService* getGraphicService(); + EventService* getEventService(); + PlayerService* getplayerservice(); + TimeService* gettimeservice(); + UiService* getUiservice(); + }; +} \ No newline at end of file diff --git a/Space-Invaders/Headers/Graphic/GraphicService.h b/Space-Invaders/Headers/Graphic/GraphicService.h new file mode 100644 index 000000000..fc8491480 --- /dev/null +++ b/Space-Invaders/Headers/Graphic/GraphicService.h @@ -0,0 +1,44 @@ + +#pragma once + +#include +namespace Graphic { + + class GraphicService + { + private: + + + const std::string game_window_title = "Outscal Presents - Alien Invader"; + + const int game_window_width = 1920; + const int game_window_height = 1080; + + const sf::Color window_color = sf::Color::Blue; + + const int framerate = 60; + + 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/Headers/TIME/TimeService .h b/Space-Invaders/Headers/TIME/TimeService .h new file mode 100644 index 000000000..2a4183d17 --- /dev/null +++ b/Space-Invaders/Headers/TIME/TimeService .h @@ -0,0 +1,23 @@ +#pragma once +//Capture the current time at the beginning of a frame +//Capture the current time again at the beginning of the next frame +//Calculate the delta time by subtracting the previous frame's start time from the current frame's start time. +//Update the current frame's start time to become the previous frame's start time so as to prepare for the next frame. +#include + +class TimeService { +private: + std::chrono::time_point previous_time; + + float delta_time;//to store the value of delta time + float calculate_delta_time();//calculate time by subtracting the previous time from the current time + void updatePreviousTime(); // finally update the current time to be previous time + void updateDeltaTime(); +public: + void update(); + void intialize(); + float getdeltatime(); + + + +}; diff --git a/Space-Invaders/Headers/main/GameService.h b/Space-Invaders/Headers/main/GameService.h new file mode 100644 index 000000000..8850e9ade --- /dev/null +++ b/Space-Invaders/Headers/main/GameService.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include"../Global/ServiceLocator.h" +enum class GameState //create the enum +{ + BOOT, + MAIN_MENU, + GAMEPLAY, +}; + + + + +namespace Main { + + using namespace Global; + + class GameService + { + private: + + + static GameState current_state; + + ServiceLocator* service_locator; + sf::RenderWindow* game_window; + + void initialize(); + void initializeVariables();// Handles game initialization. + void destroy(); // Handles cleanup tasks. + + 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(); + + void showmainmenu(); + + + }; +} \ No newline at end of file diff --git a/Space-Invaders/Headers/player/PlayerController.h b/Space-Invaders/Headers/player/PlayerController.h new file mode 100644 index 000000000..9406c7c23 --- /dev/null +++ b/Space-Invaders/Headers/player/PlayerController.h @@ -0,0 +1,35 @@ +#pragma once +#include +namespace player { + + enum class PlayerState; + class PlayerView; + class PlayerModel; + + class PlayerController { + + private: + + + + void processinput(); + void processmoveleft(); + void processmoveright(); + public: + + PlayerModel* model; + PlayerView* view; + PlayerController(); + ~PlayerController(); + void intialize(); + void update(); + void render(); + + + + + sf::Vector2f getPlayerPosition(); + + }; + +} \ No newline at end of file diff --git a/Space-Invaders/Headers/player/PlayerModel.h b/Space-Invaders/Headers/player/PlayerModel.h new file mode 100644 index 000000000..eb54839b4 --- /dev/null +++ b/Space-Invaders/Headers/player/PlayerModel.h @@ -0,0 +1,58 @@ +#pragma once +#include +class PlayerView; +class PlayerModel; + +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); //new var + sf::Vector2f player_position; //new var + PlayerState player_state; + PlayerModel* model; + PlayerView* view; + int player_score = 0; + + + 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 float player_movement_speed = 350.0f; + + PlayerModel(); + ~PlayerModel(); + + void initialize(); + + void reset(); //new method + + + + + //getters and setters + sf::Vector2f getPlayerPosition(); + void setPlayerPosition(sf::Vector2f position); + + PlayerState getplayerstate(); + + + void setplayerstate(PlayerState state); + + + + }; +} \ No newline at end of file diff --git a/Space-Invaders/Headers/player/PlayerService.h b/Space-Invaders/Headers/player/PlayerService.h new file mode 100644 index 000000000..e8620c5f4 --- /dev/null +++ b/Space-Invaders/Headers/player/PlayerService.h @@ -0,0 +1,58 @@ +#pragma once +#include" +#include"../TIME/TimeService .h" +#include"../player/PlayerController.h" + + +namespace player { + class PlayerService + { + + + + private: + + + + int health = 3; + sf::Vector2f position = sf::Vector2f(200.0f, 100.0f); + float movement_speed = 5.0f; + int player_score = 0; + const sf::Vector2f initial_player_position = sf::Vector2f(950.f, 950.f); + + const sf::String player_texture_path = "assets/textures/player_ship.png"; + + sf::Texture player_texture; + sf::Sprite player_sprite; + + sf::RenderWindow* game_window; //as always + + void initializePlayerSprite(); + void processPlayerInput(); + + PlayerController* player_controller; + + + 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 float player_movement_speed = 350.0f; + + + PlayerService(); + ~PlayerService(); + + void initialize(); + void update(); + void render(); + + void moveLef(); + void moveRight(); + int getMoveSpeed(); + sf::Vector2f getPlayerPosition(); + + }; +} \ No newline at end of file diff --git a/Space-Invaders/Headers/player/PlayerView.h b/Space-Invaders/Headers/player/PlayerView.h new file mode 100644 index 000000000..cba5f3eba --- /dev/null +++ b/Space-Invaders/Headers/player/PlayerView.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include"../player/PlayerController.h" + + class PlayerController; + 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; + + public: + PlayerView(); + ~PlayerView(); + + void initialize(PlayerController* player_controller); + void update(); + void render(); + }; + } \ No newline at end of file diff --git a/Space-Invaders/Space-Invaders.vcxproj b/Space-Invaders/Space-Invaders.vcxproj index 6f7fa388d..6d436d8bf 100644 --- a/Space-Invaders/Space-Invaders.vcxproj +++ b/Space-Invaders/Space-Invaders.vcxproj @@ -1,4 +1,4 @@ - + @@ -132,7 +132,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Space-Invaders/Space-Invaders.vcxproj.filters b/Space-Invaders/Space-Invaders.vcxproj.filters index ce0c35ccf..31167764f 100644 --- a/Space-Invaders/Space-Invaders.vcxproj.filters +++ b/Space-Invaders/Space-Invaders.vcxproj.filters @@ -18,5 +18,61 @@ 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/UI/MainMenu/MainMenuUIController.cpp b/Space-Invaders/UI/MainMenu/MainMenuUIController.cpp new file mode 100644 index 000000000..e7fbf934c --- /dev/null +++ b/Space-Invaders/UI/MainMenu/MainMenuUIController.cpp @@ -0,0 +1,135 @@ +#include "MainMenuUIController.h" +#include"../../Headers/main/GameService.h" +#include"../../Headers/Global/ServiceLocator.h" +#include"../../Headers/Graphic/GraphicService.h" +namespace UI { + + namespace MainMenu { + + using namespace Global; + using namespace Main; + using namespace Graphic; + using namespace event; + + void MainMenuUI::initializeBackgroundImage() + { + if (background_texture.loadFromFile(background_texture_path)) + { + background_sprite.setTexture(background_texture); + scaleBackgroundImage(); + } + } + + void MainMenuUI::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 MainMenuUI::initializeButtons() + { + if (loadButtonTexturesFromFile()) + { + // order of function calls matter + setButtonSprites(); + scaleAllButttons(); + positionButtons(); + } + } + + bool MainMenuUI::loadButtonTexturesFromFile() + { + return play_button_texture.loadFromFile(play_button_texture_path) + && instructions_button_texture.loadFromFile(instructions_button_texture_path) + && quit_button_texture.loadFromFile(quit_button_texture_path); + } + + void MainMenuUI::setButtonSprites() + { + play_button_sprite.setTexture(play_button_texture); + instructions_button_sprite.setTexture(instructions_button_texture); + quit_button_sprite.setTexture(quit_button_texture); + } + + void MainMenuUI::scaleAllButttons() + { + scaleButton(&play_button_sprite); + scaleButton(&instructions_button_sprite); + scaleButton(&quit_button_sprite); + } + + void MainMenuUI::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 MainMenuUI::positionButtons() + { + float xposition = (static_cast(game_window->getSize().x) / 2) - button_width / 2; + play_button_sprite.setPosition(xposition, 500); + instructions_button_sprite.setPosition(xposition,700); + quit_button_sprite.setPosition(xposition, 900); + } + + UI::MainMenu::MainMenuUI::MainMenuUI() + { + game_window = nullptr; + } + + UI::MainMenu::MainMenuUI::~MainMenuUI() + { + + } + + void UI::MainMenu::MainMenuUI::intialize() + { + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializeButtons(); + initializeBackgroundImage(); + + } + + void UI::MainMenu::MainMenuUI::update() + { + processButtonInteractions(); + + } + + void UI::MainMenu::MainMenuUI::render() + { + + game_window->draw(background_sprite); + game_window->draw(play_button_sprite); + game_window->draw(instructions_button_sprite); + game_window->draw(quit_button_sprite); + } + void MainMenuUI::processButtonInteractions() + { + sf::Vector2f mouse_position = sf::Vector2f(sf::Mouse::getPosition(*game_window)); + if (clickedButton(&play_button_sprite, mouse_position)) { + 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 MainMenuUI::clickedButton(sf::Sprite* button_sprite, sf::Vector2f mouse_position) + { + + EventService* event_service = ServiceLocator::getInstance()->getEventService(); + return event_service->pressedLeftMouseButton() && button_sprite->getGlobalBounds().contains(mouse_position); + } + } +} \ No newline at end of file diff --git a/Space-Invaders/UI/MainMenu/MainMenuUIController.h b/Space-Invaders/UI/MainMenu/MainMenuUIController.h new file mode 100644 index 000000000..3ed4df406 --- /dev/null +++ b/Space-Invaders/UI/MainMenu/MainMenuUIController.h @@ -0,0 +1,62 @@ +#pragma once +#include +namespace UI { + namespace MainMenu { + class MainMenuUI { + + private: + sf::RenderWindow* game_window; + const float button_height = 200.f; + const float button_width = 200.f; + + 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"; + + 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; + + void initializeBackgroundImage(); + void scaleBackgroundImage(); + + + void initializeButtons(); + bool loadButtonTexturesFromFile(); + void setButtonSprites(); + + void scaleAllButttons(); + void scaleButton(sf::Sprite* button_to_scale); + void positionButtons(); + + + + + public: + MainMenuUI(); + ~MainMenuUI(); + + + + + + void intialize(); + void update(); + void render(); + + + void processButtonInteractions(); + bool clickedButton(sf::Sprite* button_sprite, sf::Vector2f mouse_position); + +}; +} +} \ No newline at end of file diff --git a/Space-Invaders/UI/UISERVICE.cpp b/Space-Invaders/UI/UISERVICE.cpp new file mode 100644 index 000000000..158fc78c2 --- /dev/null +++ b/Space-Invaders/UI/UISERVICE.cpp @@ -0,0 +1,65 @@ +#include "UISERVICE.h" +#include"../../Headers/main/GameService.h" +namespace UI { + using namespace Main; + using namespace MainMenu; + void UI::UiService::createControllers() + { + main_menu_controller = new MainMenuUI(); + } + + void UI::UiService::intializecontrollers() + { + main_menu_controller->intialize(); + } + + void UI::UiService::destroycontrollers() + { + delete(main_menu_controller); + } + + UI::UiService::UiService() + { + main_menu_controller = nullptr; + createControllers(); + } + + UI::UiService::~UiService() + { + destroycontrollers(); + } + + void UI::UiService::intialize() + { + + + + main_menu_controller->intialize(); + intializecontrollers(); + + + + } + + void UI::UiService::update() + { + switch (GameService::getGameState()) + { + case GameState::MAIN_MENU: + return main_menu_controller->update(); + break; + } + } + + void UI::UiService::render() + { + + + switch (GameService::getGameState()) + { + case GameState::MAIN_MENU: + return main_menu_controller->render(); + break; + } + } +} \ No newline at end of file diff --git a/Space-Invaders/UI/UISERVICE.h b/Space-Invaders/UI/UISERVICE.h new file mode 100644 index 000000000..aefc88036 --- /dev/null +++ b/Space-Invaders/UI/UISERVICE.h @@ -0,0 +1,19 @@ +#pragma once +#include"../../UI/MainMenu/MainMenuUIController.h" +namespace UI { + class UiService { + + private: + void createControllers(); + void intializecontrollers(); + void destroycontrollers(); + MainMenu::MainMenuUI* main_menu_controller; + public: + UiService(); + ~UiService(); + void intialize(); + void update(); + void render(); + }; + +} \ No newline at end of file diff --git a/Space-Invaders/main.cpp b/Space-Invaders/main.cpp index 7d5f90dff..a7a0b06f7 100644 --- a/Space-Invaders/main.cpp +++ b/Space-Invaders/main.cpp @@ -1,5 +1,21 @@ - +#include"../Space-Invaders/Headers/main/GameService.h" +using namespace Main; int main() { + + GameService* game_service = new GameService(); + + game_service->ignite(); + + while (game_service->isRunning()) + { + game_service->update(); + game_service->render(); + + + + + } return 0; -} \ No newline at end of file +} + diff --git a/Space-Invaders/source/EventService.cpp b/Space-Invaders/source/EventService.cpp new file mode 100644 index 000000000..70f1de3f7 --- /dev/null +++ b/Space-Invaders/source/EventService.cpp @@ -0,0 +1,146 @@ +//#include"ServiceLocator.h" +//#include"GraphicService.h" +//#include"EventService.h" + +#include"../Headers/main/GameService.h" +#include"../Headers/Global/ServiceLocator.h" +#include"../Headers/EVENT/EventService.h" + + +namespace event { + + using namespace Global; + using namespace Graphic; + using namespace event; + + 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; + } + + } + + EventService::EventService() { game_window = nullptr; } + + EventService::~EventService() = default; //calls the default destructor + + 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(); + } + } + } + } + + 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; } + + bool EventService::pressedLeftKey() { return game_event.key.code == sf::Keyboard::Left; } + bool EventService::pressedRightKey() { return game_event.key.code == sf::Keyboard::Right; } + + bool EventService::leftmousebutton() + { + return game_event.type == sf::Event::MouseButtonPressed && game_event.mouseButton.button == sf::Mouse::Left; + } + + bool EventService::rightmousebutton() + { + return game_event.type==sf::Event::MouseButtonPressed && game_event.mouseButton.button == sf::Mouse::Right; + } + + bool EventService::pressedLeftMouseButton() + { + 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; + } + bool EventService::pressedAKey() + { + return A_button_state == ButtonState::HELD; + } + bool EventService::pressedDKey() + { + return D_button_state == ButtonState::HELD; + } + } + + + diff --git a/Space-Invaders/source/GameService.cpp b/Space-Invaders/source/GameService.cpp new file mode 100644 index 000000000..390341aec --- /dev/null +++ b/Space-Invaders/source/GameService.cpp @@ -0,0 +1,88 @@ +//#include "GameService.h" +//#include"GraphicService.h" +#include"../Headers/Graphic/GraphicService.h" +#include"../Headers/Global/ServiceLocator.h" +#include"../Headers/main/GameService.h" + + + +namespace Main { + using namespace Global; + using namespace event; + using namespace Graphic; + + + GameState GameService::current_state = GameState::BOOT; + + 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 = ServiceLocator::getInstance(); // Get ServiceLocator + initialize(); // Initialize services. + } + + //initialize service locator and other variables + void GameService::initialize() + { + service_locator->initialize(); + initializeVariables(); + 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. + } + + // 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(); + } + + + void GameService::setGameState(GameState new_state) { current_state = new_state; } + + GameState GameService::getGameState() { return current_state; } + void GameService::showmainmenu() + { + setGameState(GameState::MAIN_MENU); + + + } +} + + + + + diff --git a/Space-Invaders/source/GraphicService.cpp b/Space-Invaders/source/GraphicService.cpp new file mode 100644 index 000000000..f435a8a0b --- /dev/null +++ b/Space-Invaders/source/GraphicService.cpp @@ -0,0 +1,71 @@ +//#include"ServiceLocator.h" +//#include"GraphicService.h" +#include"../Headers/Global/ServiceLocator.h" +#include"../Headers/Graphic/GraphicService.h" + +namespace Graphic { + + // 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 to the game_window pointer + + game_window->setFramerateLimit(framerate); + } + + + // 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/PlayerController.cpp b/Space-Invaders/source/PlayerController.cpp new file mode 100644 index 000000000..e27a1ee91 --- /dev/null +++ b/Space-Invaders/source/PlayerController.cpp @@ -0,0 +1,81 @@ +#include"../Headers/player/PlayerController.h" +#include"../Headers//EVENT/EventService.h" +#include"../Headers/Global/ServiceLocator.h" +#include"../Headers/player/PlayerModel.h" +#include"../Headers//player/PlayerView.h" +#include +namespace player{ + using namespace Global; + void PlayerController::processinput() + { + EventService* event_service = ServiceLocator::getInstance()->getEventService(); + + if (event_service->pressedLeftKey() || event_service->pressedAKey()) + { + processmoveleft(); + } + + if (event_service->pressedRightKey() || event_service->pressedDKey()) + { + processmoveright(); + } + + + + + } + + void PlayerController::processmoveleft() + { + + sf::Vector2f current_position = model->getPlayerPosition(); + current_position.x -= model->player_movement_speed * ServiceLocator::getInstance()->gettimeservice()->getdeltatime(); + current_position.x = std::max(current_position.x, model->left_most_position.x); + model->setPlayerPosition(current_position); + } + + + void PlayerController::processmoveright() + { + sf::Vector2f current_position = model->getPlayerPosition(); + current_position.x += model->player_movement_speed * ServiceLocator::getInstance()->gettimeservice()->getdeltatime(); + current_position.x = std::min(current_position.x, model->right_most_position.x); + model->setPlayerPosition(current_position); + + } + + PlayerController::PlayerController() + { + + model = new PlayerModel(); + view = new PlayerView(); + } + + PlayerController::~PlayerController() + { + delete (view); + delete (model); + } + + void PlayerController::intialize() + { + model->initialize(); + view->initialize(this); + } + + void PlayerController::update() + { + processinput(); + view->update(); + } + + void PlayerController::render() + { + view->render(); + } + + sf::Vector2f PlayerController::getPlayerPosition() + { + return model->getPlayerPosition(); + } +} diff --git a/Space-Invaders/source/PlayerModel.cpp b/Space-Invaders/source/PlayerModel.cpp new file mode 100644 index 000000000..0218d5e85 --- /dev/null +++ b/Space-Invaders/source/PlayerModel.cpp @@ -0,0 +1,54 @@ +//#include"PlayerModel.h" +#include"../Headers/player/PlayerModel.h" +namespace player { + + PlayerModel::PlayerModel() { } + + PlayerModel::~PlayerModel() { } + + void PlayerModel::initialize() { reset(); } + + void PlayerModel::reset() + { + + player_state = PlayerState::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; + } + + PlayerState PlayerModel::getplayerstate() + { + return player_state; + } + + void PlayerModel::setplayerstate(PlayerState state) + + { + player_state = state; + + } + +} + + + + + + + + + + + + + diff --git a/Space-Invaders/source/PlayerService.cpp b/Space-Invaders/source/PlayerService.cpp new file mode 100644 index 000000000..6ccda2e3a --- /dev/null +++ b/Space-Invaders/source/PlayerService.cpp @@ -0,0 +1,91 @@ +//#include "../Headers/PlayerService.h" +//#include"../Headers/ServiceLocator.h" +//#include"../Headers/player/PlayerController.h" +#include"../Headers/Global/ServiceLocator.h" +#include"../Headers/player/PlayerService.h" +#include"../Headers/player/PlayerController.h" +#include"../Headers/EVENT/EventService.h" +namespace player { + using namespace event; + using namespace Global; + + + void PlayerService::initializePlayerSprite() + { + if (player_texture.loadFromFile(player_texture_path)) { + player_sprite.setTexture(player_texture); + } + } + + void PlayerService::processPlayerInput() + { + + EventService* checkkey = ServiceLocator::getInstance()->getEventService(); + if (checkkey->isKeyboardEvent()) { + if (checkkey->pressedLeftKey()) { + moveLef(); + } + + if (checkkey->pressedRightKey()) { + moveRight(); + } + } + } + + PlayerService::PlayerService() + { + game_window = nullptr; + player_controller = new PlayerController; + } + + PlayerService::~PlayerService() + { + delete player_controller; + } + + void PlayerService::initialize() + { + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + player_controller->intialize(); + initializePlayerSprite(); + } + + void PlayerService::update() + { + processPlayerInput(); + player_controller->update(); + player_sprite.setPosition(getPlayerPosition()); + } + + void PlayerService::render() + + { + player_controller->render(); + + } + + void PlayerService::moveLef() + { + + position.x -= ServiceLocator::getInstance()->gettimeservice()->getdeltatime(); + } + + void PlayerService::moveRight() + { + + position.x += ServiceLocator::getInstance()->gettimeservice()->getdeltatime(); + } + + + + int PlayerService::getMoveSpeed() + { + return movement_speed; + } + + sf::Vector2f PlayerService::getPlayerPosition() + { + return position; + } + +} \ No newline at end of file diff --git a/Space-Invaders/source/PlayerView.cpp b/Space-Invaders/source/PlayerView.cpp new file mode 100644 index 000000000..c4068235f --- /dev/null +++ b/Space-Invaders/source/PlayerView.cpp @@ -0,0 +1,49 @@ +//#include"PlayerView.h" +//#include"../ServiceLocator.h" +#include"../Headers/player/PlayerView.h" +#include"../Headers/Global/ServiceLocator.h" + +namespace player { + using namespace Global; + + PlayerView::PlayerView() { } + + PlayerView::~PlayerView() { } + + void PlayerView::initialize(PlayerController* controller) + { + + player_controller = controller; + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializePlayerSprite(); + } + + void PlayerView::initializePlayerSprite() + { + if (player_texture.loadFromFile(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() + { + 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/ServiceLocator.cpp b/Space-Invaders/source/ServiceLocator.cpp new file mode 100644 index 000000000..9e21dc4c3 --- /dev/null +++ b/Space-Invaders/source/ServiceLocator.cpp @@ -0,0 +1,110 @@ + +#include"../Headers/Global/ServiceLocator.h" +#include"../Headers/EVENT/EventService.h" +#include"../Headers/player/PlayerService.h" +#include"../Headers/TIME/TimeService .h" +#include"../Headers//Graphic/GraphicService.h" + +namespace Global { + + // Constructor: Initializes the graphic_service pointer to null and creates services. + ServiceLocator::ServiceLocator() { + graphic_service = nullptr;// Initialize graphic_service to null + event_service = nullptr; + player_service = nullptr; + time_Service = nullptr; + ui_service = nullptr; + createServices(); // Call createServices to instantiate services + } + + // Destructor: Cleans up resources by clearing all services. + ServiceLocator::~ServiceLocator() { + clearAllServices(); // Call clearAllServices to delete any allocated services + } + + // Creates service instances, specifically the graphic service in this case. + void ServiceLocator::createServices() { + graphic_service = new GraphicService(); // Dynamically create a GraphicService instance + event_service = new EventService(); + + player_service = new PlayerService(); + time_Service = new TimeService(); + ui_service = new UiService(); + } + + // Deletes allocated services to prevent memory leaks, specifically the graphic service. + void ServiceLocator::clearAllServices() { + delete(graphic_service); // Delete the graphic_service instance + delete(event_service); + delete(player_service); + delete(time_Service); + delete(ui_service); + + } + + // Returns a pointer to ServiceLocator. + ServiceLocator* ServiceLocator::getInstance() { + static ServiceLocator instance; + return &instance; // Return address of the instance + } + + // Calls initialize on the graphic service, readying it for use. + void ServiceLocator::initialize() { + graphic_service->initialize(); // Initialize graphic service + event_service->initialize(); + player_service->initialize(); + time_Service->intialize(); + ui_service->intialize(); + } + + // Updates the state of the graphic service. + void ServiceLocator::update() { + graphic_service->update(); // Update graphic service + event_service->update(); + player_service->update(); + time_Service->update(); + ui_service->update(); + } + + + // Renders using the graphic service. + void ServiceLocator::render() { + + + + graphic_service->render(); // Render graphic service + + // Render graphic service + player_service->render(); + ui_service->render(); + + + + + } + + // Returns a pointer to the currently set graphic service. + 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; + } + + + +} + diff --git a/Space-Invaders/source/TimeService .cpp b/Space-Invaders/source/TimeService .cpp new file mode 100644 index 000000000..7667ed227 --- /dev/null +++ b/Space-Invaders/source/TimeService .cpp @@ -0,0 +1,42 @@ +#include"../Headers/TIME/TimeService .h" + +float TimeService::calculate_delta_time() +{ + // 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. + // We will learn aboit how this works in detail later. + return static_cast(delta) / static_cast(1000000); +} + +void TimeService::updatePreviousTime() +{ + + previous_time = std::chrono::steady_clock::now(); +} + +void TimeService::updateDeltaTime() +{ + delta_time = calculate_delta_time(); + updatePreviousTime(); + +} + +void TimeService::update() +{ + updateDeltaTime(); +} + +void TimeService::intialize() +{ + previous_time = std::chrono::steady_clock::now(); + delta_time = 0; +} + +float TimeService::getdeltatime() +{ + return delta_time; +} +