diff --git a/Space-Invaders/PlayerService.cpp b/Space-Invaders/PlayerService.cpp
new file mode 100644
index 000000000..92f70dd0a
--- /dev/null
+++ b/Space-Invaders/PlayerService.cpp
@@ -0,0 +1,57 @@
+#include "../Header/PlayerService.h"
+#include "../Header/ServiceLocator.h"
+
+PlayerService::PlayerService()
+{
+ game_window = nullptr;
+}
+
+PlayerService::~PlayerService() = default;
+
+//init
+void PlayerService::initialize()
+{
+ game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+ initializePlayerSprite();
+}
+
+//take our players input in update, then set the position.
+//order is important here
+void PlayerService::update()
+{
+ processPlayerInput();
+ player_sprite.setPosition(getPlayerPosition());
+}
+
+void PlayerService::render()
+{
+ game_window->draw(player_sprite);
+}
+
+void PlayerService::processPlayerInput()
+{
+ // Handle keyboard input
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
+ move(-1.0f * getMoveSpeed());
+ }
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
+ move(1.0f * getMoveSpeed());
+ }
+}
+
+void PlayerService::initializePlayerSprite()
+{
+ if (player_texture.loadFromFile(player_texture_path))
+ {
+ player_sprite.setTexture(player_texture);
+ }
+}
+
+void PlayerService::move(float offsetX) {
+ position.x += offsetX;
+}
+
+//helper functions
+sf::Vector2f PlayerService::getPlayerPosition() { return position; }
+int PlayerService::getMoveSpeed() { return movement_speed; }
+
diff --git a/Space-Invaders/Space-Invaders.vcxproj b/Space-Invaders/Space-Invaders.vcxproj
index d4d53576b..30f60fefb 100644
--- a/Space-Invaders/Space-Invaders.vcxproj
+++ b/Space-Invaders/Space-Invaders.vcxproj
@@ -132,12 +132,30 @@
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
diff --git a/Space-Invaders/Space-Invaders.vcxproj.filters b/Space-Invaders/Space-Invaders.vcxproj.filters
index a095c5df4..55742eea8 100644
--- a/Space-Invaders/Space-Invaders.vcxproj.filters
+++ b/Space-Invaders/Space-Invaders.vcxproj.filters
@@ -21,12 +21,66 @@
Source Files
+
+ 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
+
+
Header Files
diff --git a/Space-Invaders/header/EventService.h b/Space-Invaders/header/EventService.h
new file mode 100644
index 000000000..3f2fe897e
--- /dev/null
+++ b/Space-Invaders/header/EventService.h
@@ -0,0 +1,32 @@
+#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/GraphicService.h b/Space-Invaders/header/GraphicService.h
new file mode 100644
index 000000000..0d138531f
--- /dev/null
+++ b/Space-Invaders/header/GraphicService.h
@@ -0,0 +1,7 @@
+class GraphicService {
+public:
+ void initialize();
+
+private:
+ static const int frame_rate = 60;
+};
\ No newline at end of file
diff --git a/Space-Invaders/header/PlayerController.h b/Space-Invaders/header/PlayerController.h
new file mode 100644
index 000000000..45a7567d4
--- /dev/null
+++ b/Space-Invaders/header/PlayerController.h
@@ -0,0 +1,26 @@
+
+#pragma once
+#include
+#include "../Player/PlayerModel.h"
+#include "../Player/PlayerView.h"
+
+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();
+};
diff --git a/Space-Invaders/header/PlayerModel.h b/Space-Invaders/header/PlayerModel.h
new file mode 100644
index 000000000..ddc252a0f
--- /dev/null
+++ b/Space-Invaders/header/PlayerModel.h
@@ -0,0 +1,43 @@
+#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);
+
+ sf::Vector2f player_position;
+ PlayerState player_state; //Declaration
+ int player_score;
+
+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();
+
+ sf::Vector2f getPlayerPosition();
+ void setPlayerPosition(sf::Vector2f position);
+
+ int getPlayerScore();
+ void setPlayerScore(int score);
+
+ //new getter and setter
+ PlayerState getPlayerState();
+ void setPlayerState(PlayerState state);
+
+
+};
\ 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..5e57ab793
--- /dev/null
+++ b/Space-Invaders/header/PlayerService.h
@@ -0,0 +1,26 @@
+
+#pragma once
+
+
+#pragma once
+#include
+#include "../../Header/Player/PlayerController.h"
+class PlayerService
+{
+
+private:
+
+PlayerController* player_controller
+
+public:
+
+ PlayerService();
+ ~PlayerService();
+
+ void initialize();
+ void update();
+ void render();
+
+
+
+};
diff --git a/Space-Invaders/header/PlayerView.h b/Space-Invaders/header/PlayerView.h
new file mode 100644
index 000000000..3c9999102
--- /dev/null
+++ b/Space-Invaders/header/PlayerView.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "../../Header/Player/PlayerController.h"
+#include
+
+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();
+ void update();
+ void render();
+ void initialize(PlayerController* controller);
+};
diff --git a/Space-Invaders/header/TimeService.h b/Space-Invaders/header/TimeService.h
new file mode 100644
index 000000000..7f6c57a02
--- /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();
+};
\ No newline at end of file
diff --git a/Space-Invaders/header/servicelocator.h b/Space-Invaders/header/servicelocator.h
index 6f70f09be..6c8d15b7d 100644
--- a/Space-Invaders/header/servicelocator.h
+++ b/Space-Invaders/header/servicelocator.h
@@ -1 +1,31 @@
+
#pragma once
+#include "../header/GraphicService.h"
+#include "../header/EventService.h"
+
+class ServiceLocator
+{
+private:
+ // Private Attributes:
+ GraphicService* graphic_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();
+
+};
diff --git a/Space-Invaders/source/EventService.cpp b/Space-Invaders/source/EventService.cpp
new file mode 100644
index 000000000..891ed1457
--- /dev/null
+++ b/Space-Invaders/source/EventService.cpp
@@ -0,0 +1,45 @@
+#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::pressedLeftKey() { return game_event.key.code == sf::Keyboard::Left; }
+bool EventService::pressedRightKey() { return game_event.key.code == sf::Keyboard::Right; }
+
+bool EventService::gameWindowWasClosed() { return game_event.type == sf::Event::Closed; }
\ No newline at end of file
diff --git a/Space-Invaders/source/GraphicService.cpp b/Space-Invaders/source/GraphicService.cpp
new file mode 100644
index 000000000..27b2dde7c
--- /dev/null
+++ b/Space-Invaders/source/GraphicService.cpp
@@ -0,0 +1,6 @@
+#include "../header/GraphicService.h"
+void GraphicService::initialize()
+{
+ game_window = createGameWindow();
+ game_window->setFramerateLimit(frame_rate);
+}
\ 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..998e15c6c
--- /dev/null
+++ b/Space-Invaders/source/PLayerController.cpp
@@ -0,0 +1,72 @@
+#include "../../Header/Player/PlayerController.h"
+#include "../../Header/EventService.h"
+#include "../../Header/ServiceLocator.h"
+#include
+
+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/Space-Invaders/source/PLayerView.cpp b/Space-Invaders/source/PLayerView.cpp
new file mode 100644
index 000000000..22b067944
--- /dev/null
+++ b/Space-Invaders/source/PLayerView.cpp
@@ -0,0 +1,43 @@
+#include "../../Header/Player/PlayerView.h"
+#include "../../Header/ServiceLocator.h"
+
+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/PlayerModel.cpp b/Space-Invaders/source/PlayerModel.cpp
new file mode 100644
index 000000000..f56c7dc0d
--- /dev/null
+++ b/Space-Invaders/source/PlayerModel.cpp
@@ -0,0 +1,45 @@
+#include "../../Header/Player/PlayerModel.h"
+
+PlayerModel::PlayerModel() { }
+
+PlayerModel::~PlayerModel() { }
+
+void PlayerModel::initialize() { reset(); } // remember to call reset()
+
+void PlayerModel::reset()
+{
+ player_state = PlayerState::ALIVE; // set state to alive
+ player_position = initial_player_position;
+ player_score = 0;
+}
+
+sf::Vector2f PlayerModel::getPlayerPosition()
+{
+ return player_position;
+}
+
+void PlayerModel::setPlayerPosition(sf::Vector2f position)
+{
+ player_position = position;
+}
+
+int PlayerModel::getPlayerScore()
+{
+ return player_score;
+}
+
+void PlayerModel::setPlayerScore(int score)
+{
+ player_score = score;
+}
+
+//..
+PlayerState PlayerModel::getPlayerState()
+{
+ return player_state;
+}
+
+void PlayerModel::setPlayerState(PlayerState state)
+{
+ player_state = state;
+}
\ No newline at end of file
diff --git a/Space-Invaders/source/PlayerService.cpp b/Space-Invaders/source/PlayerService.cpp
new file mode 100644
index 000000000..345bd0474
--- /dev/null
+++ b/Space-Invaders/source/PlayerService.cpp
@@ -0,0 +1,27 @@
+#include "../Header/PlayerService.h"
+#include "../Header/Player/PlayerController.h"
+
+PlayerService::PlayerService()
+{
+ player_controller = new PlayerController();
+}
+
+PlayerService::~PlayerService()
+{
+ delete (player_controller);
+}
+
+void PlayerService::initialize()
+{
+ player_controller->initialize();
+}
+
+void PlayerService::update()
+{
+ player_controller->update();
+}
+
+void PlayerService::render()
+{
+ player_controller->render();
+}
\ No newline at end of file
diff --git a/Space-Invaders/source/ServiceLocator.cpp b/Space-Invaders/source/ServiceLocator.cpp
new file mode 100644
index 000000000..2d5b31b90
--- /dev/null
+++ b/Space-Invaders/source/ServiceLocator.cpp
@@ -0,0 +1,57 @@
+#include "../Header/ServiceLocator.h"
+#include "../Header/TimeService.h"
+#include "../Header/EventService.h"
+ServiceLocator::ServiceLocator()
+{
+ graphic_service = nullptr;
+ time_service = nullptr;
+ event_service = nullptr;
+ player_service = nullptr;
+
+ createServices();
+}
+
+//.. some other code
+
+void ServiceLocator::createServices()
+{
+ graphic_service = new GraphicService();
+ time_service = new TimeService();
+ event_service = new EventService();
+ player_service = new PlayerService();
+}
+
+void ServiceLocator::clearAllServices()
+{
+ delete(graphic_service);
+ delete(time_service);
+ delete(event_service);
+ delete(player_service);
+}
+
+//... other code
+
+void ServiceLocator::initialize()
+{
+ graphic_service->initialize();
+ time_service->initialize();
+ event_service->initialize();
+ player_service->initialize();
+}
+
+void ServiceLocator::update()
+{
+ graphic_service->update();
+ time_service->update();
+ event_service->update();
+ player_service->update();
+}
+
+//... other code
+
+GraphicService* ServiceLocator::getGraphicService() { return graphic_service; }
+EventService* ServiceLocator::getEventService() { return event_service; }
+PlayerService* ServiceLocator::getPlayerService() { return player_service; }
+TimeService* ServiceLocator::getTimeService() { return time_service; }
+
+//... other code
\ No newline at end of file
diff --git a/Space-Invaders/source/TimeService.cpp b/Space-Invaders/source/TimeService.cpp
new file mode 100644
index 000000000..33cbee4c8
--- /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();
+}