-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseGame.cpp
More file actions
165 lines (129 loc) · 4.14 KB
/
BaseGame.cpp
File metadata and controls
165 lines (129 loc) · 4.14 KB
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
#include "BaseGame.hpp"
namespace Framework {
BaseGame::BaseGame() {
}
bool BaseGame::run() {
// Initialise SDL and globals - if it fails, don't run program
if (!init()) {
return false;
}
// Allow game to get ready
// Game must set stage ptr
start();
stage->init(&graphics_objects, &input);
// Main game loop
bool running = true;
while (running) {
running = main_loop();
}
// Allow game to clean up
end();
// Quit everything
quit();
return true;
}
// Limit framerate and get approximate dt
// Limiting is inaccurate: alright for 60fps (+/- ~2fps), 120fps gets inaccurate (+/- ~10fps) and higher framerates are worse.
// This is due to SDL working in milliseconds, so we can't do any better than 1000/17 = 111 fps or 1000/8 = 125 fps
bool BaseGame::main_loop() {
// Get start time
uint32_t start_time = SDL_GetTicks();
// 'Calculate' dt
//float dt = WINDOW::TARGET_DT;
// Or we could get last frame's dt - this is better
float dt = (start_time - last_time) / 1000.0f;
last_time = start_time;
// Cap dt - stops game skipping time when window is dragged (which caused objects to phase through other objects)
// Essentially makes game run slower if dt < MAX_DT
// While window is dragged, dt accumulates because main_loop isn't called, so dt because very large
dt = std::min(dt, WINDOW::MAX_DT);
// Update input handler (updates all key states etc)
input.update();
// Handle events
SDL_Event sdl_event;
while (SDL_PollEvent(&sdl_event) != 0) {
switch (sdl_event.type) {
case SDL_QUIT:
// X (close) is pressed
return false;
case SDL_KEYDOWN:
case SDL_KEYUP:
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEWHEEL:
// Delegate to InputHandler
input.handle_sdl_event(sdl_event);
break;
default:
break;
}
}
bool running = update(dt);
// Clear the screen
/*SDLUtils::SDL_SetRenderDrawColor(renderer, COLOURS::BLACK);
SDL_RenderClear(renderer);*/
graphics_objects.graphics.fill(COLOURS::BLACK);
// Render game
render();
// Update screen
SDL_RenderPresent(renderer);
// If we were too quick, sleep!
uint32_t end_time = SDL_GetTicks();
uint32_t difference = end_time - start_time;
int ticks_to_sleep = static_cast<int>(WINDOW::TARGET_DT * 1000.0f) - difference;
if (ticks_to_sleep > 0) {
SDL_Delay(ticks_to_sleep);
}
//printf("FPS: %f\n", 1.0f / dt);
return running;
}
bool BaseGame::update(float dt) {
if (stage->finished()) {
// Allow user to clear up anything
stage->end();
if (stage->delete_me()) {
BaseStage* temp_stage = stage->next();
delete stage;
stage = temp_stage;
}
else {
stage = stage->next();
}
// Setup next stage
stage->init(&graphics_objects, &input);
}
bool running = stage->update(dt);
return running;
}
void BaseGame::render() {
stage->render();
}
bool BaseGame::init() {
// Prep SDL, return false if it fails
if (!Framework::SDLUtils::init_sdl(window, renderer, WINDOW::TITLE, WINDOW::SIZE)) {
return false;
}
// Create Graphics and Window instances
graphics_objects.graphics = Graphics();
graphics_objects.graphics.set_renderer(renderer);
graphics_objects.window = Window();
graphics_objects.window.set_window(window);
// Set up graphics_objects vectors:
graphics_objects.image_ptrs = std::vector<std::unique_ptr<Framework::Image>>(GRAPHICS_OBJECTS::IMAGES::TOTAL_IMAGES);
graphics_objects.spritesheets = std::vector<Framework::Spritesheet>(GRAPHICS_OBJECTS::SPRITESHEETS::TOTAL_SPRITESHEETS);
graphics_objects.fonts = std::vector<Framework::Font>(GRAPHICS_OBJECTS::FONTS::TOTAL_FONTS);
graphics_objects.transition_ptrs = std::vector<std::unique_ptr<Framework::BaseTransition>>(GRAPHICS_OBJECTS::TRANSITIONS::TOTAL_TRANSITIONS);
graphics_objects.button_image_groups = std::vector<Framework::Button::ButtonImages>(GRAPHICS_OBJECTS::BUTTON_IMAGE_GROUPS::TOTAL_BUTTON_IMAGE_GROUPS);
// Load game data
load_data();
return true;
}
void BaseGame::quit() {
// Clear game data
clear_data();
// Destroy renderer and window
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
}