122 lines
3.6 KiB
Plaintext
122 lines
3.6 KiB
Plaintext
|
|
/*
|
||
|
|
* 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 <stdbool.h>
|
||
|
|
#include <stddef.h>
|
||
|
|
#include <stdint.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include <SDL3/SDL.h>
|
||
|
|
#include <SDL3_ttf/SDL_ttf.h>
|
||
|
|
|
||
|
|
#include <akerror.h>
|
||
|
|
#include <akstdlib.h>
|
||
|
|
|
||
|
|
#include <akgl/actor.h>
|
||
|
|
#include <akgl/character.h>
|
||
|
|
#include <akgl/controller.h>
|
||
|
|
#include <akgl/draw.h>
|
||
|
|
#include <akgl/error.h>
|
||
|
|
#include <akgl/game.h>
|
||
|
|
#include <akgl/heap.h>
|
||
|
|
#include <akgl/physics.h>
|
||
|
|
#include <akgl/registry.h>
|
||
|
|
#include <akgl/renderer.h>
|
||
|
|
#include <akgl/sprite.h>
|
||
|
|
#include <akgl/text.h>
|
||
|
|
#include <akgl/ui.h>
|
||
|
|
#include <akgl/util.h>
|
||
|
|
|
||
|
|
#include <akbasic/environment.h>
|
||
|
|
#include <akbasic/error.h>
|
||
|
|
#include <akbasic/host.h>
|
||
|
|
#include <akbasic/runtime.h>
|
||
|
|
#include <akbasic/sink.h>
|
||
|
|
|
||
|
|
#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);
|