aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gameloop/.vscode/settings.json54
-rw-r--r--gameloop/CMakeLists.txt2
-rw-r--r--gameloop/include/gameObject.h29
-rw-r--r--gameloop/include/loopManager.h14
-rw-r--r--gameloop/include/timer.h31
-rw-r--r--gameloop/include/window.h12
-rw-r--r--gameloop/src/gameObject.cpp58
-rw-r--r--gameloop/src/loopManager.cpp41
-rw-r--r--gameloop/src/main.cpp2
-rw-r--r--gameloop/src/timer.cpp56
-rw-r--r--gameloop/src/window.cpp38
-rw-r--r--gameloop/versions/delayBased.cpp57
12 files changed, 366 insertions, 28 deletions
diff --git a/gameloop/.vscode/settings.json b/gameloop/.vscode/settings.json
new file mode 100644
index 0000000..6cee9cb
--- /dev/null
+++ b/gameloop/.vscode/settings.json
@@ -0,0 +1,54 @@
+{
+ "files.associations": {
+ "array": "cpp",
+ "atomic": "cpp",
+ "bit": "cpp",
+ "*.tcc": "cpp",
+ "cctype": "cpp",
+ "clocale": "cpp",
+ "cmath": "cpp",
+ "compare": "cpp",
+ "concepts": "cpp",
+ "cstdarg": "cpp",
+ "cstddef": "cpp",
+ "cstdint": "cpp",
+ "cstdio": "cpp",
+ "cstdlib": "cpp",
+ "cwchar": "cpp",
+ "cwctype": "cpp",
+ "deque": "cpp",
+ "list": "cpp",
+ "map": "cpp",
+ "string": "cpp",
+ "unordered_map": "cpp",
+ "vector": "cpp",
+ "exception": "cpp",
+ "algorithm": "cpp",
+ "functional": "cpp",
+ "iterator": "cpp",
+ "memory": "cpp",
+ "memory_resource": "cpp",
+ "numeric": "cpp",
+ "optional": "cpp",
+ "random": "cpp",
+ "string_view": "cpp",
+ "system_error": "cpp",
+ "tuple": "cpp",
+ "type_traits": "cpp",
+ "utility": "cpp",
+ "initializer_list": "cpp",
+ "iosfwd": "cpp",
+ "iostream": "cpp",
+ "istream": "cpp",
+ "limits": "cpp",
+ "new": "cpp",
+ "numbers": "cpp",
+ "ostream": "cpp",
+ "sstream": "cpp",
+ "stdexcept": "cpp",
+ "streambuf": "cpp",
+ "cinttypes": "cpp",
+ "typeinfo": "cpp",
+ "valarray": "cpp"
+ }
+}
diff --git a/gameloop/CMakeLists.txt b/gameloop/CMakeLists.txt
index 16cbcf3..6bc5017 100644
--- a/gameloop/CMakeLists.txt
+++ b/gameloop/CMakeLists.txt
@@ -14,6 +14,8 @@ set(SOURCES
src/window.cpp
src/main.cpp
src/eventManager.cpp
+ src/gameObject.cpp
+ src/timer.cpp
)
add_executable(gameloop ${SOURCES})
diff --git a/gameloop/include/gameObject.h b/gameloop/include/gameObject.h
new file mode 100644
index 0000000..0e17991
--- /dev/null
+++ b/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/gameloop/include/loopManager.h b/gameloop/include/loopManager.h
index 03b07a9..5ed918d 100644
--- a/gameloop/include/loopManager.h
+++ b/gameloop/include/loopManager.h
@@ -1,6 +1,7 @@
#pragma once
#include <SDL2/SDL.h>
#include "window.h"
+#include "gameObject.h"
class LoopManager{
public:
LoopManager();
@@ -8,11 +9,18 @@ class LoopManager{
void loop();
private:
-
+ std::vector<GameObject*> objectList;
void processInput();
void update();
+ void lateUpdate();
+ void fixedUpdate();
void render();
- bool gameRunning;
+ bool gameRunning = false;
WindowManager window;
-
+ int timeScale = 1;
+ float lag = 0.0;
+ double currentTime;
+ double t = 0.0;
+ double dt = 0.01;
+ state previous;
};
diff --git a/gameloop/include/timer.h b/gameloop/include/timer.h
new file mode 100644
index 0000000..2769e4d
--- /dev/null
+++ b/gameloop/include/timer.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <SDL2/SDL.h>
+
+class LoopTimer {
+public:
+ static LoopTimer& getInstance();
+ void start();
+ void update();
+ float getDeltaTime() const;
+ float getDeltaTimeMs() const;
+ float getFixedDeltaTime() const;
+ int getCurrentTime() const;
+ void setFPS(int FPS);
+ int getFPS() const;
+ void enforceFrameRate();
+ float getLag() const;
+private:
+ LoopTimer();
+ int FPS = 30;
+ float frameTargetTime = FPS / 1000;
+ int lastTime;
+ float fixedDeltaTime = 2;
+ float maxDeltaTime = 1;
+ float fixedTime = 0;
+ int lastFrameTime;
+ float deltaTime;
+ float time = 0;
+ int frequency;
+ float lag;
+};
diff --git a/gameloop/include/window.h b/gameloop/include/window.h
index b4f2b78..cfde0e9 100644
--- a/gameloop/include/window.h
+++ b/gameloop/include/window.h
@@ -1,20 +1,18 @@
#pragma once
#include <SDL2/SDL.h>
+#include <vector>
+#include "gameObject.h"
+#include <iostream>
class WindowManager{
public:
WindowManager();
virtual ~WindowManager();
- bool loadMedia();
- void update();
- bool init();
- void close();
+ void render(std::vector<GameObject*> objects);
bool initWindow();
void destroyWindow();
+
SDL_Renderer* getRenderer();
private:
- //Loads media
- //Frees media and shuts down SDL
-
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
SDL_Window* window = NULL;
diff --git a/gameloop/src/gameObject.cpp b/gameloop/src/gameObject.cpp
new file mode 100644
index 0000000..f637314
--- /dev/null
+++ b/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/gameloop/src/loopManager.cpp b/gameloop/src/loopManager.cpp
index ef2decf..c439a3e 100644
--- a/gameloop/src/loopManager.cpp
+++ b/gameloop/src/loopManager.cpp
@@ -1,4 +1,5 @@
#include "loopManager.h"
+#include "timer.h"
LoopManager::LoopManager(){
}
void LoopManager::processInput(){
@@ -15,23 +16,53 @@ void LoopManager::processInput(){
break;
}
}
+void LoopManager::fixedUpdate(){
+ fprintf(stderr,"fixed update\n");
+}
void LoopManager::loop(){
+ fprintf(stderr,"loop. \n");
+ LoopTimer& timer = LoopTimer::getInstance();
while(gameRunning){
- //processInput();
+ timer.update();
+ lag += timer.getDeltaTime();
+ processInput();
+ while (lag >= timer.getFixedDeltaTime())
+ {
+ fixedUpdate();
+ lag -= timer.getFixedDeltaTime();
+ }
//update();
- //render();
+ //timer.enforceFrameRate();
+ render();
}
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){
- SDL_SetRenderDrawColor(window.getRenderer(),255,0,0,255);
- SDL_RenderClear(window.getRenderer());
+ window.render(objectList);
}
}
-void LoopManager::update(){
+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/gameloop/src/main.cpp b/gameloop/src/main.cpp
index 76d0c84..2333e63 100644
--- a/gameloop/src/main.cpp
+++ b/gameloop/src/main.cpp
@@ -3,6 +3,7 @@
#include <stdio.h>
//#include "window.h"
#include "loopManager.h"
+#include "timer.h"
//Screen dimension constants
@@ -13,5 +14,6 @@ int main( int argc, char* args[] )
LoopManager gameLoop;
gameLoop.setup();
gameLoop.loop();
+
return 0;
}
diff --git a/gameloop/src/timer.cpp b/gameloop/src/timer.cpp
new file mode 100644
index 0000000..6428797
--- /dev/null
+++ b/gameloop/src/timer.cpp
@@ -0,0 +1,56 @@
+#include "timer.h"
+
+// Singleton instance for global access
+LoopTimer& LoopTimer::getInstance() {
+ static LoopTimer instance;
+ return instance;
+}
+
+// Private constructor
+LoopTimer::LoopTimer() : lastTime(0), deltaTime(0), frequency(0), FPS(0), frameTargetTime(0) {}
+
+void LoopTimer::start() {
+
+}
+
+void LoopTimer::update() {
+ Uint64 currentTime = SDL_GetTicks64();
+ deltaTime = (currentTime - lastFrameTime) / 1000.0;
+ time += deltaTime;
+ lastFrameTime = currentTime;
+}
+
+float LoopTimer::getDeltaTime() const {
+ return deltaTime;
+}
+float LoopTimer::getDeltaTimeMs() const {
+ return deltaTime * 1000;
+}
+int LoopTimer::getCurrentTime() const {
+ return SDL_GetTicks64();
+}
+
+float LoopTimer::getFixedDeltaTime() const {
+ return fixedDeltaTime;
+}
+
+void LoopTimer::setFPS(int FPS) {
+ if (FPS > 0) {
+ this->FPS = FPS;
+ frameTargetTime = 1000 / FPS;
+ }
+}
+float LoopTimer::getLag() const{
+ return lag;
+}
+int LoopTimer::getFPS() const {
+ return FPS;
+}
+
+// Delay to match target frame time
+void LoopTimer::enforceFrameRate() {
+ int waitTime = frameTargetTime - (SDL_GetTicks64() - lastFrameTime);
+ if(waitTime > 0 && waitTime <= frameTargetTime){
+ SDL_Delay(waitTime);
+ }
+}
diff --git a/gameloop/src/window.cpp b/gameloop/src/window.cpp
index 11424dd..f998a79 100644
--- a/gameloop/src/window.cpp
+++ b/gameloop/src/window.cpp
@@ -1,5 +1,4 @@
#include "window.h"
-
WindowManager::WindowManager(){
if( !initWindow() )
{
@@ -9,27 +8,40 @@ WindowManager::WindowManager(){
WindowManager::~WindowManager(){
destroyWindow();
}
-bool WindowManager::init()
-{
-}
-bool WindowManager::loadMedia()
-{
-}
-void WindowManager::close()
-{
-
-}
SDL_Renderer* WindowManager::getRenderer(){
return renderer;
}
-void WindowManager::update(){
+
+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("Gameloop POC",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,SCREEN_WIDTH,SCREEN_HEIGHT,SDL_WINDOW_RESIZABLE);
+ 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;
diff --git a/gameloop/versions/delayBased.cpp b/gameloop/versions/delayBased.cpp
new file mode 100644
index 0000000..a8cad15
--- /dev/null
+++ b/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);
+ }
+}
+