aboutsummaryrefslogtreecommitdiff
path: root/mwe/gameloop
diff options
context:
space:
mode:
Diffstat (limited to 'mwe/gameloop')
-rw-r--r--mwe/gameloop/CMakeLists.txt28
-rw-r--r--mwe/gameloop/imgs/demo.bmpbin0 -> 7998698 bytes
-rw-r--r--mwe/gameloop/imgs/demo.jpgbin0 -> 903706 bytes
-rw-r--r--mwe/gameloop/include/eventManager.h4
-rw-r--r--mwe/gameloop/include/gameObject.h29
-rw-r--r--mwe/gameloop/include/loopManager.h25
-rw-r--r--mwe/gameloop/include/timer.h30
-rw-r--r--mwe/gameloop/include/window.h20
-rw-r--r--mwe/gameloop/src/eventManager.cpp0
-rw-r--r--mwe/gameloop/src/gameObject.cpp58
-rw-r--r--mwe/gameloop/src/loopManager.cpp72
-rw-r--r--mwe/gameloop/src/main.cpp19
-rw-r--r--mwe/gameloop/src/timer.cpp68
-rw-r--r--mwe/gameloop/src/window.cpp60
-rw-r--r--mwe/gameloop/versions/delayBased.cpp57
15 files changed, 470 insertions, 0 deletions
diff --git a/mwe/gameloop/CMakeLists.txt b/mwe/gameloop/CMakeLists.txt
new file mode 100644
index 0000000..6bc5017
--- /dev/null
+++ b/mwe/gameloop/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.5)
+project(gameloop)
+
+# Set the C++ standard (optional, but good practice)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+
+# Find the SDL2 package
+find_package(SDL2 REQUIRED)
+
+# Add your executable
+set(SOURCES
+ src/loopManager
+ src/window.cpp
+ src/main.cpp
+ src/eventManager.cpp
+ src/gameObject.cpp
+ src/timer.cpp
+)
+
+add_executable(gameloop ${SOURCES})
+
+# Link the SDL2 library to your project
+target_link_libraries(gameloop ${SDL2_LIBRARIES})
+
+# Include SDL2 header files and project headers
+target_include_directories(gameloop PRIVATE ${SDL2_INCLUDE_DIRS})
+target_include_directories(gameloop PRIVATE ${CMAKE_SOURCE_DIR}/include)
diff --git a/mwe/gameloop/imgs/demo.bmp b/mwe/gameloop/imgs/demo.bmp
new file mode 100644
index 0000000..65354fe
--- /dev/null
+++ b/mwe/gameloop/imgs/demo.bmp
Binary files differ
diff --git a/mwe/gameloop/imgs/demo.jpg b/mwe/gameloop/imgs/demo.jpg
new file mode 100644
index 0000000..f534e1b
--- /dev/null
+++ b/mwe/gameloop/imgs/demo.jpg
Binary files differ
diff --git a/mwe/gameloop/include/eventManager.h b/mwe/gameloop/include/eventManager.h
new file mode 100644
index 0000000..2aa0a68
--- /dev/null
+++ b/mwe/gameloop/include/eventManager.h
@@ -0,0 +1,4 @@
+class EventManager
+{
+
+};
diff --git a/mwe/gameloop/include/gameObject.h b/mwe/gameloop/include/gameObject.h
new file mode 100644
index 0000000..0e17991
--- /dev/null
+++ b/mwe/gameloop/include/gameObject.h
@@ -0,0 +1,29 @@
+#pragma once
+#include <iostream>
+class GameObject {
+ public:
+ GameObject();
+ GameObject(std::string name, float x, float y, float width, float height, float velX, float velY);
+ std::string getName() const;
+ float getX() const;
+ float getY() const;
+ float getWidth() const;
+ float getHeight() const;
+ float getVelX() const;
+ float getVelY() const;
+ void setName(std::string value);
+ void setX(float value);
+ void setY(float value);
+ void setWidth(float value);
+ void setHeight(float value);
+ void setVelX(float value);
+ void setVelY(float value);
+ private:
+ std::string name = "";
+ float x = 0;
+ float y = 0;
+ float width = 0;
+ float height = 0;
+ float velX = 0;
+ float velY = 0;
+};
diff --git a/mwe/gameloop/include/loopManager.h b/mwe/gameloop/include/loopManager.h
new file mode 100644
index 0000000..06bcd5f
--- /dev/null
+++ b/mwe/gameloop/include/loopManager.h
@@ -0,0 +1,25 @@
+#pragma once
+#include <SDL2/SDL.h>
+#include "window.h"
+#include "gameObject.h"
+class LoopManager{
+ public:
+ LoopManager();
+ void setup();
+ void loop();
+ private:
+
+ std::vector<GameObject*> objectList;
+ void processInput();
+ void update();
+ void lateUpdate();
+ void fixedUpdate();
+ void render();
+ bool gameRunning = false;
+ WindowManager window;
+ int timeScale = 1;
+ float accumulator = 0.0;
+ double currentTime;
+ double t = 0.0;
+ double dt = 0.01;
+};
diff --git a/mwe/gameloop/include/timer.h b/mwe/gameloop/include/timer.h
new file mode 100644
index 0000000..a245e5c
--- /dev/null
+++ b/mwe/gameloop/include/timer.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <SDL2/SDL.h>
+
+class LoopTimer {
+public:
+ static LoopTimer& getInstance();
+ void start();
+ void update();
+ double getDeltaTime() const;
+ int getCurrentTime() const;
+ void advanceFixedUpdate();
+ double getFixedDeltaTime() const;
+ void setFPS(int FPS);
+ int getFPS() const;
+ void enforceFrameRate();
+ double getLag() const;
+private:
+ LoopTimer();
+ int FPS = 50;
+ double gameScale = 1;
+ double maximumDeltaTime = 0.25;
+ double deltaTime;
+ double frameTargetTime = FPS / 1000;
+ double fixedDeltaTime = 0.01;
+ double elapsedTime;
+ double elapsedFixedTime;
+ double time;
+ uint64_t lastFrameTime;
+};
diff --git a/mwe/gameloop/include/window.h b/mwe/gameloop/include/window.h
new file mode 100644
index 0000000..cfde0e9
--- /dev/null
+++ b/mwe/gameloop/include/window.h
@@ -0,0 +1,20 @@
+#pragma once
+#include <SDL2/SDL.h>
+#include <vector>
+#include "gameObject.h"
+#include <iostream>
+class WindowManager{
+ public:
+ WindowManager();
+ virtual ~WindowManager();
+ void render(std::vector<GameObject*> objects);
+ bool initWindow();
+ void destroyWindow();
+
+ SDL_Renderer* getRenderer();
+ private:
+ const int SCREEN_WIDTH = 800;
+ const int SCREEN_HEIGHT = 600;
+ SDL_Window* window = NULL;
+ SDL_Renderer* renderer = NULL;
+};
diff --git a/mwe/gameloop/src/eventManager.cpp b/mwe/gameloop/src/eventManager.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mwe/gameloop/src/eventManager.cpp
diff --git a/mwe/gameloop/src/gameObject.cpp b/mwe/gameloop/src/gameObject.cpp
new file mode 100644
index 0000000..f637314
--- /dev/null
+++ b/mwe/gameloop/src/gameObject.cpp
@@ -0,0 +1,58 @@
+#include "gameObject.h"
+std::string GameObject::getName() const{
+ return name;
+}
+float GameObject::getX() const{
+ return x;
+}
+
+float GameObject::getY() const{
+ return y;
+}
+
+float GameObject::getWidth() const{
+ return width;
+}
+
+float GameObject::getHeight() const{
+ return height;
+}
+
+float GameObject::getVelX() const{
+ return velX;
+}
+
+float GameObject::getVelY() const{
+ return velY;
+}
+void GameObject::setName(std::string value){
+ name = value;
+}
+void GameObject::setX(float value){
+ x = value;
+}
+
+void GameObject::setY(float value){
+ y = value;
+}
+
+void GameObject::setWidth(float value){
+ width = value;
+}
+
+void GameObject::setHeight(float value){
+ height = value;
+}
+
+void GameObject::setVelX(float value){
+ velX = value;
+}
+
+void GameObject::setVelY(float value){
+ velY = value;
+}
+
+GameObject::GameObject(std::string name, float x, float y, float width, float height, float velX, float velY)
+ : name(name),x(x), y(y), width(width), height(height), velX(velX), velY(velY) {
+
+ }
diff --git a/mwe/gameloop/src/loopManager.cpp b/mwe/gameloop/src/loopManager.cpp
new file mode 100644
index 0000000..f7ce886
--- /dev/null
+++ b/mwe/gameloop/src/loopManager.cpp
@@ -0,0 +1,72 @@
+#include "loopManager.h"
+#include "timer.h"
+LoopManager::LoopManager(){
+}
+void LoopManager::processInput(){
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ switch(event.type){
+ case SDL_QUIT:
+ gameRunning = false;
+ break;
+ case SDL_KEYDOWN:
+ if(event.key.keysym.sym == SDLK_ESCAPE){
+ gameRunning = false;
+ }
+ break;
+ }
+}
+void LoopManager::fixedUpdate(){
+ fprintf(stderr,"fixed update\n");
+}
+void LoopManager::loop() {
+ LoopTimer& timer = LoopTimer::getInstance();
+ timer.start();
+
+ while (gameRunning) {
+ timer.update();
+
+ while (timer.getLag() >= timer.getFixedDeltaTime()) {
+ processInput();
+ fixedUpdate();
+ timer.advanceFixedUpdate();
+ }
+
+ update();
+ render();
+
+ timer.enforceFrameRate();
+ }
+
+ window.destroyWindow();
+}
+
+void LoopManager::setup(){
+ gameRunning = window.initWindow();
+ LoopTimer::getInstance().start();
+ LoopTimer::getInstance().setFPS(50);
+
+ for(int i = 0; i < 2;i++){
+ GameObject* square = new GameObject("square2",i*40,i*40,20,20,0,0);
+ objectList.push_back(square);
+ }
+}
+void LoopManager::render(){
+ fprintf(stderr,"**********render********** \n");
+ if(gameRunning){
+ window.render(objectList);
+ }
+}
+
+void LoopManager::update() {
+ fprintf(stderr,"**********normal update********** \n");
+ LoopTimer& timer = LoopTimer::getInstance();
+
+ float delta= timer.getDeltaTime();
+
+ for (int i = 0; i < objectList.size(); i++) {
+ objectList[i]->setX(objectList[i]->getX() + 50 * delta);
+ objectList[i]->setY(objectList[i]->getY() + 50 * delta);
+ }
+}
+
diff --git a/mwe/gameloop/src/main.cpp b/mwe/gameloop/src/main.cpp
new file mode 100644
index 0000000..2333e63
--- /dev/null
+++ b/mwe/gameloop/src/main.cpp
@@ -0,0 +1,19 @@
+//Using SDL and standard IO
+#include <SDL2/SDL.h>
+#include <stdio.h>
+//#include "window.h"
+#include "loopManager.h"
+#include "timer.h"
+//Screen dimension constants
+
+
+//Starts up SDL and creates window
+
+int main( int argc, char* args[] )
+{
+ LoopManager gameLoop;
+ gameLoop.setup();
+ gameLoop.loop();
+
+ return 0;
+}
diff --git a/mwe/gameloop/src/timer.cpp b/mwe/gameloop/src/timer.cpp
new file mode 100644
index 0000000..1e3045f
--- /dev/null
+++ b/mwe/gameloop/src/timer.cpp
@@ -0,0 +1,68 @@
+#include "timer.h"
+
+// Constructor (private)
+LoopTimer::LoopTimer(){}
+
+// Get the singleton instance of the timer
+LoopTimer& LoopTimer::getInstance() {
+ static LoopTimer instance;
+ return instance;
+}
+
+// Start the timer (initialize frame time)
+void LoopTimer::start() {
+ lastFrameTime = SDL_GetTicks64();
+ elapsedTime = 0;
+ elapsedFixedTime = 0;
+ deltaTime = 0;
+}
+
+// Update the timer, calculate deltaTime
+void LoopTimer::update() {
+ uint64_t currentFrameTime = SDL_GetTicks64();
+ deltaTime = (currentFrameTime - lastFrameTime) / 1000.0; // Convert to seconds
+
+ if (deltaTime > maximumDeltaTime) {
+ deltaTime = maximumDeltaTime;
+ }
+
+ elapsedTime += deltaTime;
+ lastFrameTime = currentFrameTime;
+}
+
+double LoopTimer::getDeltaTime() const {
+ return deltaTime;
+}
+int LoopTimer::getCurrentTime() const {
+ return SDL_GetTicks();
+}
+
+void LoopTimer::advanceFixedUpdate() {
+ elapsedFixedTime += fixedDeltaTime;
+}
+
+double LoopTimer::getFixedDeltaTime() const {
+ return fixedDeltaTime;
+}
+
+void LoopTimer::setFPS(int FPS) {
+ this->FPS = FPS;
+ frameTargetTime = 1.0 / FPS;
+}
+
+int LoopTimer::getFPS() const {
+ return FPS;
+}
+
+void LoopTimer::enforceFrameRate() {
+ uint64_t currentFrameTime = SDL_GetTicks64();
+ double frameDuration = (currentFrameTime - lastFrameTime) / 1000.0;
+
+ if (frameDuration < frameTargetTime) {
+ uint32_t delayTime = (uint32_t)((frameTargetTime - frameDuration) * 1000.0);
+ SDL_Delay(delayTime);
+ }
+}
+double LoopTimer::getLag() const {
+ return elapsedTime - elapsedFixedTime;
+}
diff --git a/mwe/gameloop/src/window.cpp b/mwe/gameloop/src/window.cpp
new file mode 100644
index 0000000..f998a79
--- /dev/null
+++ b/mwe/gameloop/src/window.cpp
@@ -0,0 +1,60 @@
+#include "window.h"
+WindowManager::WindowManager(){
+ if( !initWindow() )
+ {
+ printf( "Failed to initialize!\n" );
+ }
+}
+WindowManager::~WindowManager(){
+ destroyWindow();
+}
+SDL_Renderer* WindowManager::getRenderer(){
+ return renderer;
+}
+
+void WindowManager::render(std::vector<GameObject*> objects){
+ // Set the draw color to black and clear the screen
+ SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
+ SDL_RenderClear(renderer);
+
+ // Print object position (optional for debugging)
+ //fprintf(stderr, "%d\n", objectList.size());
+ for(int i = 0; i < objects.size();i++){
+ //fprintf(stderr, "%f\n", objectList[i]->getX());
+ // Create a rectangle representing the ball
+ SDL_Rect ball_rect = {
+ (int)objects[i]->getX(),
+ (int)objects[i]->getY(),
+ (int)objects[i]->getWidth(),
+ (int)objects[i]->getHeight(),
+ };
+ // Set the draw color to white and render the ball
+ SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
+ SDL_RenderFillRect(renderer, &ball_rect);
+ }
+
+ SDL_RenderPresent(renderer);
+}
+
+bool WindowManager::initWindow(){
+ if(SDL_Init(SDL_INIT_EVERYTHING) != 0){
+ fprintf(stderr,"Error inititalising SDL.\n");
+ return false;
+ }
+ window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
+ if(!window){
+ fprintf(stderr,"Error creating SDL Window. \n");
+ return false;
+ }
+ renderer = SDL_CreateRenderer(window,-1,0);
+ if(!renderer){
+ fprintf(stderr,"Error creating SDL renderer. \n");
+ return false;
+ }
+ return true;
+}
+void WindowManager::destroyWindow(){
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+}
diff --git a/mwe/gameloop/versions/delayBased.cpp b/mwe/gameloop/versions/delayBased.cpp
new file mode 100644
index 0000000..a8cad15
--- /dev/null
+++ b/mwe/gameloop/versions/delayBased.cpp
@@ -0,0 +1,57 @@
+#include "loopManager.h"
+#include "timer.h"
+LoopManager::LoopManager(){
+}
+void LoopManager::processInput(){
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ switch(event.type){
+ case SDL_QUIT:
+ gameRunning = false;
+ break;
+ case SDL_KEYDOWN:
+ if(event.key.keysym.sym == SDLK_ESCAPE){
+ gameRunning = false;
+ }
+ break;
+ }
+}
+void LoopManager::loop(){
+ fprintf(stderr,"loop. \n");
+ while(gameRunning){
+ //Timer::getInstance().update();
+ //deltaTime = Timer::getInstance().getDeltaTime();
+ processInput();
+ update();
+ render();
+ }
+ window.destroyWindow();
+}
+void LoopManager::setup(){
+ gameRunning = window.initWindow();
+ LoopTimer::getInstance().start();
+ LoopTimer::getInstance().setFPS(210);
+
+ for(int i = 0; i < 2;i++){
+ GameObject* square2 = new GameObject("square2",i*40,i*40,20,20,0,0);
+ objectList.push_back(square2);
+ }
+}
+void LoopManager::render(){
+ if(gameRunning){
+ window.render(objectList);
+ }
+}
+
+void LoopManager::update() {
+ LoopTimer& timer = LoopTimer::getInstance();
+ timer.enforceFrameRate();
+ timer.update();
+ float delta= timer.getDeltaTime();
+
+ for (int i = 0; i < objectList.size(); i++) {
+ objectList[i]->setX(objectList[i]->getX() + 50 * delta);
+ objectList[i]->setY(objectList[i]->getY() + 50 * delta);
+ }
+}
+