Created the UML diagrams, and started cleaning up the code in the new txts.

This commit is contained in:
Relintai 2021-04-09 18:39:03 +02:00
parent bbecc1abbf
commit b71371f0e1
8 changed files with 424 additions and 359 deletions

View File

@ -1,10 +1,14 @@
class Scene {
public:
virtual void event(const SDL_Event &ev) = 0;
virtual void update(float delta) = 0;
virtual void render() = 0;
Scene(); |---------------------------------------------------------------------------------------|
virtual ~Scene(); | class Scene |
}; |---------------------------------------------------------------------------------------|
| + virtual void event(const SDL_Event &ev) = 0 |
| + virtual void update(float delta) = 0 |
| + virtual void render() = 0 |
| |
| + Scene() |
| + virtual ~Scene() |
|---------------------------------------------------------------------------------------|

View File

@ -1,95 +1,96 @@
class Application {
public:
bool running;
int target_fps;
virtual void event(const SDL_Event &current_event); |---------------------------------------------------------------------------------------|
virtual void update(float delta); | class Application |
virtual void render(); |---------------------------------------------------------------------------------------|
| + bool running |
void main_loop(); | + int target_fps |
| |
Application(); | + virtual void event(const SDL_Event &current_event) |
virtual ~Application(); | + virtual void update(float delta) |
| + virtual void render() |
Scene *scene; | |
| + void main_loop() |
static Application* get_singleton(); | |
| + Application() |
double frame_delta = 0; | + virtual ~Application() |
| |
protected: | + Scene *scene |
static Application* _instance; | |
}; | + static Application* get_singleton() |
| |
| + double frame_delta = 0 |
| |
| # static Application* _instance |
|---------------------------------------------------------------------------------------|
Application* Application::_instance = nullptr; Application* Application::_instance = nullptr
#include <chrono> #include <chrono>
void Application::event(const SDL_Event &current_event) { void Application::event(const SDL_Event &current_event):
switch (current_event.type) { switch (current_event.type):
case SDL_QUIT: case SDL_QUIT:
running = false; running = false
break; break
}
scene->event(current_event); scene->event(current_event)
}
void Application::update(float delta) {
scene->update(delta);
}
void Application::render() {
scene->render();
Renderer::get_singleton()->present(); void Application::update(float delta):
} scene->update(delta)
void Application::main_loop() { void Application::render():
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); scene->render()
Renderer::get_singleton()->present()
void Application::main_loop():
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now()
//handle input //handle input
SDL_Event current_event; SDL_Event current_event
while (SDL_PollEvent(&current_event)) { while (SDL_PollEvent(&current_event)):
event(current_event); event(current_event)
}
update(frame_delta); update(frame_delta)
render(); render()
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now()
std::chrono::duration<double> elapsed_seconds = end - start; std::chrono::duration<double> elapsed_seconds = end - start
double t = elapsed_seconds.count(); double t = elapsed_seconds.count()
double tfps = 1.0 / static_cast<double>(target_fps); double tfps = 1.0 / static_cast<double>(target_fps)
double remaining = tfps - t; double remaining = tfps - t
if (remaining > 0) { if (remaining > 0):
Uint32 fms = static_cast<Uint32>(remaining * 1000.0); Uint32 fms = static_cast<Uint32>(remaining * 1000.0)
frame_delta = tfps; frame_delta = tfps
SDL_Delay(fms); SDL_Delay(fms)
} else { else:
frame_delta = t; frame_delta = t
}
}
Application::Application() {
running = true;
target_fps = 60;
scene = nullptr; Application::Application():
_instance = this; running = true
} target_fps = 60
Application::~Application() {
_instance = nullptr; scene = nullptr
} _instance = this
Application::~Application():
_instance = nullptr
Application* Application::get_singleton():
return _instance
Application* Application::get_singleton() {
return _instance;
}

View File

