C로 약간의 게임을 만들고 있습니다. 함수 포인터를 사용하여 객체 지향 방식으로 프로그래밍하려고합니다.
나는이 시간을 앞당기 고 지나치게 일반화하기를 과장하지 않으려 고 종종 이것을 잃어 버렸다. 평범한 구식 C를 사용하면 프로그램을 더 빠르고 더 잘 할 수있었습니다. 당신이 또는이 스타일을 감사하지 않을 수 있지만심볼 충돌을 피하면서 C로 일반/OO와 유사한 프로그래밍
/* 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;
, 내가 좋아하는 성장 하 고 그것을이 작은 (개인에 지금까지 저를 잘 제공 :
은 현재 내가 사용하는 "게임 주"에 대해 설명합니다. .) 프로젝트.
예를 들어, 한 게임 상태에서 다른 게임 상태로 간단히 전환하는 "전환"게임 상태가 있습니다. 각 게임 상태에 대해 내가 좋아하는 일이,
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);
또한 : 나는 다른 게임을 함께 명시 연결할 때
그러나, 내가 좋아하는 추한 것들을 얻을
menu.c을
struct MenuModel menu_model; /* The singleton 'menu' model */
game.c
struct GameModel game_model; /* The singleton 'game' model */
.. 프로그램 실행 전반에 걸쳐 힙에 남아있는 글로벌 데이터 조각입니다. 물론 이러한 필드는 대개 동적 메모리에 대한 포인터로 구성되며 게임 상태가 변경 될 때 어떤 내용이 변경됩니다.
처음에는 이것이 제 정신이 아니니 나는 그것을 좋아하기 시작했습니다. 그러나 다른 ".o"가 링크되어있는 경우에도 "menu_model"기호가있는 경우 네임 스페이스 충돌이 발생할 수 있습니다.
첫 번째 질문 :이 정신 나간가? 이런 일을하는 더 좋은 방법이 있습니까? 이러한 가능한 심볼 이름 충돌을 피하기 위해 사람들은 보통 무엇을합니까?
두 번째 질문은 내가 다음과 같은 유형의 함수를 보유하고있는 하나의 소스 파일/오브젝트 파일에 사용 ..._ setup_routine/.. draw_routine/.. 기능 "통근을 .."다른를 다시 게시해야한다는 것입니다 :
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;
}
}
그렇지 않으면 컴파일 할 때 심볼 "menu_setup_routine"을 알 수 없기 때문에.
어쨌든, 어떤 조언도 환영합니다. 저는 C에 조금 익숙합니다. 프로그래밍을 정말 좋아하지만,이 경우 제대로 사용하고 있는지 궁금합니다.
감사합니다. Neverball 소스는 매우 흥미 롭습니다. 나는 C++을 피할 수없이 피하고, 과거에는 전문적으로 사용했고, 지금은 지루해하고 있으며, 컴퓨터에서 코드가 어떤 모습인지 반각 쯤 알 수 없다. (이것은 C++의 잘못이 아니라 지식에 대한 지식이 부족하다.). – buddhabrot