diff --git a/Header/Event/EventService.h b/Header/Event/EventService.h new file mode 100644 index 000000000..a7c01eb3b --- /dev/null +++ b/Header/Event/EventService.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include + +namespace Event +{ + + 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 + + + + 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(); + + }; +} diff --git a/Header/Global/ServiceLocator.h b/Header/Global/ServiceLocator.h new file mode 100644 index 000000000..0e8f50440 --- /dev/null +++ b/Header/Global/ServiceLocator.h @@ -0,0 +1,45 @@ +#pragma once +#include "../../Header/Graphic/GraphicService.h" +#include "../../Header/Event/EventService.h" +#include "../../Header/Player/PlayerService.h" +#include "../../Header/Time/TimeService.h" + +namespace Global +{ + + class ServiceLocator + { + private: + // Private Attributes: + Graphic::GraphicService* graphic_service; + + Event::EventService* event_service; + + Player::PlayerService* player_service; + + Time::TimeService* time_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: + Graphic::GraphicService* getGraphicService(); + Event::EventService* getEventService(); + Player::PlayerService* getPlayerService(); + Time::TimeService* getTimeService(); + + }; +} \ No newline at end of file diff --git a/Header/Graphic/GraphicService.h b/Header/Graphic/GraphicService.h new file mode 100644 index 000000000..3f75bbb5b --- /dev/null +++ b/Header/Graphic/GraphicService.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +namespace Graphic +{ + + class GraphicService + { + private: + + const std::string game_window_title = "Alien Invader"; + + const int game_window_width = 800; + const int game_window_height = 600; + const int frame_rate = 60; + + const sf::Color window_color = sf::Color::Blue; + + 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 + }; +} diff --git a/Header/Main/GameService.h b/Header/Main/GameService.h new file mode 100644 index 000000000..a47f77e97 --- /dev/null +++ b/Header/Main/GameService.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include "../../Header/Global/ServiceLocator.h" + +namespace Main +{ + using namespace Global; + + class GameService + { + private: + + Global::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. + }; +} \ No newline at end of file diff --git a/Header/Player/PlayerController.h b/Header/Player/PlayerController.h new file mode 100644 index 000000000..cc34d58d4 --- /dev/null +++ b/Header/Player/PlayerController.h @@ -0,0 +1,32 @@ +#pragma once +#include + +enum class PlayerSate; +class PlayerView; +class PlayerModel; + +class PlayerController +{ + +private: + + PlayerView* player_view; + PlayerModel* player_model; + + void processPlayerInput(); + void moveLeft(); + void moveRight(); + +public: + + PlayerController(); + ~PlayerController(); + + void initialize(); + void update(); + void render(); + + sf::Vector2f getPlayerPosition(); + + +}; \ No newline at end of file diff --git a/Header/Player/PlayerModel.h b/Header/Player/PlayerModel.h new file mode 100644 index 000000000..65fc78700 --- /dev/null +++ b/Header/Player/PlayerModel.h @@ -0,0 +1,46 @@ +#pragma once +#include + + +enum class PlayerState //Our Enum +{ + ALIVE, + DEAD, + // we will add more states later +}; + + + +class PlayerModel +{ +private: + + const sf::Vector2f initial_player_position = sf::Vector2f(500.f, 500.f); //new var + sf::Vector2f player_position; //new var + + PlayerState player_state; + + +public: + const sf::Vector2f left_most_position = sf::Vector2f(50.f, 0.f); + const sf::Vector2f right_most_position = sf::Vector2f(700.f, 0.f); + + const float player_movement_speed = 200.0f; + + PlayerModel(); + ~PlayerModel(); + + void initialize(); + + void reset(); //new method + + + //getters and setters + sf::Vector2f getPlayerPosition(); + void setPlayerPosition(sf::Vector2f position); + + //new getter and setter + PlayerState getPlayerState(); + void setPlayerState(PlayerState state); + +}; \ No newline at end of file diff --git a/Header/Player/PlayerService.h b/Header/Player/PlayerService.h new file mode 100644 index 000000000..3a3fc477a --- /dev/null +++ b/Header/Player/PlayerService.h @@ -0,0 +1,23 @@ +#pragma once +#include "../../Header/Player/PlayerController.h" + +namespace Player +{ + + enum class PlayerState; + //class PlayerController; + + class PlayerService + { + private: + PlayerController* player_controller; + + public: + PlayerService(); + ~PlayerService(); + + void initialize(); + void update(); + void render(); + }; +} \ No newline at end of file diff --git a/Header/Player/PlayerView.h b/Header/Player/PlayerView.h new file mode 100644 index 000000000..67fb29928 --- /dev/null +++ b/Header/Player/PlayerView.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "../../Header/Player/PlayerController.h" + + + +class PlayerView +{ +private: + + PlayerController* player_controller; // ptr to player controller + + //player texture path + const sf::String player_texture_path = "assets/textures/player_ship.png"; + + //player sprite and texture + sf::Texture player_texture; + sf::Sprite player_sprite; + + + //player sprite attribute(height & Width)(60, 60) + const int player_sprite_width = 60; + const int player_sprite_height = 60; + + + //ptr to game window for rendering our player + sf::RenderWindow* game_window; + + + //initializePlayerSprite() + void initializePlayerSprite(); + + + //scaleSprite() + void scalePlayerSprite(); + +public: + + //constructor Destructor + PlayerView(); + ~PlayerView(); + + + //initialise, update, render + + void initialize(PlayerController* controller); // we pass a pointer of type controller because we need to use this in the view later. + void update(); + void render(); + + +}; diff --git a/Header/Time/TimeService.h b/Header/Time/TimeService.h new file mode 100644 index 000000000..11b380822 --- /dev/null +++ b/Header/Time/TimeService.h @@ -0,0 +1,36 @@ +#pragma once +#include + +namespace Time +{ + + /* + // The TimeService class helps keep track of time in game and calculate delta time. + // Utilizes the library to calculate delta time. + */ + class TimeService + { + private: + + // A point in time which indicates the starting time of previous frame. + std::chrono::time_point previous_time; + // No need to worry about the syntax of this variable too much right now + // It'll be explained in detail at a later 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/Source/Event/EventServices.cpp b/Source/Event/EventServices.cpp new file mode 100644 index 000000000..0e54c472e --- /dev/null +++ b/Source/Event/EventServices.cpp @@ -0,0 +1,45 @@ +#include "../../Header/Event/EventService.h" +#include "../../Header/Main/GameService.h" +#include "../../Header/Graphic/GraphicService.h" + +namespace Event +{ + using namespace Global; + + EventService::EventService() { game_window = nullptr; } + + EventService::~EventService() = default; //calls the default destructor + void EventService::initialize() + { + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + } + void EventService::update() + { + //for later + } + 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; } +} \ No newline at end of file diff --git a/Source/Global/ServiceLocator.cpp b/Source/Global/ServiceLocator.cpp new file mode 100644 index 000000000..b7f83693f --- /dev/null +++ b/Source/Global/ServiceLocator.cpp @@ -0,0 +1,82 @@ +#include "../../Header/Global/ServiceLocator.h" + +namespace Global +{ + + using namespace Graphic; + using namespace Time; + using namespace Player; + using namespace Event; + + // Constructor: Initializes the graphic_service pointer to null and creates services. + ServiceLocator::ServiceLocator() { + graphic_service = nullptr; // Initialize graphic_service to null + time_service = nullptr; + event_service = nullptr; + player_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 + time_service = new TimeService(); + event_service = new EventService(); + player_service = new PlayerService(); + } + + // Deletes allocated services to prevent memory leaks, specifically the graphic service. + void ServiceLocator::clearAllServices() { + delete(graphic_service); // Delete the graphic_service instance + delete(time_service); + delete(event_service); + delete(player_service); + + graphic_service = nullptr; // Reset pointer to null to avoid dangling pointer + } + + // Returns a pointer to ServiceLocator. + ServiceLocator* ServiceLocator::getInstance() { + static ServiceLocator instance; // we will discuss what 'static' means at a later time. + 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 + time_service->initialize(); + event_service->initialize(); + player_service->initialize(); + } + + // Updates the state of the graphic service. + void ServiceLocator::update() { + graphic_service->update(); // Update graphic service + time_service->update(); + event_service->update(); + player_service->update(); + } + + // Renders using the graphic service. + void ServiceLocator::render() { + graphic_service->render(); // Render graphic service + player_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; } + +} + + + + + diff --git a/Source/Graphic/GraphicService.cpp b/Source/Graphic/GraphicService.cpp new file mode 100644 index 000000000..78181b91e --- /dev/null +++ b/Source/Graphic/GraphicService.cpp @@ -0,0 +1,61 @@ +#include "../../Header/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(); + game_window->setFramerateLimit(frame_rate); + } + + // 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); // 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/Source/Main/GameService.cpp b/Source/Main/GameService.cpp new file mode 100644 index 000000000..a877d4cf4 --- /dev/null +++ b/Source/Main/GameService.cpp @@ -0,0 +1,68 @@ +#include "../../Header/Main/GameService.h" +#include "../../Header/Graphic/GraphicService.h" + +namespace Main +{ + + + // 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 = ServiceLocator::getInstance(); // Get ServiceLocator + initialize(); // Initialize services. + } + + //initialize service locator and other variables + void GameService::initialize() + { + service_locator->initialize(); + initializeVariables(); + } + + 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->update(); // Call update on the service locator which then updates all its managed services + + // Process Events. + service_locator->getEventService()->processEvents(); + + // Update Game Logic. + service_locator->update(); + } + + + // 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(); + } +} \ No newline at end of file diff --git a/Source/Player/PlayerController.cpp b/Source/Player/PlayerController.cpp new file mode 100644 index 000000000..50ba237ab --- /dev/null +++ b/Source/Player/PlayerController.cpp @@ -0,0 +1,85 @@ +#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 + +using namespace Global; + +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() +{ + // we will move this to event service at a later time + if ((sf::Keyboard::isKeyPressed(sf::Keyboard::Left))) + { + moveLeft(); + } + // we will move this to event service at a later time + if ((sf::Keyboard::isKeyPressed(sf::Keyboard::Right))) + { + moveRight(); + } +} + +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); +} \ No newline at end of file diff --git a/Source/Player/PlayerModel.cpp b/Source/Player/PlayerModel.cpp new file mode 100644 index 000000000..6cba1e9b3 --- /dev/null +++ b/Source/Player/PlayerModel.cpp @@ -0,0 +1,33 @@ +#include "../../Header/Player/PlayerModel.h" + +PlayerModel::PlayerModel() { } + +PlayerModel::~PlayerModel() { } + +void PlayerModel::initialize() { reset(); } + +void PlayerModel::reset() +{ + player_state = PlayerState::ALIVE; + player_position = initial_player_position; +} + +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; +} \ No newline at end of file diff --git a/Source/Player/PlayerService.cpp b/Source/Player/PlayerService.cpp new file mode 100644 index 000000000..1c1391ace --- /dev/null +++ b/Source/Player/PlayerService.cpp @@ -0,0 +1,32 @@ +#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(); + } +} + diff --git a/Source/Player/PlayerView.cpp b/Source/Player/PlayerView.cpp new file mode 100644 index 000000000..d0894cfdb --- /dev/null +++ b/Source/Player/PlayerView.cpp @@ -0,0 +1,49 @@ +#include "../../Header/Player/PlayerView.h" +#include "../../Header/Global/ServiceLocator.h" + +using namespace Global; + +PlayerView::PlayerView() {} + +PlayerView::~PlayerView () {} + + +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(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); +} diff --git a/Source/Time/TimeService.cpp b/Source/Time/TimeService.cpp new file mode 100644 index 000000000..55bf7d10a --- /dev/null +++ b/Source/Time/TimeService.cpp @@ -0,0 +1,44 @@ +#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. + // We will learn aboit how this works in detail later. + return static_cast(delta) / static_cast(1000000); + } + + // Update previous_time to the current time + void TimeService::updatePreviousTime() + { + previous_time = std::chrono::steady_clock::now(); + } +} \ No newline at end of file diff --git a/Space-Invaders.sln b/Space-Invaders.sln new file mode 100644 index 000000000..21ec086fc --- /dev/null +++ b/Space-Invaders.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34024.191 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Space-Invaders", "Space-Invaders.vcxproj", "{AB3664CD-9870-4359-8811-B481DB3B55A0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Debug|x64.ActiveCfg = Debug|x64 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Debug|x64.Build.0 = Debug|x64 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Debug|x86.ActiveCfg = Debug|Win32 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Debug|x86.Build.0 = Debug|Win32 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Release|x64.ActiveCfg = Release|x64 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Release|x64.Build.0 = Release|x64 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Release|x86.ActiveCfg = Release|Win32 + {AB3664CD-9870-4359-8811-B481DB3B55A0}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F8206701-92F6-4A4D-B0E5-F40E32131C64} + EndGlobalSection +EndGlobal diff --git a/Space-Invaders.vcxproj b/Space-Invaders.vcxproj new file mode 100644 index 000000000..d7a3c6fca --- /dev/null +++ b/Space-Invaders.vcxproj @@ -0,0 +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) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Space-Invaders.vcxproj.filters b/Space-Invaders.vcxproj.filters new file mode 100644 index 000000000..d20f98c74 --- /dev/null +++ b/Space-Invaders.vcxproj.filters @@ -0,0 +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 + + + 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.vcxproj.user b/Space-Invaders.vcxproj.user new file mode 100644 index 000000000..966b4ffb6 --- /dev/null +++ b/Space-Invaders.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/Space-Invaders/Header/EventService.h b/Space-Invaders/Header/EventService.h new file mode 100644 index 000000000..fbb4c6d14 --- /dev/null +++ b/Space-Invaders/Header/EventService.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +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 + + + +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(); + +}; diff --git a/Space-Invaders/Header/GameService.h b/Space-Invaders/Header/GameService.h new file mode 100644 index 000000000..acf939667 --- /dev/null +++ b/Space-Invaders/Header/GameService.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include "../Header/ServiceLocator.h" + +class GameService +{ +private: + + 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. +}; \ No newline at end of file diff --git a/Space-Invaders/Header/GraphicService.h b/Space-Invaders/Header/GraphicService.h new file mode 100644 index 000000000..4dba0c0d9 --- /dev/null +++ b/Space-Invaders/Header/GraphicService.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +class GraphicService +{ +private: + + const std::string game_window_title = "Alien Invader"; + + const int game_window_width = 800; + const int game_window_height = 600; + const int frame_rate = 60; + + const sf::Color window_color = sf::Color::Blue; + + 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 +}; diff --git a/Space-Invaders/Header/PlayerModel.h b/Space-Invaders/Header/PlayerModel.h new file mode 100644 index 000000000..b8ed4c6cd --- /dev/null +++ b/Space-Invaders/Header/PlayerModel.h @@ -0,0 +1,33 @@ +#pragma once +#include + +class PlayerModel +{ +private: + + const sf::Vector2f initial_player_position = sf::Vector2f(500.f, 500.f); //new var + sf::Vector2f player_position; //new var + bool player_alive; //new bool + + +public: + const sf::Vector2f left_most_position = sf::Vector2f(50.f, 0.f); + const sf::Vector2f right_most_position = sf::Vector2f(700.f, 0.f); + + const float player_movement_speed = 200.0f; + + PlayerModel(); + ~PlayerModel(); + + void initialize(); + + void reset(); //new method + + + //getters and setters + sf::Vector2f getPlayerPosition(); + void setPlayerPosition(sf::Vector2f position); + + bool getPlayerAlive(); + void setPlayerAlive(bool alive); +}; \ No newline at end of file diff --git a/Space-Invaders/Header/PlayerService.h b/Space-Invaders/Header/PlayerService.h new file mode 100644 index 000000000..962736c1a --- /dev/null +++ b/Space-Invaders/Header/PlayerService.h @@ -0,0 +1,40 @@ +#pragma once +#include + +class PlayerService{ + +private: + + int health = 3; + sf::Vector2f position = sf::Vector2f(200.0f, 100.0f); + float movement_speed = 5; + int player_score = 0; + + 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(); + +public: + + PlayerService(); + ~PlayerService(); + + void initialize(); + void update(); + void render(); + + void moveLeft(); + void moveRight(); + void move(float offsetX); + int getMoveSpeed(); + sf::Vector2f getPosition(); + + + +}; diff --git a/Space-Invaders/Header/ServiceLocator.h b/Space-Invaders/Header/ServiceLocator.h new file mode 100644 index 000000000..db424e80f --- /dev/null +++ b/Space-Invaders/Header/ServiceLocator.h @@ -0,0 +1,41 @@ +#pragma once +#include "../Header/GraphicService.h" +#include "../Header/EventService.h" +#include "../Header/PlayerService.h" +#include "../Header/TimeService.h" + +class ServiceLocator +{ +private: + // Private Attributes: + GraphicService* graphic_service; + + EventService* event_service; + + PlayerService* player_service; + + TimeService* time_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(); + +}; diff --git a/Space-Invaders/Header/TimeService.h b/Space-Invaders/Header/TimeService.h new file mode 100644 index 000000000..ceb9cd1fe --- /dev/null +++ b/Space-Invaders/Header/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. + */ +class TimeService +{ +private: + + // A point in time which indicates the starting time of previous frame. + std::chrono::time_point previous_time; + // No need to worry about the syntax of this variable too much right now + // It'll be explained in detail at a later 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/Source/EventServices.cpp b/Space-Invaders/Source/EventServices.cpp new file mode 100644 index 000000000..518be056b --- /dev/null +++ b/Space-Invaders/Source/EventServices.cpp @@ -0,0 +1,40 @@ +#include "../Header/EventService.h" +#include "../Header/GameService.h" +#include "../Header/GraphicService.h" + +EventService::EventService() { game_window = nullptr; } + +EventService::~EventService() = default; //calls the default destructor +void EventService::initialize() +{ + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); +} +void EventService::update() +{ + //for later +} +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; } \ No newline at end of file diff --git a/Space-Invaders/Source/GameService.cpp b/Space-Invaders/Source/GameService.cpp new file mode 100644 index 000000000..499a2d13a --- /dev/null +++ b/Space-Invaders/Source/GameService.cpp @@ -0,0 +1,64 @@ +#include "../Header/GameService.h" +#include "../Header/GraphicService.h" + + +// 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 = ServiceLocator::getInstance(); // Get ServiceLocator + initialize(); // Initialize services. +} + +//initialize service locator and other variables +void GameService::initialize() +{ + service_locator->initialize(); + initializeVariables(); +} + +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->update(); // Call update on the service locator which then updates all its managed services + + // Process Events. + service_locator->getEventService()->processEvents(); + + // Update Game Logic. + service_locator->update(); +} + + +// 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(); +} diff --git a/Space-Invaders/Source/GraphicService.cpp b/Space-Invaders/Source/GraphicService.cpp new file mode 100644 index 000000000..fc404ceb5 --- /dev/null +++ b/Space-Invaders/Source/GraphicService.cpp @@ -0,0 +1,57 @@ +#include "../Header/GraphicService.h" + +// 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(); + game_window->setFramerateLimit(frame_rate); +} + +// 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); // 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/PlayerModel.cpp b/Space-Invaders/Source/PlayerModel.cpp new file mode 100644 index 000000000..fc625a27b --- /dev/null +++ b/Space-Invaders/Source/PlayerModel.cpp @@ -0,0 +1,33 @@ +#include "../Header/PlayerModel.h" + +PlayerModel::PlayerModel() { } + +PlayerModel::~PlayerModel() { } + +void PlayerModel::initialize() { reset(); } + +void PlayerModel::reset() +{ + player_alive = true; + player_position = initial_player_position; +} + +sf::Vector2f PlayerModel::getPlayerPosition() +{ + return player_position; +} + +void PlayerModel::setPlayerPosition(sf::Vector2f position) +{ + player_position = position; +} + +bool PlayerModel::getPlayerAlive() +{ + return player_alive; +} + +void PlayerModel::setPlayerAlive(bool alive) +{ + player_alive = alive; +} \ No newline at end of file diff --git a/Space-Invaders/Source/PlayerService.cpp b/Space-Invaders/Source/PlayerService.cpp new file mode 100644 index 000000000..2ace83158 --- /dev/null +++ b/Space-Invaders/Source/PlayerService.cpp @@ -0,0 +1,74 @@ +#include "../Header/PlayerService.h" +#include "../Header/ServiceLocator.h" + +PlayerService::PlayerService() { + game_window = nullptr; +} + +PlayerService::~PlayerService() = default; + +void PlayerService::initialize() { + game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow(); + initializePlayerSprite(); +} + +void PlayerService::update() { + processPlayerInput(); + player_sprite.setPosition(getPosition()); +} + +void PlayerService::render() { + game_window->draw(player_sprite); +} + + + +void PlayerService::processPlayerInput() +{ + EventService* event_service = ServiceLocator::getInstance()->getEventService(); + + if (event_service->isKeyboardEvent()) //check if a key has been pressed + { + if (event_service->pressedLeftKey()) + { + moveLeft(); + } + + if (event_service->pressedRightKey()) + { + moveRight(); + } + } +} + +// New movement methods +void PlayerService::moveLeft() +{ + position.x -= movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); +} + +void PlayerService::moveRight() +{ + position.x += movement_speed * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); +} + +void PlayerService::initializePlayerSprite() +{ + if (player_texture.loadFromFile(player_texture_path)) + { + player_sprite.setTexture(player_texture); + } +} + + +void PlayerService::move(float offsetX) { + position.x += offsetX * ServiceLocator::getInstance()->getTimeService()->getDeltaTime(); +} + +int PlayerService::getMoveSpeed() { + return movement_speed; +} + +sf::Vector2f PlayerService::getPosition() { + return position; +} \ 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..3ca25f7b9 --- /dev/null +++ b/Space-Invaders/Source/ServiceLocator.cpp @@ -0,0 +1,76 @@ +#include "../Header/ServiceLocator.h" + + +// Constructor: Initializes the graphic_service pointer to null and creates services. +ServiceLocator::ServiceLocator() { + graphic_service = nullptr; // Initialize graphic_service to null + time_service = nullptr; + event_service = nullptr; + player_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 + time_service = new TimeService(); + event_service = new EventService(); + player_service = new PlayerService(); +} + +// Deletes allocated services to prevent memory leaks, specifically the graphic service. +void ServiceLocator::clearAllServices() { + delete(graphic_service); // Delete the graphic_service instance + delete(time_service); + delete(event_service); + delete(player_service); + + graphic_service = nullptr; // Reset pointer to null to avoid dangling pointer +} + +// Returns a pointer to ServiceLocator. +ServiceLocator* ServiceLocator::getInstance() { + static ServiceLocator instance; // we will discuss what 'static' means at a later time. + 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 + time_service->initialize(); + event_service->initialize(); + player_service->initialize(); +} + +// Updates the state of the graphic service. +void ServiceLocator::update() { + graphic_service->update(); // Update graphic service + time_service->update(); + event_service->update(); + player_service->update(); +} + +// Renders using the graphic service. +void ServiceLocator::render() { + graphic_service->render(); // Render graphic service +} + +// 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; } + + + + + + + + + diff --git a/Space-Invaders/Source/TimeService.cpp b/Space-Invaders/Source/TimeService.cpp new file mode 100644 index 000000000..9bb20d5eb --- /dev/null +++ b/Space-Invaders/Source/TimeService.cpp @@ -0,0 +1,40 @@ +#include "../Header/TimeService.h" + +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. + // We will learn aboit how this works in detail later. + return static_cast(delta) / static_cast(1000000); +} + +// Update previous_time to the current time +void TimeService::updatePreviousTime() +{ + previous_time = std::chrono::steady_clock::now(); +} \ No newline at end of file diff --git a/Space-Invaders/Space-Invaders.vcxproj b/Space-Invaders/Space-Invaders.vcxproj index 6f7fa388d..ccfcc446e 100644 --- a/Space-Invaders/Space-Invaders.vcxproj +++ b/Space-Invaders/Space-Invaders.vcxproj @@ -1,4 +1,4 @@ - + @@ -133,6 +133,22 @@ + + + + + + + + + + + + + + + + diff --git a/Space-Invaders/Space-Invaders.vcxproj.filters b/Space-Invaders/Space-Invaders.vcxproj.filters index ce0c35ccf..39b714b26 100644 --- a/Space-Invaders/Space-Invaders.vcxproj.filters +++ b/Space-Invaders/Space-Invaders.vcxproj.filters @@ -18,5 +18,49 @@ 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 + \ No newline at end of file diff --git a/Space-Invaders/main.cpp b/Space-Invaders/main.cpp index 7d5f90dff..47a2c523b 100644 --- a/Space-Invaders/main.cpp +++ b/Space-Invaders/main.cpp @@ -1,5 +1,120 @@ +#include "../Space-Invaders/Header/GameService.h" + +int main() { + + GameService gameService; + + gameService.ignite(); + + while (gameService.isRunning()) + { + + gameService.update(); + gameService.render(); + + } + +} + + + + + +/* + +#include + +#include + +class Player { + +private: + + // Private Properties + int health = 3; + sf::Vector2f position = sf::Vector2f(200.0f, 100.0f); + int movement_speed = 1; + int player_score = 0; + +public: + + // Public Properties + sf::Texture player_texture; + sf::Sprite player_sprite; + + //Public Getter & Setter methods + int getScore() { + return player_score; + } + + void setScore(int newScore) { + player_score = newScore; + } + + sf::Vector2f getPosition() { + return position; + } + + + void takeDamage() {}; + void move(float offsetX) { + position.x += offsetX; + + }; + + + + int getMoveSpeed() { + return movement_speed; + } + + void shootBullets() {}; + +}; + +int main() { + + sf::VideoMode videoMode = sf::VideoMode(800, 600); // Define the video mode (dimensions) + + sf::RenderWindow window(videoMode, "SFML Window"); // Create a window object + + Player player; // Create the player object + + + while (window.isOpen()) { + sf::Event event; + while (window.pollEvent(event)) { + // Check for window closure + if (event.type == sf::Event::Closed) + window.close(); + } + + // Handle keyboard input + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { + player.move(-1.0f * player.getMoveSpeed()); + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { + player.move(1.0f * player.getMoveSpeed()); + } + + + + player.player_texture.loadFromFile("assets/textures/player_ship.png"); // Load the player ship texture + + player.player_sprite.setTexture(player.player_texture); // Set the player sprite variable + + // Clear the window + window.clear(sf::Color::Blue); // this code will set a blue background color (optional) + + player.player_sprite.setPosition(player.getPosition()); // Set the position of the player sprite + + window.draw(player.player_sprite); // Draw the player sprite + + window.display(); // Display what was drawn + + } // end while loop -int main() -{ return 0; -} \ No newline at end of file +} + +*/ \ No newline at end of file diff --git a/assets/fonts/DS_DIGIB.TTF b/assets/fonts/DS_DIGIB.TTF new file mode 100644 index 000000000..064ad478a Binary files /dev/null and b/assets/fonts/DS_DIGIB.TTF differ diff --git a/assets/fonts/OpenSans.ttf b/assets/fonts/OpenSans.ttf new file mode 100644 index 000000000..ac587b482 Binary files /dev/null and b/assets/fonts/OpenSans.ttf differ diff --git a/assets/fonts/bubbleBobble.ttf b/assets/fonts/bubbleBobble.ttf new file mode 100644 index 000000000..bf238148b Binary files /dev/null and b/assets/fonts/bubbleBobble.ttf differ diff --git a/assets/sounds/background_music.mp3 b/assets/sounds/background_music.mp3 new file mode 100644 index 000000000..05b105786 Binary files /dev/null and b/assets/sounds/background_music.mp3 differ diff --git a/assets/sounds/bullet_fire.ogg b/assets/sounds/bullet_fire.ogg new file mode 100644 index 000000000..7a9a4d2f2 Binary files /dev/null and b/assets/sounds/bullet_fire.ogg differ diff --git a/assets/sounds/button_click_sound.wav b/assets/sounds/button_click_sound.wav new file mode 100644 index 000000000..4f9abb7c5 Binary files /dev/null and b/assets/sounds/button_click_sound.wav differ diff --git a/assets/sounds/explosion.wav b/assets/sounds/explosion.wav new file mode 100644 index 000000000..5472d9920 Binary files /dev/null and b/assets/sounds/explosion.wav differ diff --git a/assets/sounds/powerup_disabled.ogg b/assets/sounds/powerup_disabled.ogg new file mode 100644 index 000000000..e3a7a514d Binary files /dev/null and b/assets/sounds/powerup_disabled.ogg differ diff --git a/assets/sounds/powerup_enabled.ogg b/assets/sounds/powerup_enabled.ogg new file mode 100644 index 000000000..49fdb6cc8 Binary files /dev/null and b/assets/sounds/powerup_enabled.ogg differ diff --git a/assets/textures/bunker.png b/assets/textures/bunker.png new file mode 100644 index 000000000..144d0c495 Binary files /dev/null and b/assets/textures/bunker.png differ diff --git a/assets/textures/circle_animation.png b/assets/textures/circle_animation.png new file mode 100644 index 000000000..bebf03ef8 Binary files /dev/null and b/assets/textures/circle_animation.png differ diff --git a/assets/textures/explosion.png b/assets/textures/explosion.png new file mode 100644 index 000000000..77a5bccd9 Binary files /dev/null and b/assets/textures/explosion.png differ diff --git a/assets/textures/frost_beam.png b/assets/textures/frost_beam.png new file mode 100644 index 000000000..6f3b9103a Binary files /dev/null and b/assets/textures/frost_beam.png differ diff --git a/assets/textures/instructions_button.png b/assets/textures/instructions_button.png new file mode 100644 index 000000000..6aab36c3d Binary files /dev/null and b/assets/textures/instructions_button.png differ diff --git a/assets/textures/laser_bullet.png b/assets/textures/laser_bullet.png new file mode 100644 index 000000000..97a44051d Binary files /dev/null and b/assets/textures/laser_bullet.png differ diff --git a/assets/textures/menu_button.png b/assets/textures/menu_button.png new file mode 100644 index 000000000..3e9675527 Binary files /dev/null and b/assets/textures/menu_button.png differ diff --git a/assets/textures/outscal_bomb.png b/assets/textures/outscal_bomb.png new file mode 100644 index 000000000..3e35744d5 Binary files /dev/null and b/assets/textures/outscal_bomb.png differ diff --git a/assets/textures/outscal_logo.png b/assets/textures/outscal_logo.png new file mode 100644 index 000000000..638e48412 Binary files /dev/null and b/assets/textures/outscal_logo.png differ diff --git a/assets/textures/play_button.png b/assets/textures/play_button.png new file mode 100644 index 000000000..0c842b345 Binary files /dev/null and b/assets/textures/play_button.png differ diff --git a/assets/textures/player_ship.png b/assets/textures/player_ship.png new file mode 100644 index 000000000..796e81d71 Binary files /dev/null and b/assets/textures/player_ship.png differ diff --git a/assets/textures/quit_button.png b/assets/textures/quit_button.png new file mode 100644 index 000000000..6f1a965bd Binary files /dev/null and b/assets/textures/quit_button.png differ diff --git a/assets/textures/rapid_fire.png b/assets/textures/rapid_fire.png new file mode 100644 index 000000000..ea98f39b4 Binary files /dev/null and b/assets/textures/rapid_fire.png differ diff --git a/assets/textures/shield.png b/assets/textures/shield.png new file mode 100644 index 000000000..8d68623bb Binary files /dev/null and b/assets/textures/shield.png differ diff --git a/assets/textures/space_invaders_bg.png b/assets/textures/space_invaders_bg.png new file mode 100644 index 000000000..0055a6146 Binary files /dev/null and b/assets/textures/space_invaders_bg.png differ diff --git a/assets/textures/subzero.png b/assets/textures/subzero.png new file mode 100644 index 000000000..a575c9d49 Binary files /dev/null and b/assets/textures/subzero.png differ diff --git a/assets/textures/thunder_snake.png b/assets/textures/thunder_snake.png new file mode 100644 index 000000000..fb0c0a2ca Binary files /dev/null and b/assets/textures/thunder_snake.png differ diff --git a/assets/textures/torpedoe.png b/assets/textures/torpedoe.png new file mode 100644 index 000000000..5a2cce30e Binary files /dev/null and b/assets/textures/torpedoe.png differ diff --git a/assets/textures/tripple_laser.png b/assets/textures/tripple_laser.png new file mode 100644 index 000000000..28f7aebaa Binary files /dev/null and b/assets/textures/tripple_laser.png differ diff --git a/assets/textures/ufo.png b/assets/textures/ufo.png new file mode 100644 index 000000000..6397792bf Binary files /dev/null and b/assets/textures/ufo.png differ diff --git a/assets/textures/zapper.png b/assets/textures/zapper.png new file mode 100644 index 000000000..5189d2459 Binary files /dev/null and b/assets/textures/zapper.png differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 000000000..a38ee8d4e --- /dev/null +++ b/main.cpp @@ -0,0 +1,122 @@ +#include "../Space-Invaders/Header/Main/GameService.h" + +int main() { + + using namespace Main; + + GameService gameService; + + gameService.ignite(); + + while (gameService.isRunning()) + { + + gameService.update(); + gameService.render(); + + } + +} + + + + + +/* + +#include + +#include + +class player { + +private: + + private properties + int health = 3; + sf::vector2f position = sf::vector2f(200.0f, 100.0f); + int movement_speed = 1; + int player_score = 0; + +public: + + public properties + sf::texture player_texture; + sf::sprite player_sprite; + + public getter & setter methods + int getscore() { + return player_score; + } + + void setscore(int newscore) { + player_score = newscore; + } + + sf::vector2f getposition() { + return position; + } + + + void takedamage() {}; + void move(float offsetx) { + position.x += offsetx; + + }; + + + + int getmovespeed() { + return movement_speed; + } + + void shootbullets() {}; + +}; + +int main() { + + sf::videomode videomode = sf::videomode(800, 600); // define the video mode (dimensions) + + sf::renderwindow window(videomode, "sfml window"); // create a window object + + player player; // create the player object + + + while (window.isopen()) { + sf::event event; + while (window.pollevent(event)) { + check for window closure + if (event.type == sf::event::closed) + window.close(); + } + + handle keyboard input + if (sf::keyboard::iskeypressed(sf::keyboard::left)) { + player.move(-1.0f * player.getmovespeed()); + } + if (sf::keyboard::iskeypressed(sf::keyboard::right)) { + player.move(1.0f * player.getmovespeed()); + } + + + + player.player_texture.loadfromfile("assets/textures/player_ship.png"); // load the player ship texture + + player.player_sprite.settexture(player.player_texture); // set the player sprite variable + + clear the window + window.clear(sf::color::blue); // this code will set a blue background color (optional) + + player.player_sprite.setposition(player.getposition()); // set the position of the player sprite + + window.draw(player.player_sprite); // draw the player sprite + + window.display(); // display what was drawn + + } // end while loop + + return 0; +} + +*/ \ No newline at end of file diff --git a/sfml/include/SFML/Audio.hpp b/sfml/include/SFML/Audio.hpp new file mode 100644 index 000000000..d5f798d1d --- /dev/null +++ b/sfml/include/SFML/Audio.hpp @@ -0,0 +1,56 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_AUDIO_HPP +#define SFML_AUDIO_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif // SFML_AUDIO_HPP + +//////////////////////////////////////////////////////////// +/// \defgroup audio Audio module +/// +/// Sounds, streaming (musics or custom sources), recording, +/// spatialization. +/// +//////////////////////////////////////////////////////////// diff --git a/sfml/include/SFML/Audio/AlResource.hpp b/sfml/include/SFML/Audio/AlResource.hpp new file mode 100644 index 000000000..7ac21fe8b --- /dev/null +++ b/sfml/include/SFML/Audio/AlResource.hpp @@ -0,0 +1,70 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_ALRESOURCE_HPP +#define SFML_ALRESOURCE_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Base class for classes that require an OpenAL context +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API AlResource +{ +protected: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + AlResource(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + //////////////////////////////////////////////////////////// + ~AlResource(); +}; + +} // namespace sf + + +#endif // SFML_ALRESOURCE_HPP + +//////////////////////////////////////////////////////////// +/// \class sf::AlResource +/// \ingroup audio +/// +/// This class is for internal use only, it must be the base +/// of every class that requires a valid OpenAL context in +/// order to work. +/// +//////////////////////////////////////////////////////////// diff --git a/sfml/include/SFML/Audio/Export.hpp b/sfml/include/SFML/Audio/Export.hpp new file mode 100644 index 000000000..e25315146 --- /dev/null +++ b/sfml/include/SFML/Audio/Export.hpp @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_AUDIO_EXPORT_HPP +#define SFML_AUDIO_EXPORT_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +//////////////////////////////////////////////////////////// +// Define portable import / export macros +//////////////////////////////////////////////////////////// +#if defined(SFML_AUDIO_EXPORTS) + + #define SFML_AUDIO_API SFML_API_EXPORT + +#else + + #define SFML_AUDIO_API SFML_API_IMPORT + +#endif + + +#endif // SFML_AUDIO_EXPORT_HPP diff --git a/sfml/include/SFML/Audio/InputSoundFile.hpp b/sfml/include/SFML/Audio/InputSoundFile.hpp new file mode 100644 index 000000000..0a02b1407 --- /dev/null +++ b/sfml/include/SFML/Audio/InputSoundFile.hpp @@ -0,0 +1,268 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_INPUTSOUNDFILE_HPP +#define SFML_INPUTSOUNDFILE_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + + +namespace sf +{ +class InputStream; +class SoundFileReader; + +//////////////////////////////////////////////////////////// +/// \brief Provide read access to sound files +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API InputSoundFile : NonCopyable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + InputSoundFile(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + //////////////////////////////////////////////////////////// + ~InputSoundFile(); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC, MP3. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// Because of minimp3_ex limitation, for MP3 files with big (>16kb) APEv2 tag, + /// it may not be properly removed, tag data will be treated as MP3 data + /// and there is a low chance of garbage decoded at the end of file. + /// See also: https://github.com/lieff/minimp3 + /// + /// \param filename Path of the sound file to load + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + bool openFromFile(const std::string& filename); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + bool openFromMemory(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + bool openFromStream(InputStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Get the total number of audio samples in the file + /// + /// \return Number of samples + /// + //////////////////////////////////////////////////////////// + Uint64 getSampleCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the number of channels used by the sound + /// + /// \return Number of channels (1 = mono, 2 = stereo) + /// + //////////////////////////////////////////////////////////// + unsigned int getChannelCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the sample rate of the sound + /// + /// \return Sample rate, in samples per second + /// + //////////////////////////////////////////////////////////// + unsigned int getSampleRate() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the total duration of the sound file + /// + /// This function is provided for convenience, the duration is + /// deduced from the other sound file attributes. + /// + /// \return Duration of the sound file + /// + //////////////////////////////////////////////////////////// + Time getDuration() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in time + /// + /// \return Time position + /// + //////////////////////////////////////////////////////////// + Time getTimeOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in samples + /// + /// \return Sample position + /// + //////////////////////////////////////////////////////////// + Uint64 getSampleOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given sample offset + /// + /// This function takes a sample offset to provide maximum + /// precision. If you need to jump to a given time, use the + /// other overload. + /// + /// The sample offset takes the channels into account. + /// If you have a time offset instead, you can easily find + /// the corresponding sample offset with the following formula: + /// `timeInSeconds * sampleRate * channelCount` + /// If the given offset exceeds to total number of samples, + /// this function jumps to the end of the sound file. + /// + /// \param sampleOffset Index of the sample to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(Uint64 sampleOffset); + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given time offset + /// + /// Using a time offset is handy but imprecise. If you need an accurate + /// result, consider using the overload which takes a sample offset. + /// + /// If the given time exceeds to total duration, this function jumps + /// to the end of the sound file. + /// + /// \param timeOffset Time to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(Time timeOffset); + + //////////////////////////////////////////////////////////// + /// \brief Read audio samples from the open file + /// + /// \param samples Pointer to the sample array to fill + /// \param maxCount Maximum number of samples to read + /// + /// \return Number of samples actually read (may be less than \a maxCount) + /// + //////////////////////////////////////////////////////////// + Uint64 read(Int16* samples, Uint64 maxCount); + + //////////////////////////////////////////////////////////// + /// \brief Close the current file + /// + //////////////////////////////////////////////////////////// + void close(); + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + SoundFileReader* m_reader; //!< Reader that handles I/O on the file's format + InputStream* m_stream; //!< Input stream used to access the file's data + bool m_streamOwned; //!< Is the stream internal or external? + Uint64 m_sampleOffset; //!< Sample Read Position + Uint64 m_sampleCount; //!< Total number of samples in the file + unsigned int m_channelCount; //!< Number of channels of the sound + unsigned int m_sampleRate; //!< Number of samples per second +}; + +} // namespace sf + + +#endif // SFML_INPUTSOUNDFILE_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::InputSoundFile +/// \ingroup audio +/// +/// This class decodes audio samples from a sound file. It is +/// used internally by higher-level classes such as sf::SoundBuffer +/// and sf::Music, but can also be useful if you want to process +/// or analyze audio files without playing them, or if you want to +/// implement your own version of sf::Music with more specific +/// features. +/// +/// Usage example: +/// \code +/// // Open a sound file +/// sf::InputSoundFile file; +/// if (!file.openFromFile("music.ogg")) +/// /* error */; +/// +/// // Print the sound attributes +/// std::cout << "duration: " << file.getDuration().asSeconds() << std::endl; +/// std::cout << "channels: " << file.getChannelCount() << std::endl; +/// std::cout << "sample rate: " << file.getSampleRate() << std::endl; +/// std::cout << "sample count: " << file.getSampleCount() << std::endl; +/// +/// // Read and process batches of samples until the end of file is reached +/// sf::Int16 samples[1024]; +/// sf::Uint64 count; +/// do +/// { +/// count = file.read(samples, 1024); +/// +/// // process, analyze, play, convert, or whatever +/// // you want to do with the samples... +/// } +/// while (count > 0); +/// \endcode +/// +/// \see sf::SoundFileReader, sf::OutputSoundFile +/// +//////////////////////////////////////////////////////////// diff --git a/sfml/include/SFML/Audio/Listener.hpp b/sfml/include/SFML/Audio/Listener.hpp new file mode 100644 index 000000000..edfe6502d --- /dev/null +++ b/sfml/include/SFML/Audio/Listener.hpp @@ -0,0 +1,234 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_LISTENER_HPP +#define SFML_LISTENER_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief The audio listener is the point in the scene +/// from where all the sounds are heard +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API Listener +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Change the global volume of all the sounds and musics + /// + /// The volume is a number between 0 and 100; it is combined with + /// the individual volume of each sound / music. + /// The default value for the volume is 100 (maximum). + /// + /// \param volume New global volume, in the range [0, 100] + /// + /// \see getGlobalVolume + /// + //////////////////////////////////////////////////////////// + static void setGlobalVolume(float volume); + + //////////////////////////////////////////////////////////// + /// \brief Get the current value of the global volume + /// + /// \return Current global volume, in the range [0, 100] + /// + /// \see setGlobalVolume + /// + //////////////////////////////////////////////////////////// + static float getGlobalVolume(); + + //////////////////////////////////////////////////////////// + /// \brief Set the position of the listener in the scene + /// + /// The default listener's position is (0, 0, 0). + /// + /// \param x X coordinate of the listener's position + /// \param y Y coordinate of the listener's position + /// \param z Z coordinate of the listener's position + /// + /// \see getPosition, setDirection + /// + //////////////////////////////////////////////////////////// + static void setPosition(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the position of the listener in the scene + /// + /// The default listener's position is (0, 0, 0). + /// + /// \param position New listener's position + /// + /// \see getPosition, setDirection + /// + //////////////////////////////////////////////////////////// + static void setPosition(const Vector3f& position); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of the listener in the scene + /// + /// \return Listener's position + /// + /// \see setPosition + /// + //////////////////////////////////////////////////////////// + static Vector3f getPosition(); + + //////////////////////////////////////////////////////////// + /// \brief Set the forward vector of the listener in the scene + /// + /// The direction (also called "at vector") is the vector + /// pointing forward from the listener's perspective. Together + /// with the up vector, it defines the 3D orientation of the + /// listener in the scene. The direction vector doesn't + /// have to be normalized. + /// The default listener's direction is (0, 0, -1). + /// + /// \param x X coordinate of the listener's direction + /// \param y Y coordinate of the listener's direction + /// \param z Z coordinate of the listener's direction + /// + /// \see getDirection, setUpVector, setPosition + /// + //////////////////////////////////////////////////////////// + static void setDirection(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the forward vector of the listener in the scene + /// + /// The direction (also called "at vector") is the vector + /// pointing forward from the listener's perspective. Together + /// with the up vector, it defines the 3D orientation of the + /// listener in the scene. The direction vector doesn't + /// have to be normalized. + /// The default listener's direction is (0, 0, -1). + /// + /// \param direction New listener's direction + /// + /// \see getDirection, setUpVector, setPosition + /// + //////////////////////////////////////////////////////////// + static void setDirection(const Vector3f& direction); + + //////////////////////////////////////////////////////////// + /// \brief Get the current forward vector of the listener in the scene + /// + /// \return Listener's forward vector (not normalized) + /// + /// \see setDirection + /// + //////////////////////////////////////////////////////////// + static Vector3f getDirection(); + + //////////////////////////////////////////////////////////// + /// \brief Set the upward vector of the listener in the scene + /// + /// The up vector is the vector that points upward from the + /// listener's perspective. Together with the direction, it + /// defines the 3D orientation of the listener in the scene. + /// The up vector doesn't have to be normalized. + /// The default listener's up vector is (0, 1, 0). It is usually + /// not necessary to change it, especially in 2D scenarios. + /// + /// \param x X coordinate of the listener's up vector + /// \param y Y coordinate of the listener's up vector + /// \param z Z coordinate of the listener's up vector + /// + /// \see getUpVector, setDirection, setPosition + /// + //////////////////////////////////////////////////////////// + static void setUpVector(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the upward vector of the listener in the scene + /// + /// The up vector is the vector that points upward from the + /// listener's perspective. Together with the direction, it + /// defines the 3D orientation of the listener in the scene. + /// The up vector doesn't have to be normalized. + /// The default listener's up vector is (0, 1, 0). It is usually + /// not necessary to change it, especially in 2D scenarios. + /// + /// \param upVector New listener's up vector + /// + /// \see getUpVector, setDirection, setPosition + /// + //////////////////////////////////////////////////////////// + static void setUpVector(const Vector3f& upVector); + + //////////////////////////////////////////////////////////// + /// \brief Get the current upward vector of the listener in the scene + /// + /// \return Listener's upward vector (not normalized) + /// + /// \see setUpVector + /// + //////////////////////////////////////////////////////////// + static Vector3f getUpVector(); +}; + +} // namespace sf + + +#endif // SFML_LISTENER_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Listener +/// \ingroup audio +/// +/// The audio listener defines the global properties of the +/// audio environment, it defines where and how sounds and musics +/// are heard. If sf::View is the eyes of the user, then sf::Listener +/// is his ears (by the way, they are often linked together -- +/// same position, orientation, etc.). +/// +/// sf::Listener is a simple interface, which allows to setup the +/// listener in the 3D audio environment (position, direction and +/// up vector), and to adjust the global volume. +/// +/// Because the listener is unique in the scene, sf::Listener only +/// contains static functions and doesn't have to be instantiated. +/// +/// Usage example: +/// \code +/// // Move the listener to the position (1, 0, -5) +/// sf::Listener::setPosition(1, 0, -5); +/// +/// // Make it face the right axis (1, 0, 0) +/// sf::Listener::setDirection(1, 0, 0); +/// +/// // Reduce the global volume +/// sf::Listener::setGlobalVolume(50); +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/sfml/include/SFML/Audio/Music.hpp b/sfml/include/SFML/Audio/Music.hpp new file mode 100644 index 000000000..4c4eefb24 --- /dev/null +++ b/sfml/include/SFML/Audio/Music.hpp @@ -0,0 +1,337 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_MUSIC_HPP +#define SFML_MUSIC_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include + + +namespace sf +{ +class InputStream; + +//////////////////////////////////////////////////////////// +/// \brief Streamed music played from an audio file +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API Music : public SoundStream +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Structure defining a time range using the template type + /// + //////////////////////////////////////////////////////////// + template + struct Span + { + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + Span() + { + + } + + //////////////////////////////////////////////////////////// + /// \brief Initialization constructor + /// + /// \param off Initial Offset + /// \param len Initial Length + /// + //////////////////////////////////////////////////////////// + Span(T off, T len): + offset(off), + length(len) + { + + } + + T offset; //!< The beginning offset of the time range + T length; //!< The length of the time range + }; + + // Define the relevant Span types + typedef Span