@ -49,7 +49,10 @@ MainScene::MainScene() {
b1->up = new Sprite(_texture); b1->up = new Sprite(_texture);
b1->down = new Sprite(_texture, Color(100, 100, 100)); b1->down = new Sprite(_texture, Color(100, 100, 100));
b1->hover = new Sprite(_texture, Color(200, 200, 200)); b1->hover = new Sprite(_texture, Color(200, 200, 200));
b1->on_click = MainScene::on_first_button_clicked;
//b1->on_click = MainScene::on_first_button_clicked;
b1->on_click = []() -> void { printf("Click lambda!"); };
b2 = new Button(); b2 = new Button();
b2->transform = Rect2(0, 110, 100, 100); b2->transform = Rect2(0, 110, 100, 100);

View File

@ -8,19 +8,19 @@
Renderer *renderer = nullptr; Renderer *renderer = nullptr;
Application *application = nullptr; Application *application = nullptr;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]):
renderer = new Renderer(); renderer = new Renderer();
application = new ImplApplication(); application = new ImplApplication();
while (application->running) { while (application->running):
application->main_loop(); application->main_loop();
}
delete application; delete application;
delete renderer; delete renderer;
return 0; return 0;
}
@ -40,24 +40,24 @@ int main(int argc, char *argv[]) {
Renderer *renderer = nullptr; Renderer *renderer = nullptr;
Application *application = nullptr; Application *application = nullptr;
void handle_frame() { void handle_frame():
application->main_loop(); application->main_loop();
}
int main(int argc, char *argv[]) {
int main(int argc, char *argv[]):
renderer = new Renderer(); renderer = new Renderer();
application = new APPLICATION_CLASS(); application = new APPLICATION_CLASS();
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
emscripten_set_main_loop(handle_frame, 0, 1); emscripten_set_main_loop(handle_frame, 0, 1);
#else #else
while (application->running) { while (application->running):
application->main_loop(); application->main_loop();
}
#endif #endif
delete application; delete application;
delete renderer; delete renderer;
return 0; return 0;
}

View File

@ -1,20 +1,21 @@
class MainScene : public Scene { |---------------------------------------------------------------------------------------|
public: | class MainScene : public Scene |
void event(const SDL_Event &ev); |---------------------------------------------------------------------------------------|
void update(float delta); | + void event(const SDL_Event &ev) |
void render(); | + void update(float delta) |
| + void render() |
MainScene(); | |
~MainScene(); | + MainScene() |
| + ~MainScene() |
Camera *_camera; | |
Image *_image; | + Camera *_camera |
Texture *_texture; | + Image *_image |
Sprite *_sprite; | + Texture *_texture |
int _dir; | + Sprite *_sprite |
}; | + int _dir |
|---------------------------------------------------------------------------------------|
#include "main_scene.h" #include "main_scene.h"
@ -22,48 +23,48 @@ public:
#include "renderer.h" #include "renderer.h"
void MainScene::event(const SDL_Event &ev) { void MainScene::event(const SDL_Event &ev):
}
void MainScene::update(float delta) {
}
void MainScene::render() { void MainScene::update(float delta):
Renderer::get_singleton()->clear();
_camera->viewport.x += _dir;
void MainScene::render():
Renderer::get_singleton()->clear()
_camera->viewport.x += _dir
if (_camera->viewport.x <= -100) if (_camera->viewport.x <= -100)
_dir = 1; _dir = 1
else if (_camera->viewport.x >= 100) else if (_camera->viewport.x >= 100)
_dir = -1; _dir = -1
_camera->bind(); _camera->bind()
_sprite->draw(); _sprite->draw()
}
MainScene::MainScene() {
_camera = new Camera();
_image = new Image("ti.bmp");
_texture = new Texture(_image);
_sprite = new Sprite(_texture);
_sprite->set_x(30); MainScene::MainScene():
_sprite->set_y(30); _camera = new Camera()
_image = new Image("ti.bmp")
_texture = new Texture(_image)
_sprite = new Sprite(_texture)
_dir = 1; _sprite->set_x(30)
} _sprite->set_y(30)
MainScene::~MainScene() { _dir = 1
_texture->free();
_image->free();
MainScene::~MainScene():
_texture->free()
_image->free()
delete _sprite
delete _texture
delete _image
delete _camera
delete _sprite;
delete _texture;
delete _image;
delete _camera;
}
@ -77,14 +78,14 @@ MainScene::~MainScene() {
#include "main_scene.h" #include "main_scene.h"
class ImplApplication : public Application { class ImplApplication : public Application:
public: public:
ImplApplication() : Application() { ImplApplication() : Application():
scene = new MainScene(); scene = new MainScene()
}
~ImplApplication() { ~ImplApplication():
delete scene; delete scene
}
};
#endif #endif

View File

@ -1,22 +1,25 @@
class MainScene : public Scene {
public:
void event(const SDL_Event &ev);
void update(float delta);
void render();
MainScene();
~MainScene();
Camera *_camera; |---------------------------------------------------------------------------------------|
Image *_image; | class MainScene : public Scene |
Texture *_texture; |---------------------------------------------------------------------------------------|
Sprite *_sprite; | + void event(const SDL_Event &ev) |
| + void update(float delta) |
bool _up; | + void render() |
bool _down; | |
bool _left; | + MainScene() |
bool _right; | + ~MainScene() |
}; | |
| + Camera *_camera |
| + Image *_image |
| + Texture *_texture |
| + Sprite *_sprite |
| |
| + bool _up |
| + bool _down |
| + bool _left |
| + bool _right |
|---------------------------------------------------------------------------------------|
#include "main_scene.h" #include "main_scene.h"
@ -26,97 +29,97 @@ public:
#include <SDL.h> #include <SDL.h>
void MainScene::event(const SDL_Event &ev) { void MainScene::event(const SDL_Event &ev):
switch (ev.type) { switch (ev.type):
case SDL_WINDOWEVENT: { case SDL_WINDOWEVENT::
switch (ev.window.event) { switch (ev.window.event):
case SDL_WINDOWEVENT_SIZE_CHANGED: { case SDL_WINDOWEVENT_SIZE_CHANGED::
int width = ev.window.data1; int width = ev.window.data1
int height = ev.window.data2; int height = ev.window.data2
_camera->viewport = Rect2(0, 0, width, height); _camera->viewport = Rect2(0, 0, width, height)
break; break
}
}
break; break
}
case SDL_KEYDOWN: { case SDL_KEYDOWN::
if (ev.key.keysym.scancode == SDL_SCANCODE_A) { if (ev.key.keysym.scancode == SDL_SCANCODE_A):
_left = true; _left = true
} else if (ev.key.keysym.scancode == SDL_SCANCODE_W) { else if (ev.key.keysym.scancode == SDL_SCANCODE_W):
_up = true; _up = true
} else if (ev.key.keysym.scancode == SDL_SCANCODE_S) { else if (ev.key.keysym.scancode == SDL_SCANCODE_S):
_down = true; _down = true
} else if (ev.key.keysym.scancode == SDL_SCANCODE_D) { else if (ev.key.keysym.scancode == SDL_SCANCODE_D):
_right = true; _right = true
}
break; break
}
case SDL_KEYUP: { case SDL_KEYUP::
if (ev.key.keysym.scancode == SDL_SCANCODE_A) { if (ev.key.keysym.scancode == SDL_SCANCODE_A):
_left = false; _left = false
} else if (ev.key.keysym.scancode == SDL_SCANCODE_W) { else if (ev.key.keysym.scancode == SDL_SCANCODE_W):
_up = false; _up = false
} else if (ev.key.keysym.scancode == SDL_SCANCODE_S) { else if (ev.key.keysym.scancode == SDL_SCANCODE_S):
_down = false; _down = false
} else if (ev.key.keysym.scancode == SDL_SCANCODE_D) { else if (ev.key.keysym.scancode == SDL_SCANCODE_D):
_right = false; _right = false
}
break; break
}
}
}
void MainScene::update(float delta) {
if (_up) {
_sprite->set_y(_sprite->get_y() - 50 * delta);
}
if (_down) { void MainScene::update(float delta):
_sprite->set_y(_sprite->get_y() + 50 * delta); if (_up):
} _sprite->set_y(_sprite->get_y() - 50 * delta)
if (_left) { if (_down):
_sprite->set_x(_sprite->get_x() - 50 * delta); _sprite->set_y(_sprite->get_y() + 50 * delta)
}
if (_right) { if (_left):
_sprite->set_x(_sprite->get_x() + 50 * delta); _sprite->set_x(_sprite->get_x() - 50 * delta)
}
}
void MainScene::render() { if (_right):
Renderer::get_singleton()->clear(); _sprite->set_x(_sprite->get_x() + 50 * delta)
_camera->bind();
Renderer::get_singleton()->draw_sprite(_sprite); void MainScene::render():
} Renderer::get_singleton()->clear()
MainScene::MainScene() { _camera->bind()
_camera = new Camera();
_image = new Image("ti.bmp");
_texture = new Texture(_image);
_sprite = new Sprite(_texture);
_up = false; Renderer::get_singleton()->draw_sprite(_sprite)
_down = false;
_left = false;
_right = false;
}
MainScene::~MainScene() {
_texture->free();
_image->free();
delete _sprite; MainScene::MainScene():
delete _texture; _camera = new Camera()
delete _image; _image = new Image("ti.bmp")
delete _camera; _texture = new Texture(_image)
} _sprite = new Sprite(_texture)
_up = false
_down = false
_left = false
_right = false
MainScene::~MainScene():
_texture->free()
_image->free()
delete _sprite
delete _texture
delete _image
delete _camera

View File

@ -1,134 +1,187 @@
Írjunk egy gomb (Button) osztályt.
#include <functional> Látjátok, hogy az UML diagramba raktam egy nem standard ábrázolást.
Itt csak az a lényeg, hogy innen elég 1 megoldást választani.
Az itteni változók függvénymutatók letárolására valók.
Nem olyan szépek sajnos, mert mindkét esetben statikus függvényt lehet csak
beléjük rakni, (vagy lambda függvényt - lást kicsit lejjebb -), viszont
a tagfüggvények eoltárolására a kód ennél jóval rosszabbul néz ki, ezért
úgy döntöttem, hogy azt nem rakom bele. Akit érdekel keresgéljen rá.
Érdemes a <functional> (std::functional) dokumentációját is nézegetni,
ott is van sok infó erről.
(Igazából ajánlom, hogy próbálgassatok ki több más módszert is, mert
elég sok van.)
class Button { Lambda függvény == Anoním függvény == név nélküli függvény
public:
enum ButtonState { így kell lértehozni:
BUTTON_STATE_UP,
BUTTON_STATE_HOVER, [ capture clause ] (parameters) -> return-type
BUTTON_STATE_DOWN, {
BUTTON_STATE_OFF, definition of method
}
[ Az ide rakott változók elérhetőek lesznek majd a függvényben ] (paraméterek) -> visszatérési típus
{
kód
}
Nyilván, mivel nincs neve, ezért nem igazán lehet csak úgy meghívogatni, kivéve,
ha eltároljuk egy függvénymutatóban!
Azaz az A verzióval az on_click változóba így lehet egy lambda függvényt belerakni:
void Application::test() {
button->on_click = []() -> void { printf("Click lambda!"); };
button->on_click = [this]() -> void {
/* itt lehet majd használni a test() függvényben elérhető "this" pointert. */
printf("Click lambda!");
}; };
void event(const SDL_Event &ev); int a = 10;
void update(float delta); button->on_click = [a]() -> void {
void render(); /* itt lehet majd használni a test() függvényben elérhető "a" változót. */
printf("Click lambda!");
};
//ver a: (Csak statikus fv állítható be rá) button->on_click = [&]() -> void {
std::function<void(void)> on_click; /* itt lehet majd használni a test() függvényben elérhető összes változót. */
printf("Click lambda!");
};
}
//ver b: (Képes osztályok függvényeit is meghívni) Ez az include kelleni fog: #include <functional>
//Meg lehet oldani sokféleképp, egyik sem annyira szép sajnos
//mindneképp érdemes lenne setter mögé rejteni ezeket
void* cls;
std::function<void(void*)> on_click_member;
Button(); És akkor az osztály:
virtual ~Button();
ButtonState state; |---------------------------------------------------------------------------------------|
| class Button |
Rect2 transform; |---------------------------------------------------------------------------------------|
| + enum ButtonState { BUTTON_STATE_UP, BUTTON_STATE_HOVER, |
Sprite *up; | BUTTON_STATE_DOWN, BUTTON_STATE_OFF } |
Sprite *down; | |
Sprite *hover; | + void event(const SDL_Event &ev) |
Sprite *off; | + void update(float delta) |
}; | + void render() |
| |
| ----------------------------------------------------------------- |
| | A.Verzió: (Csak statikus fv állítható be rá) | |
| | + std::function<void(void)> on_click | |
| | ------------------------------------------------ | |
| | B Verzió: (Képes osztályok függvényeit is meghívni) | |
| | Meg lehet oldani sokféleképp, egyik sem annyira szép sajnos | |
| | mindneképp érdemes lenne setter mögé rejteni ezeket | |
| | + void* cls | |
| | + std::function<void(void*)> on_click_member | |
| ------------------------------------------------------------------ |
| |
| + Button() |
| + virtual ~Button() |
| |
| + ButtonState state |
| |
| + Rect2 transform |
| |
| + Sprite *up |
| + Sprite *down |
| + Sprite *hover |
| + Sprite *off |
|---------------------------------------------------------------------------------------|
#include "button.h" #include "button.h"
#include "math.h" #include "math.h"
void Button::event(const SDL_Event &ev) { void Button::event(const SDL_Event &ev)
if (state == BUTTON_STATE_OFF) { if (state == BUTTON_STATE_OFF)
return; return
}
switch (ev.type) { switch (ev.type)
case SDL_MOUSEMOTION: { case SDL_MOUSEMOTION:
int x = ev.motion.x; int x = ev.motion.x
int y = ev.motion.y; int y = ev.motion.y
if (transform.x < x && transform.x + transform.w > x && transform.y < y && transform.y + transform.w > y) { if (transform.x < x && transform.x + transform.w > x && transform.y < y && transform.y + transform.w > y)
state = BUTTON_STATE_HOVER; state = BUTTON_STATE_HOVER
} else { else
state = BUTTON_STATE_UP; state = BUTTON_STATE_UP
}
break; break
}
case SDL_MOUSEBUTTONDOWN: { case SDL_MOUSEBUTTONDOWN:
int x = ev.motion.x; int x = ev.motion.x
int y = ev.motion.y; int y = ev.motion.y
if (transform.x < x && transform.x + transform.w > x && transform.y < y && transform.y + transform.w > y) { if (transform.x < x && transform.x + transform.w > x && transform.y < y && transform.y + transform.w > y)
state = BUTTON_STATE_DOWN; state = BUTTON_STATE_DOWN
}
break; break
}
case SDL_MOUSEBUTTONUP: { case SDL_MOUSEBUTTONUP:
int x = ev.motion.x; int x = ev.motion.x
int y = ev.motion.y; int y = ev.motion.y
if (transform.x < x && transform.x + transform.w > x && transform.y < y && transform.y + transform.w > y) { if (transform.x < x && transform.x + transform.w > x && transform.y < y && transform.y + transform.w > y)
state = BUTTON_STATE_HOVER; state = BUTTON_STATE_HOVER
if (on_click) { if (on_click)
on_click(); on_click()
}
if (on_click_member) { if (on_click_member)
on_click_member(cls); on_click_member(cls)
}
} else { else
state = BUTTON_STATE_UP; state = BUTTON_STATE_UP
}
break; break
}
}
}
void Button::update(float delta) { void Button::update(float delta)
}
void Button::render() { void Button::render()
if (state == BUTTON_STATE_UP) { if (state == BUTTON_STATE_UP)
if (up) { if (up)
up->set_transform(transform); up->set_transform(transform)
up->draw(); up->draw()
}
} else if (state == BUTTON_STATE_HOVER) { else if (state == BUTTON_STATE_HOVER)
if (hover) { if (hover)
hover->set_transform(transform); hover->set_transform(transform)
hover->draw(); hover->draw()
}
} else if (state == BUTTON_STATE_DOWN) { else if (state == BUTTON_STATE_DOWN)
if (down) { if (down)
down->set_transform(transform); down->set_transform(transform)
down->draw(); down->draw()
}
} else if (state == BUTTON_STATE_OFF) { else if (state == BUTTON_STATE_OFF)
if (off) { if (off)
off->set_transform(transform); off->set_transform(transform)
off->draw(); off->draw()
}
}
}
Button::Button() { Button::Button()
state = BUTTON_STATE_UP; state = BUTTON_STATE_UP
up = nullptr; up = nullptr
down = nullptr; down = nullptr
hover = nullptr; hover = nullptr
off = nullptr; off = nullptr
}
Button::~Button() { Button::~Button()
}

View File

@ -1,5 +1,5 @@
class MainScene : public Scene { class MainScene : public Scene:
public: public:
void event(const SDL_Event &ev); void event(const SDL_Event &ev);
void update(float delta); void update(float delta);
@ -22,7 +22,7 @@ public:
Button *b1; Button *b1;
Button *b2; Button *b2;
Button *b3; Button *b3;
}; ;
#include "main_scene.h" #include "main_scene.h"
@ -34,16 +34,16 @@ public:
#include <stdio.h> #include <stdio.h>
void MainScene::event(const SDL_Event &ev) { void MainScene::event(const SDL_Event &ev):
b1->event(ev); b1->event(ev);
b2->event(ev); b2->event(ev);
b3->event(ev); b3->event(ev);
}
void MainScene::update(float delta) {
}
void MainScene::render() { void MainScene::update(float delta):
void MainScene::render():
Renderer::get_singleton()->clear(); Renderer::get_singleton()->clear();
_camera->bind(); _camera->bind();
@ -51,22 +51,22 @@ void MainScene::render() {
b1->render(); b1->render();
b2->render(); b2->render();
b3->render(); b3->render();
}
void MainScene::on_first_button_clicked() {
void MainScene::on_first_button_clicked():
printf("Click!\n"); printf("Click!\n");
}
void MainScene::on_first_button_clicked_member(void* cls) {
if (cls) { void MainScene::on_first_button_clicked_member(void* cls):
if (cls):
reinterpret_cast<MainScene*>(cls)->member_print(); reinterpret_cast<MainScene*>(cls)->member_print();
}
}
void MainScene::member_print() {
printf("Click Member!\n");
}
MainScene::MainScene() { void MainScene::member_print():
printf("Click Member!\n");
MainScene::MainScene():
_camera = new Camera(); _camera = new Camera();
_image = new Image("ti.bmp"); _image = new Image("ti.bmp");
_texture = new Texture(_image); _texture = new Texture(_image);
@ -90,9 +90,9 @@ MainScene::MainScene() {
b3->hover = new Sprite(_texture, Color(200, 200, 200)); b3->hover = new Sprite(_texture, Color(200, 200, 200));
b3->cls = this; b3->cls = this;
b3->on_click_member = MainScene::on_first_button_clicked_member; b3->on_click_member = MainScene::on_first_button_clicked_member;
}
MainScene::~MainScene() {
MainScene::~MainScene():
_texture->free(); _texture->free();
_image->free(); _image->free();
@ -112,6 +112,6 @@ MainScene::~MainScene() {
delete _texture; delete _texture;
delete _image; delete _image;
delete _camera; delete _camera;
}