[Conception] généricité des données manipulées
Bonjour à tous.
Dans le cadre de mes études, je dois développer un zuma en C.
J'ai commencé l'analyse et en parallèle je teste 2/3 bouts de code et je me heurte à un problème.
En effet, dans l'état actuel j'ai articulé mon jeu autour de la notion de "game state".
Chaque game state represente un état dans le lequel peut se trouver à un instant T (écran d'accueil, jeu principal, score, option ...).
Pour rendre le tout générique j'ai crée une structure game_state avec deux pointeurs de fonction: l'un va être appelé pour gérer les événements et l'autre l'affichage.
Le soucis se pose dans les données manipulées par chaque état. En effet, celle ci sont différentes d'un état à l'autre et je ne sais pas comment en tenir compte.
Par exemple, l'écran de jeu à proprement parler va devoir manipuler des liste de sprites et gérer les collisions entres elles, ce dont les autres états doivent ignorer l'existence.
Pour le moment, j'ai tout fouré dans une structure game_data mais il faut dire que c'est totalement dégeulase.
la seule solution que je vois pour segmenter les données. consiste à ajouter dans ma structure game_state un pointeur de type void* specific_data, à le faire pointer vers une structure spécifique (jeu_data, option_data, ...) au moment de l'appel des les fonctions d'initialisations spécifiques et à caster à chaque fois que j'en ai besoin.
Mais venant du C++, ca ne me plaît pas. Après, je sais que c'est une pratique qui existe en C (je pense aux threads par exemple).
Si vous avez une idée, n'hésitez pas !!!!
Voici une version "synthétisée" de mon code pour (j'espère) rendre le tout plus clair:
Code:
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
|
struct game_data
{
string name;
};
typedef void (*display_fct)(game_state*,displayer*);
typedef void (*event_fct)(game_state*);
struct game_state
{
game_data* common_data;
/*Pointeur pour acceder aux données spécifique de chaque game_state*/
/*
void* specific_data;
*/
event_fct event_handler;
display_fct display_handler;
SDL_Surface* background;
SDL_Event event;
int continuer;
};
struct game
{
/** Donne du jeu*/
game_data common_data;
game_state* acceuil,jeu;
game_state* current_state;
};
/*=====================*/
int main(int argc, char *argv[])
{
game* g=0;
displayer* d=0;
/*...*/
d=create_display();
g=create_game(d);
run_game(g,d);
destruct_game(g);
return EXIT_SUCCESS;
}
/*=====================*/
game* create_game(displayer* d)
{
game* g=malloc(sizeof(*g));
init_data(&(g->common_data));
g->acceuil=create_game_state(&display_acceuil,&event_acceuil,g);
g->jeu=create_game_state(&display_jeu,&event_jeu,g);
/*Initialisation specifique a accueil*/
init_acceuil(g->acceuil,d);
g->current_state=g->acceuil;
return g;
}
/*Boucle principale du jeu*/
void run_game(game* g,displayer* d)
{
int t1=0,t2=0;
while(g->current_state->continuer)
{
t2 = SDL_GetTicks();
if (t2 - t1 > period)
{
t1 = t2;
}
else
{
SDL_Delay(period/2);
run_state(g->current_state,d);
}
}
}
game_state* create_game_state(display_fct d,event_fct e,game* game)
{
game_state* g=malloc(sizeof(*g));
g->event_handler=e;
g->display_handler=d;
g->common_data=&(game->common_data);
g->continuer=1;
return g;
}
void run_state(game_state* s,displayer* d)
{
s->event_handler(s);
s->display_handler(s,d);
}
void event_acceuil(game_state* state){/**/}
void display_acceuil(game_state* state,displayer*){/**/}
void event_jeu(game_state* state){/**/}
void display_jeu(game_state* state,displayer*){/**/} |