/* * Prelude for file-scope fragments in docs/20 and docs/21 that assume the * galaga example's own declarations already exist -- the shared structures * from examples/galaga/galaga.h and the helpers a fragment calls but does not * define. The types are copied rather than included so a fragment compiles * against exactly what the chapter has shown so far; the helper declarations * are invented prototypes, per the prelude policy in MAINTENANCE.md. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GALAGA_ENEMY_BEE 0 #define GALAGA_ENEMY_BUTTERFLY 1 #define GALAGA_ENEMY_BOSS 2 #define GALAGA_ENEMY_KINDS 3 #define GALAGA_MAX_ENEMIES 40 #define GALAGA_MAX_PLAYER_SHOTS 2 #define GALAGA_MAX_ENEMY_SHOTS 8 #define GALAGA_ES_ENTERING (1 << 0) #define GALAGA_ES_FORMATION (1 << 1) #define GALAGA_ES_DIVING (1 << 2) typedef struct galaga_Enemy { int32_t kind; int32_t state; float homex; float homey; float t; int32_t hp; int32_t fire; float rnd; } galaga_Enemy; typedef struct galaga_Shared { float playerx; float playery; int32_t wave; float rnd; } galaga_Shared; typedef enum { GALAGA_SCREEN_TITLE = 0, GALAGA_SCREEN_PLAY, GALAGA_SCREEN_GAMEOVER, GALAGA_SCREEN_VICTORY } galaga_Screen; typedef struct galaga_Game { galaga_Screen screen; int frame; float dt; bool autoplay; int score; int lives; int kills[GALAGA_ENEMY_KINDS]; int shots[GALAGA_ENEMY_KINDS]; int script_errors; akgl_Actor *player; float fire_cooldown; float respawn_timer; bool firing; bool moveleft; bool moveright; int player_shots_live; int enemy_shots_live; } galaga_Game; extern galaga_Game galaga_game; extern galaga_Shared galaga_shared; extern galaga_Enemy galaga_enemies[GALAGA_MAX_ENEMIES]; extern akgl_Actor *galaga_enemy_actors[GALAGA_MAX_ENEMIES]; float galaga_random(void); akerr_ErrorContext AKERR_NOIGNORE *galaga_script_update_enemy(galaga_Enemy *enemy, akgl_Actor *actor, float dt); akerr_ErrorContext AKERR_NOIGNORE *galaga_boom_spawn(float x, float y); akerr_ErrorContext AKERR_NOIGNORE *enemy_fire(galaga_Enemy *enemy, akgl_Actor *from); akerr_ErrorContext AKERR_NOIGNORE *kill_enemy(int index); akerr_ErrorContext AKERR_NOIGNORE *player_update(akgl_Actor *obj); akerr_ErrorContext AKERR_NOIGNORE *left_on(akgl_Actor *obj, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *left_off(akgl_Actor *obj, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *right_on(akgl_Actor *obj, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *right_off(akgl_Actor *obj, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *fire_on(akgl_Actor *obj, SDL_Event *event); akerr_ErrorContext AKERR_NOIGNORE *fire_off(akgl_Actor *obj, SDL_Event *event); void shot_box(akgl_Actor *actor, SDL_FRect *dest); void enemy_box(akgl_Actor *actor, SDL_FRect *dest); void player_box(akgl_Actor *actor, SDL_FRect *dest);