/
IMainGame.cpp
171 lines (144 loc) · 4.91 KB
/
IMainGame.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <GL\glew.h>
#include "IMainGame.h"
#include "Timing.h"
#include "ScreenList.h"
#include "IGameScreen.h"
#include <iostream>
#include <algorithm>
namespace Adina {
IMainGame::IMainGame()
{
m_screenList = std::make_unique<ScreenList>(this);
}
IMainGame::~IMainGame()
{
// Empty
}
void IMainGame::run(std::string windowName)
{
if (!init(windowName)) return;
// Some helpful constants.
const float DESIRED_FPS = 60.0f; // FPS the game is designed to run at
const int MAX_PHYSICS_STEPS = 6; // Max number of physics steps per frame
const float MS_PER_SECOND = 1000; // Number of milliseconds in a second
const float DESIRED_FRAMETIME = MS_PER_SECOND / DESIRED_FPS; // The desired frame time per frame
const float MAX_DELTA_TIME = 1.0f; // Maximum size of deltaTime
FpsLimiter limiter;
limiter.setMaxtFPS(DESIRED_FPS);
// Start our previousTicks variable
float previousTicks = SDL_GetTicks();
// Game loop
m_isRunning = true;
while (m_isRunning)
{
limiter.begin();
// Calculate the frameTime in milliseconds
float newTicks = SDL_GetTicks();
float frameTime = newTicks - previousTicks;
previousTicks = newTicks; // Store newTicks in previousTicks so we can use it next frame
// Get the total delta time
float totalDeltaTime = frameTime / DESIRED_FRAMETIME;
// Call the custom update and draw method
inputManager.update();
int i = 0; // This counter makes sure we don't spiral to death!
// Loop while we still have steps to process.
while (totalDeltaTime > 0.0f && i < MAX_PHYSICS_STEPS) {
// The deltaTime should be the the smaller of the totalDeltaTime and MAX_DELTA_TIME
float deltaTime = std::min(totalDeltaTime, MAX_DELTA_TIME);
update(deltaTime);
// Since we just took a step that is length deltaTime, subtract from totalDeltaTime
totalDeltaTime -= deltaTime;
// Increment our frame counter so we can limit steps to MAX_PHYSICS_STEPS
i++;
}
draw();
m_fps = limiter.end();
m_window.swapBuffer();
}
}
void IMainGame::exitGame()
{
m_currentScreen->onExit();
if (m_screenList)
{
m_screenList->destroy();
m_screenList.reset();
}
m_isRunning = false;
}
void IMainGame::onSDLEvent(SDL_Event& evnt) {
switch (evnt.type) {
case SDL_QUIT:
exitGame();
break;
case SDL_MOUSEMOTION:
inputManager.setMouseCoords((float)evnt.motion.x, (float)evnt.motion.y);
break;
case SDL_KEYDOWN:
inputManager.pressKey(evnt.key.keysym.sym);
break;
case SDL_KEYUP:
inputManager.releaseKey(evnt.key.keysym.sym);
break;
case SDL_MOUSEBUTTONDOWN:
inputManager.pressKey(evnt.button.button);
break;
case SDL_MOUSEBUTTONUP:
inputManager.releaseKey(evnt.button.button);
break;
}
}
bool IMainGame::init(std::string windowName) {
Adina::init();
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
if (!initSystems(windowName)) return false;
onInit();
addScreens();
m_currentScreen = m_screenList->getCurrent();
m_currentScreen->onEntry();
m_currentScreen->setRunning();
return true;
}
bool IMainGame::initSystems(std::string windowName) {
m_window.create(windowName, 1350, 700, 0);
return true;
}
void IMainGame::update(float deltaTim) {
if (m_currentScreen) {
switch (m_currentScreen->getState()) {
case ScreenState::RUNNING:
m_currentScreen->update(deltaTim);
break;
case ScreenState::CHANGE_NEXT:
m_currentScreen->onExit();
m_currentScreen = m_screenList->moveNext();
if (m_currentScreen) {
m_currentScreen->setRunning();
m_currentScreen->onEntry();
}
break;
case ScreenState::CHANGE_PREVIOUS:
m_currentScreen->onExit();
m_currentScreen = m_screenList->movePrevious();
if (m_currentScreen) {
m_currentScreen->setRunning();
m_currentScreen->onEntry();
}
break;
case ScreenState::EXIT_APPLICATION:
exitGame();
break;
default:
break;
}
} else {
exitGame();
}
}
void IMainGame::draw() {
glViewport(0, 0, m_window.getScreenWidth(), m_window.getScreenHeight());
if (m_currentScreen && m_currentScreen->getState() == ScreenState::RUNNING) {
m_currentScreen->draw();
}
}
}