Ich mache ein kleines Spiel in C. Ich versuche, objektorientiert mit Funktionszeigern zu programmieren.
Ich wollte diese Zeit wirklich vorantreiben und nicht übertreiben, Dinge zu generisch zu machen, ich verliere mich oft darin. Die Verwendung von einfachem altem C hat mir sehr geholfen, schneller und besser zu programmieren.Generische/OO-ähnliche Programmierung in C unter Vermeidung von Symbolkonflikten
Derzeit beschreibe ich „Game states“ mit:
/* macros */
#define SETUP_ROUTINE(component) component##_##setup_routine
#define DRAW_ROUTINE(component) component##_##draw_routine
#define EVENT_ROUTINE(component) component##_##event_routine
#define UPDATE_ROUTINE(component) component##_##update_routine
#define TEARDOWN_ROUTINE(component) component##_##teardown_routine
#define SETUP_ROUTINE_SIGNATURE void
#define DRAW_ROUTINE_SIGNATURE void
#define EVENT_ROUTINE_SIGNATURE SDL_Event evt, int * quit
#define UPDATE_ROUTINE_SIGNATURE double t, float dt
#define TEARDOWN_ROUTINE_SIGNATURE void
/* data */
typedef enum GameStateType {
GAME_STATE_MENU,
GAME_STATE_LEVELSELECT,
...
} GameStateType;
typedef struct GameState {
GameStateType state;
GameStateType nextState;
GameStateType prevState;
void (*setup_routine)(SETUP_ROUTINE_SIGNATURE);
void (*draw_routine)(DRAW_ROUTINE_SIGNATURE);
void (*event_routine)(EVENT_ROUTINE_SIGNATURE);
void (*update_routine)(UPDATE_ROUTINE_SIGNATURE);
void (*teardown_routine)(TEARDOWN_ROUTINE_SIGNATURE);
} GameState;
Während Sie diesen Stil nicht schätzen kann oder nicht, ich habe es gewachsen zu mögen und es dient mir bisher gut auf dieser kleinen (privat. .) Projekt.
Ich habe zum Beispiel einen "Übergang" Spielzustand, der einfach von einem Spielzustand zum anderen übergeht.
Allerdings, wenn ich die verschiedenen Spiel-Verbindungszustände zusammen, ich hässliche Dinge wie:
extern GameState GAME; /* The 'singleton' "game" */
extern void menu_setup_routine(SETUP_ROUTINE_SIGNATURE);
extern void menu_draw_routine(DRAW_ROUTINE_SIGNATURE);
extern void menu_event_routine(EVENT_ROUTINE_SIGNATURE);
extern void menu_update_routine(UPDATE_ROUTINE_SIGNATURE);
extern void menu_teardown_routine(TEARDOWN_ROUTINE_SIGNATURE);
extern void debug_setup_routine(SETUP_ROUTINE_SIGNATURE);
extern void debug_draw_routine(DRAW_ROUTINE_SIGNATURE);
extern void debug_event_routine(EVENT_ROUTINE_SIGNATURE);
extern void debug_update_routine(UPDATE_ROUTINE_SIGNATURE);
extern void debug_teardown_routine(TEARDOWN_ROUTINE_SIGNATURE);
Auch für jedes Spiel Zustand Ich habe Dinge wie:
menu.c
struct MenuModel menu_model; /* The singleton 'menu' model */
game.c
struct GameModel game_model; /* The singleton 'game' model */
..welche globale Daten sind, die während der Ausführung des Programms auf dem Heap verbleiben. Natürlich bestehen die Felder davon in der Regel aus Hinweisen auf dynamischen Speicher, die sich ändern, wenn sich die Spielzustände ändern.
Während ich zuerst dachte, das wäre verrückt, fing ich an, es zu mögen. Es kann jedoch zu Namespace-Konflikten führen, wenn ein anderes .o verknüpft ist, das ebenfalls ein solches "menu_model" -Symbol hat.
Erste Frage: Ist das verrückt, gibt es eine bessere Möglichkeit, solche Dinge zu tun? Was tun die Leute normalerweise, um diese möglichen Symbolnamenkonflikte zu vermeiden?
Zweite Frage ist, dass ich die verschiedenen ..._ setup_routine/.. draw_routine/.. Funktionen zu veröffentlichen haben „extern ..“ in der eine Quelldatei/Objektdatei, die die folgenden Arten von Funktionen gilt:
void (*get_setup_routine(GameStateType state))(SETUP_ROUTINE_SIGNATURE) {
switch(state) {
case GAME_STATE_MENU:
return SETUP_ROUTINE(menu);
break;
case GAME_STATE_LEVELSELECT:
return SETUP_ROUTINE(level_select);
break;
default: /* ... */ break;
}
}
Weil sonst beim Kompilieren das Symbol "menu_setup_routine" nicht bekannt ist.
Wie auch immer, jeder Rat ist willkommen, ich bin ein bisschen neu in C und obwohl ich wirklich gerne darin programmiere, frage ich mich, ob ich es in diesem Fall richtig benutze.
Danke, Neverball Quelle ist sehr interessant. Ich vermeide bewusst C++, ich benutze es professionell in der Vergangenheit und mir wird es jetzt langweilig, ich weiß auch nicht, wie der Code in der Hälfte der Zeit in der Maschine aussieht (das ist nicht C++ sondern mein Unwissen). – buddhabrot