home *** CD-ROM | disk | FTP | other *** search
- /* enemy.c */
-
- #include <stdio.h>
- #include <xsp2lib.h>
-
- #include "main.h"
- #include "player.h"
- #include "shot.h"
- #include "enemy.h"
-
- #define ENEMY_MAX 32 /* 敵最大数 */
-
- static ENEMY enemy[ENEMY_MAX]; /* ワーク */
- static ENEMY *enemy_top, /* 使用中のワークのリスト */
- *enemy_null_top, /* 空のワークのリスト */
- *enemy_end; /* 使用中ワークのリストの末尾 */
-
-
-
- /* 初期化関数へのポインタの配列 */
- typedef void (*enemy_alloc) (ENEMY *);
- enemy_alloc EnemyAllocFunc[] =
- {
- EnemyAllocZakoA,
- EnemyAllocZakoB,
- };
-
-
-
- /* ゲーム開始時に呼ばれる */
- void EnemyInit (void)
- {
- int i;
-
- /* リストをつなげる */
- enemy_top = NULL;
- enemy_end = NULL;
- enemy_null_top = enemy;
- for (i = 0; i < ENEMY_MAX; i++)
- enemy[i].next = &enemy[i + 1];
-
- enemy[ENEMY_MAX - 1].next = NULL;
- }
-
-
-
- /* 敵出現時に呼ばれる */
- ENEMY *EnemyAlloc (short type, signed short x, signed short y)
- {
- ENEMY *p;
-
- if (enemy_null_top == NULL)
- return (NULL); /* 空きのワークがない(キャラクターオーバー) */
-
- /* リストの末尾に新しいノードを追加(他とは違うので注意) */
- p = enemy_null_top;
- enemy_null_top = p->next;
- if (enemy_top == NULL)
- enemy_top = p;
- else
- enemy_end->next = p;
- p->next = NULL;
- enemy_end = p;
-
- p->type = type;
- p->lx = x << 16;
- p->ly = y << 16;
-
- /* 関数へのポインタを使って分岐 */
- /* type が 0 なら EnemyAllocA() が、1 なら EnemyAllocB() が実行される */
- EnemyAllocFunc[p->type] (p);
-
- return (p);
- }
-
-
-
- /* 垂直同期ごとに呼ばれる */
- void EnemyMove (void)
- {
- ENEMY *p, *q;
- signed short pl_x = player->x, pl_y = player->y;
-
- p = enemy_top; /* 現在注目しているワーク */
- q = NULL; /* 1つ前のワーク(ワーク削除時に必要) */
- while (p != NULL) {
- /* 敵キャラの移動ルーチン */
-
- /* 関数へのポインタを使って分岐 */
- /* (FuncEnemy/ 以下の FuncMoveXXX() を呼んでいる) */
- if ((p->func_enemy_move) (p)) { /* 返り値が非0なら消去 */
- (p->func_enemy_free) (p); /* 消去関数を呼ぶ */
- if (q == NULL) { /* リストの一番最初を削除 */
- enemy_top = p->next;
- p->next = enemy_null_top;
- enemy_null_top = p;
- q = NULL;
- p = enemy_top;
- } else {
- if (p == enemy_end) { /* リストの一番最後を削除 */
- q->next = NULL;
- enemy_end = q;
- p->next = enemy_null_top;
- enemy_null_top = p;
- p = q->next;
- } else {
- q->next = p->next;
- p->next = enemy_null_top;
- enemy_null_top = p;
- p = q->next;
- }
- }
- } else {
- /* 敵キャラを消去しない場合 */
- SHOT *p2 = shot_top; /* 現在注目しているショットのワーク */
- signed short t;
-
- /* プレイヤーとの当たり判定 */
- if (((t = p->x + p->hit_sx) > pl_x)
- && ((t -= (short) (p->hit_sx << 1)) < pl_x)
- && ((t = p->y + p->hit_sy) > pl_y)
- && ((t -= (short) (p->hit_sy << 1)) < pl_y)) {
- /* 当たった */
- if (player->status == PLAYER_STATUS_ALIVE)
- player->status = PLAYER_STATUS_DEAD;
- }
- /* ショットとの当たり判定 */
- while (p2 != NULL) {
- signed short p2_w;
- short hit_w;
- if (((t = p->x + (hit_w = p->hit_sx)) >= (p2_w = *((short *) (&p2->lx))))
- && ((t -= (short) (hit_w << 1)) <= p2_w)
- && ((t = p->y + (hit_w = p->hit_sy)) >= (p2_w = *((short *) (&p2->ly))))
- && ((t -= (short) (hit_w << 1)) <= p2_w)
- && (p2->damage == 0)) {
- /* ショットが当たった */
- p->damage++; /* 敵キャラにダメージを与える */
- p2->damage = !0; /* 自機ショットに当たった事を知らせる */
- }
- p2 = p2->next;
- }
- q = p;
- p = p->next;
- }
- }
- }
-