SDLでボンバーマン風ゲームを作ってみる6


こんにちは。

見てる人は少ないと思うが、久しぶりのブログ更新です。(´・∀・`)



今回は前回に引き続き、爆弾で壊せるコンテナの作成と、

同じく爆弾で殺せる敵を作ってみた。

本来なら、ブロックを崩すとアイテムが色々出てくるんですが

そこはまだ作ってません。



敵を全員殺しても残念ながらステージクリアにはなりません。(°ー°*)

そのうち時間を見て作りたいと思います。



サンプル画像







ソースコードはこちら
http://www.geocities.jp/finnissy/data/090901.zip



gfx.c

#include "gfx.h"
#include "snd.h"
#include "main.h"
#include "game.h"
#include "libttf.h"
#include "routing.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define ID_BOMM (0x100)
#define ID_BACK (0x200)
#define ID_FIRE (0x300)
#define ID_CONTAINER (0x400)
#define ID_MONSTER  (0x500)
#define OVER_COUNT (3*(60)) //16ms * 240count = 4sec

#define HUMAN_FRAME (4)
#define MOVE_VALUE  (1)

#define TERRITORY   (BLOCK_SIZE/8)
#define NUM_ENEMY   (8)

/************************************************************/
/*                      構造体変数宣言                      */
/************************************************************/

typedef struct anime_list{          // 爆弾構造体
    int x,y;
    int map_x,map_y;
    int id;
    int cnt;
    struct anime_list *next;
} Bomm_List;

typedef struct blit_info{
    SDL_Surface *surface;           //更新情報テーブル
    SDL_Rect    r;
    int id;
} Blit_Inof;

static struct {
    SDL_Rect    r;                  //前フレーム更新情報
    int id;
} old_draw[UPDATE_MAX];

static struct {
    SDL_Surface **arr;              /*  爆風構造体  */
    int frame,n;
} bomm_img[MAX_LEVEL];

static struct {
    SDL_Surface **arr;              /*  コンテナ爆風構造体  */
    int frame,n;
} container_fire;

static union {                      // 人間風ロボット
    SDL_Surface *arr[4*4];
    struct  {
        SDL_Surface *down[4];
        SDL_Surface *left[4];
        SDL_Surface *right[4];
        SDL_Surface *up[4];
    };
} humanoid;

static struct {                     //矩形情報の合計
    int now;
    int old;
    int front;
    int update;
} numrect;

static enum {                       // マップの定数
    EMPTY = 0,
    FIELD_WALL,
    FIELD_STONE,
    FIELD_CONTAINER,
    FIELD_BOMM,
    FIELD_DEATH = 10,
};

/************************************************************/
/*                          変数宣言                        */
/************************************************************/
static SDL_Surface *screen;         //ウィンドウ画像ポインタ
static SDL_Surface *back_buffer;    //バックバッファー
static SDL_Surface *play_map;       //ゲームプレイ用バッファー
static SDL_Rect rects[UPDATE_MAX];  //更新情報
static Uint32 fps_rate;             //fps計算用
static Uint16 fps_cnt;              //fpsカウント
static Sint16 map[HEIGHT_SIZE][WIDTH_SIZE];//2次元表

static Bomm_List *bomm_top;
static Bomm_List *fire_top;
static Bomm_List *container_top;
static Bomm_List *enemy_top;
static Uint32 bomms = ID_BOMM;
static Uint32 fires = ID_FIRE;
static Uint32 containers = ID_CONTAINER;
static Uint32 enemys = ID_MONSTER;

static int text_id;
static int enemy_frame;     //enemy index

static const int FPS_X  =   0;
static const int FPS_Y  =   0;
static const int FPS_W  =   FRAME_WIDTH/2;
static const int FPS_H  =   FONT_SIZE;

static Blit_Inof now_draw[UPDATE_MAX];
static Blit_Inof front_draw[UPDATE_MAX];

/************************************************************/
/*                      関数の定義                          */
/************************************************************/

//----------------------private method----------------------//
static void back_graund(SDL_Surface *surface,const char *path);
static void set_block(void);
static void set_enemy(void);
static boolean bomm_load(void);
static boolean container_fire_load(void);
static void push(SDL_Rect *r);
static void bomm_count(void);
static void add_bomm(int x, int y);
static void del_bomm(int id);
static void clean_screen(int x,int y,int w,int h,int id);
static void bomm_reset(void);
static void back_draw(Blit_Inof *info,int now);
static void blit_ttf(int x,int y,SDL_Surface *s);

static void fire(int x,int y);
static void fire_count(void);
static void add_fire(int x, int y,int mapx,int mapy);
static void del_fire(int id);
static void fire_reset(void);

static void fire_container(int x,int y);
static void fire_count_container(void);
static void add_fire_container(int x, int y,int mapx,int mapy);
static void del_fire_container(int id);
static void fire_container_reset(void);

static void go_enemy(int x,int y);
static void enemy_count(void);
static void add_enemy(int x, int y,int mapx,int mapy);
static void del_enemy(int id);
static void enemy_reset(void);
static mvdrc root_calc(int x, int y, Bomm_List *t);

static boolean lock(SDL_Surface *s);
static void unlock(SDL_Surface *s);
static void set_alpha(SDL_Surface *s, Uint32 col);
static Uint32 get_pixel(SDL_Surface *Surface, Sint32 X, Sint32 Y);
static void fire_calc(int x,int y,int range,boolean flg);
static int human_load(void);


/************************************************/
/*              Public Method                   */
/************************************************/
boolean init_gfx(void)
{
    int i;
    const char *img_path[] = {  //画像イメージのパス
        PATH_IMAGE01,   PATH_IMAGE03,   PATH_IMAGE04,
        PATH_IMAGE05,   PATH_IMAGE06,   PATH_IMAGE07,
        PATH_IMAGE08,   PATH_IMAGE09,   PATH_IMAGE10,
        PATH_IMAGE11,   PATH_IMAGE12,
    };

    if(screen != NULL)
        return TRUE;

    /****************************/
    /*      スクリーンの初期化  */
    /****************************/
    screen = SDL_SetVideoMode(
        FRAME_WIDTH,FRAME_HEIGHT,FRAME_BPP,INIT_FLAG_VIDEO
    );
    
    if(screen == NULL)  {
        printf("Error get video memory");
        return FALSE;
    }
    
    /********************************/
    /*  バックバッファーの初期化    */
    /********************************/
    play_map = SDL_AllocSurface(
                    screen->flags,
                    screen->w,
                    screen->h,
                    screen->format->BitsPerPixel,
                    screen->format->Rmask,
                    screen->format->Gmask,
                    screen->format->Bmask,
                    screen->format->Amask
                );
    if(play_map == NULL)    {
        printf("Error get video memory");
        return FALSE;
    }

    /********************************/
    /*      フォントの初期化        */
    /********************************/
    if( !ttf_init(screen,PATH_FONT,FONT_SIZE, blit_ttf) ){
        printf("Error open fontimage");
        return FALSE;
    }

    /************************************/
    /*          画像の読み込み          */
    /************************************/
    for(i = 0;i < PATH_IMAGE_MAX;i++)
    {
        images.arr[i] = SDL_LoadBMP(img_path[i]);
        if( !images.arr[i] )
            return FALSE;
    }
    /*  透過色を設定する    */
    SDL_SetColorKey(images.wall2, SDL_SRCCOLORKEY, get_pixel(images.wall2,0,0));
    SDL_SetColorKey(images.bomm1, SDL_SRCCOLORKEY, get_pixel(images.bomm1,0,0));
    SDL_SetColorKey(images.bomm2, SDL_SRCCOLORKEY, get_pixel(images.bomm2,0,0));
    SDL_SetColorKey(images.bomm3, SDL_SRCCOLORKEY, get_pixel(images.bomm3,0,0));
    SDL_SetColorKey(images.bomm4, SDL_SRCCOLORKEY, get_pixel(images.bomm4,0,0));
    SDL_SetColorKey(images.container1, SDL_SRCCOLORKEY, get_pixel(images.container1,0,0));
    SDL_SetColorKey(images.container2, SDL_SRCCOLORKEY, get_pixel(images.container2,0,0));
    SDL_SetColorKey(images.container3, SDL_SRCCOLORKEY, get_pixel(images.container3,0,0));

    /************************/
    /*      爆風の用意      */
    /************************/
    if( !bomm_load() )
        return FALSE;

    /************************/
    /*  コンテナ爆風の用意  */
    /************************/
    if( !container_fire_load() )
        return FALSE;

    /************************/
    /*      人の用意        */
    /************************/
    if( !human_load() )
        return FALSE;

    /************************/
    /*      背景の用意      */
    /************************/
    back_graund(play_map,PATH_MAP01);

    /************************/
    /*      背景の描画      */
    /************************/
    draw_scene(STATE_TITLE);

    return TRUE;
}

void quit_gfx(void)
{
    int i;

    /********************************/
    /*  イメージ構造体を解放する    */
    /********************************/
    for(i = 0; i < PATH_IMAGE_MAX; i++)     //汎用画像構造体の開放
    {
        if(images.arr[i] != NULL)
            SDL_FreeSurface(images.arr[i]);
    }
    for(i = 0; i < MAX_LEVEL; i++)          //爆風画像構造体の開放
    {
        int j;
        if(bomm_img[i].arr != NULL)
        {
            for(j = 0;j < sizeof(bomm_img[i].arr)/sizeof(bomm_img[i].arr[0]);j++)
            {
                if(bomm_img[i].arr[j] != NULL)
                    SDL_FreeSurface(bomm_img[i].arr[j]);
            }
            free(bomm_img[i].arr);
        }
    }
    if(container_fire.arr != NULL)          //コンテナ爆発画像構造体の開放
    {
        for(i = 0; i < sizeof(container_fire.arr)/sizeof(container_fire.arr[0]); i++)
        {
            if(container_fire.arr[i] != NULL)
                SDL_FreeSurface(container_fire.arr[i]);
        }
        free(container_fire.arr);
    }
    for(i = 0; i < HUMAN_FRAME*4; i++)      //人間画像構造体の開放
    {
        if(humanoid.arr[i] != NULL)
            SDL_FreeSurface(humanoid.arr[i]);
    }

    /********************************/
    /*      フォントの開放          */
    /********************************/
    ttf_quit();

    /********************************/
    /*      スクリーンの開放        */
    /********************************/
    if(screen != NULL)
        SDL_FreeSurface( screen );
}

void draw_scene(gstate scene)
{
    SDL_Rect r = {0,0,FRAME_WIDTH,FRAME_HEIGHT};

    switch( scene )
    {
    case STATE_TITLE:
        if(back_buffer != images.title)
        {
            back_buffer = images.title;
            SDL_BlitSurface(back_buffer,NULL,screen,NULL);
            push( &r );
        }
        break;
    case STATE_PLAY:
        if(back_buffer != play_map)
        {
            back_buffer = play_map; //背景セット
            set_block();            //コンテナセット
            set_enemy();
            SDL_BlitSurface(back_buffer,NULL,screen,NULL);
            push( &r );
        }
        break;
    case STATE_END:
        //SDL_BlitSurface(back_buffer,NULL,screen,NULL);
        break;
    default:
        break;
    }
}

void fps(int elapsed,int frame_rate)
{
    if( !fps_cnt )
    {
        fps_rate = SDL_GetTicks();
        fps_cnt++;
    } else
    if(++fps_cnt >= FRAME_RATE)
    {
        Uint32 elapsed = SDL_GetTicks() - fps_rate;
        Uint32 fps = (Uint32)(1000.0f/((double)elapsed/(double)FRAME_RATE));
        SDL_Rect r = { FPS_X,FPS_Y,FPS_W,FPS_H };
        
        SDL_BlitSurface(back_buffer, &r, screen, &r);
        r = ttf_puta_color(FPS_X,FPS_Y,0xAABBFF,"FPS : %.2d",fps);
        push( &r );

        fps_rate = 0;   //60回分の処理時間をリセット
        fps_cnt = 0;    //1秒間の処理回数カウントをリセット
    }
}

void blit(int x,int y,SDL_Surface *surface,int id)
{
    if(numrect.now < UPDATE_MAX)
    {
        int i = numrect.now;

        now_draw[i].r.x = x;
        now_draw[i].r.y = y;
        now_draw[i].r.w = surface->w;
        now_draw[i].r.h = surface->h;
        now_draw[i].surface = surface;
        now_draw[i].id = id;

        numrect.now++;
    }
}

void blit_text(int x,int y,Uint32 bc,Uint32 ec,const char *text,int id)
{
    text_id = id;   //必須。これが無いとまともに描画できない...
    ttf_put_grd(x,y,bc,ec,text);
}

void front_blit(int x,int y,SDL_Surface *surface,int id)
{
    if(numrect.front < UPDATE_MAX)
    {
        int i = numrect.front;

        front_draw[i].r.x = x;
        front_draw[i].r.y = y;
        front_draw[i].r.w = surface->w;
        front_draw[i].r.h = surface->h;
        front_draw[i].surface = surface;
        front_draw[i].id = id;

        numrect.front++;
    }
}

void blit_human(int x,int y,int id,SDLKey key, int flg)
{
    const int idx = flg % HUMAN_FRAME;

    switch( key )
    {
    case SDLK_DOWN: blit(x, y, humanoid.down[idx], id);     break;
    case SDLK_UP:   blit(x, y, humanoid.up[idx], id);       break;
    case SDLK_RIGHT:blit(x, y, humanoid.right[idx], id);    break;
    case SDLK_LEFT: blit(x, y, humanoid.left[idx], id);     break;
    default:        break;
    }
}

boolean map_calc(int x,int y, int state)
{
    int x1 = x / BLOCK_SIZE;
    int y1 = y / BLOCK_SIZE;
    int x2 = (x + BLOCK_SIZE-1) / (BLOCK_SIZE);
    int y2 = (y + BLOCK_SIZE-1) / (BLOCK_SIZE);

    switch( state )
    {
    case MV_LEFT:   return (!map[y1][x1] && !map[y2][x1]);
    case MV_RIGHT:  return (!map[y1][x2] && !map[y2][x2]);
    case MV_UP:     return (!map[y1][x1] && !map[y1][x2]);
    case MV_DOWN:   return (!map[y2][x1] && !map[y2][x2]);
    default:        break;
    }

    printf("move start point\n");
    return TRUE;
}

boolean isdeath(int xt,int yt)
{
    int x,xs;   //surplus
    int y,ys;

    if(xt < 0 || xt >= FRAME_WIDTH || yt < 0 || yt >= FRAME_HEIGHT)
        return FALSE;
    
    x = xt / BLOCK_SIZE;
    y = yt / BLOCK_SIZE;
    xs = (xt % BLOCK_SIZE) > 0 ? 1 : 0;
    ys = (yt % BLOCK_SIZE) > 0 ? 1 : 0;

    /*
    printf("x % 32 = %d\n",x % BLOCK_SIZE);
    printf("y % 32 = %d\n",y % BLOCK_SIZE);
    printf("map[%d][%d] = %d\n",y,x,map[y][x]);
    printf("map[%d][%d] = %d\n",y,x+xs,map[y][x+xs]);
    printf("map[%d][%d] = %d\n",y+ys,x,map[y+ys][x]);
    printf("map[%d][%d] = %d\n",y+ys,x+xs,map[y+ys][x+xs]);
    */
    if(map[y][x] >= FIELD_DEATH)        return TRUE;    else
    if(map[y][x+xs] >= FIELD_DEATH)     return TRUE;    else
    if(map[y+ys][x] >= FIELD_DEATH)     return TRUE;    else
    if(map[y+ys][x+xs] >= FIELD_DEATH)  return TRUE;

    return FALSE;
}

boolean isenemy(int x,int y)
{
    Bomm_List *t;

    t = enemy_top;
    while(t != NULL)
    {
        double f = pow(abs(x)-abs(t->x),2) + pow(abs(y)-abs(t->y),2);
        if(f <= pow(TERRITORY+TERRITORY,2))
            return TRUE;

        t = t->next;
    }

    return FALSE;
}

void draw(void)
{
    int i;

    back_draw(now_draw, numrect.now);
    back_draw(front_draw, numrect.front);

    /****************************/
    /*      画像を描画          */
    /****************************/
    for(i = 0;i < numrect.now;i++)
    {
        SDL_Rect tmp = now_draw[i].r;

        push( &tmp );
        if(now_draw[i].surface == back_buffer)
        {
            if(now_draw[i].surface && screen)
                SDL_BlitSurface(now_draw[i].surface, &tmp, screen, &tmp);
            else
                printf("draw error:image!\n");
        } else {
            if(now_draw[i].surface && screen)
                SDL_BlitSurface(now_draw[i].surface, NULL, screen, &tmp);
            else
                printf("draw error:image!\n");
        }
    }
    /****************************/
    /*      爆風を描画          */
    /****************************/
    for(i = 0;i < numrect.front;i++)
    {
        SDL_Rect tmp = front_draw[i].r;

        push( &tmp );
        if(front_draw[i].surface == back_buffer)
        {
            SDL_BlitSurface(front_draw[i].surface, &tmp, screen, &tmp);
        } else {
            SDL_BlitSurface(front_draw[i].surface, NULL, screen, &tmp);
        }
    }

    memset( now_draw, 0, sizeof(now_draw));
    memset( front_draw, 0, sizeof(front_draw));
    numrect.now = numrect.front = 0;
}

void update(void)
{
    /********************************************/
    /*  与えられた矩形情報を元に画面の更新      */
    /********************************************/
    SDL_UpdateRects(screen, numrect.update, rects);

    /********************************************/
    /*          矩形情報をクリアする            */
    /********************************************/
    memset(rects,0,sizeof(rects));
    numrect.update = 0;
}


void bomm_start(int x,int y)
{
    int x1 = (x + (BLOCK_SIZE>>1)) / BLOCK_SIZE;
    int y1 = (y + (BLOCK_SIZE>>1)) / BLOCK_SIZE;

    if((map[y1][x1] == 0)||(map[y1][x1] >= FIELD_DEATH) )
    {
        map[y1][x1] += FIELD_BOMM;
        printf("add_bomm\n");
        add_bomm(x1,y1);

        add_func( bomm_count );
    }
}

void death_effect(int x,int y)
{
    fire_container(x,y);
}

boolean isfire(void)
{
    return container_top == NULL;
}

/****************************************************/
/*                  private method                  */
/****************************************************/

static
void back_draw(Blit_Inof *info,int now)
{
    boolean flg;
    int i,j;

    if( !back_buffer || !screen )
        return;

    /****************************/
    /*      裏画面を描画        */
    /****************************/
    for(i = 0;i < now;i++)
    {
        flg = FALSE;
        for(j = 0;j < numrect.old;j++)  //前フレームで描画した場所は裏画面を描画
        {
            if(info[i].id == old_draw[j].id)
            {
                SDL_Rect tmp = old_draw[j].r;
                
                push( &tmp );
                SDL_BlitSurface(back_buffer, &tmp, screen, &tmp);
                old_draw[j].r = info[i].r;  //update the Rect Infomation

                flg = TRUE;
                break;
            }
        }
        
        if( !flg && (numrect.old < UPDATE_MAX)) //初登録のID
        {
            old_draw[numrect.old].r = info[i].r;
            old_draw[numrect.old].id = info[i].id;
            numrect.old++;
        }
    }
}

static
void set_block(void)
{
    int col,row;
    int block = (int)(WIDTH_SIZE*HEIGHT_SIZE*0.4);

    // 四隅は埋めない
    map[1][1] = map[1][2] = map[2][1] = -1;
    map[1][WIDTH_SIZE-2] = map[1][WIDTH_SIZE-3] = map[2][WIDTH_SIZE-2] = -1;
    map[HEIGHT_SIZE-2][1] = map[HEIGHT_SIZE-2][2] = map[HEIGHT_SIZE-3][1] = -1;
    map[HEIGHT_SIZE-3][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-3] = -1;

    while( block )
    {
        for(row = 1;row < HEIGHT_SIZE-1; row++)
        {
            for(col = 1;col < WIDTH_SIZE-1; col++)
            {
                if( !block )    //配置完了
                    goto CLEANUP;   //ジャンプ

                if( !map[row][col] && rand() % 3 == 0)
                {
                    SDL_Rect r;

                    r.w = r.h = 0;
                    r.x = col * BLOCK_SIZE;
                    r.y = row * BLOCK_SIZE;
                    
                    map[row][col] = FIELD_CONTAINER;
                    SDL_BlitSurface(images.container1,NULL,back_buffer,&r);
                    block--;
                }
            }
        }
    }

CLEANUP:
#if 0
    for(row = 0;row < HEIGHT_SIZE; row++)
    {
        for(col = 0;col < WIDTH_SIZE; col++)
        {
            if(map[row][col] == -1)
                map[row][col] = 0;
        }
    }
#else
    map[1][1] = map[1][2] = map[2][1] = 0;
    map[1][WIDTH_SIZE-2] = map[1][WIDTH_SIZE-3] = map[2][WIDTH_SIZE-2] = 0;
    map[HEIGHT_SIZE-2][1] = map[HEIGHT_SIZE-2][2] = map[HEIGHT_SIZE-3][1] = 0;
    map[HEIGHT_SIZE-3][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-3] = 0;
#endif

}

static
void set_enemy(void)
{
    int col,row;
    int monster = NUM_ENEMY;
    boolean loop;

    // 四隅は埋めない
    map[1][1] = map[1][2] = map[2][1] = -1;
    map[1][WIDTH_SIZE-2] = map[1][WIDTH_SIZE-3] = map[2][WIDTH_SIZE-2] = -1;
    map[HEIGHT_SIZE-2][1] = map[HEIGHT_SIZE-2][2] = map[HEIGHT_SIZE-3][1] = -1;
    map[HEIGHT_SIZE-3][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-3] = -1;

    loop = TRUE;
    while( monster )
    {
        for(row = 1;row < HEIGHT_SIZE-1 && loop; row++)
        {
            for(col = 1;col < WIDTH_SIZE-1 && loop; col++)
            {
                if( !monster )  //配置完了
                    loop = FALSE;

                if( !map[row][col] && rand() % 3 == 0)
                {
                    SDL_Rect r;

                    r.w = r.h = 0;
                    r.x = col * BLOCK_SIZE;
                    r.y = row * BLOCK_SIZE;
                    
                    go_enemy(r.x,r.y);
                    monster--;
                }
            }
        }
    }

    map[1][1] = map[1][2] = map[2][1] = 0;
    map[1][WIDTH_SIZE-2] = map[1][WIDTH_SIZE-3] = map[2][WIDTH_SIZE-2] = 0;
    map[HEIGHT_SIZE-2][1] = map[HEIGHT_SIZE-2][2] = map[HEIGHT_SIZE-3][1] = 0;
    map[HEIGHT_SIZE-3][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-2] = map[HEIGHT_SIZE-2][WIDTH_SIZE-3] = 0;
}

static
void blit_ttf(int x,int y,SDL_Surface *s)
{
    blit(x,y,s,text_id);
}

static
void back_graund(SDL_Surface *surface,const char *path)
{
    FILE *fp;
    boolean flg;
    int x,y;

    fp = fopen(path,"r");
    if(fp == NULL)
    {
        printf("Error Mapfile loading\n");
        return;
    }

    flg = FALSE;
    for(y = 0;y < WIDTH_SIZE;y++)
    {
        for(x = 0;x < HEIGHT_SIZE;x++)
        {
            SDL_Rect r;
            int c;
            
            r.x = x*BLOCK_SIZE;
            r.y = y*BLOCK_SIZE;
            
            while(!isdigit(c = fgetc(fp)) && !feof(fp) && !ferror(fp));
            
            if(feof(fp) || ferror(fp))
            {
                flg = TRUE;
                break;
            }

            map[y][x] = c = c - '0';
            switch( c )
            {
            case 0: SDL_BlitSurface(images.back,NULL,surface, &r);  break;
            case 1: SDL_BlitSurface(images.wall1,NULL,surface, &r); break;
            case 2:
                    SDL_BlitSurface(images.back,NULL,surface, &r);
                    SDL_BlitSurface(images.wall2,NULL,surface, &r); break;
            default :   break;
            }
        }

        if( flg )
            break;
    }

    fclose(fp);
}


static
boolean bomm_load(void)
{
    int i;
    const char *img = "bomm.bmp";
    const char *txt = "info.txt";
    FILE *fp_txt;

    for(i = 0;i < MAX_LEVEL;i++)
    {
        if(bomm_img[i].arr == NULL)
        {
            char path_img[255] = "";
            char path_txt[255] = "";
            char bnum[] = { '1'+i,'/','\0' };
            int width;
            int frame;

            strncpy(path_img,PATH_BOMM,200);
            strncat(path_img,bnum,30);
            strncat(path_img,img,25);

            strncpy(path_txt,PATH_BOMM,200);
            strncat(path_txt,bnum,30);
            strncat(path_txt,txt,25);

            fp_txt = fopen(path_txt,"r");
            if( fp_txt )
            {
                SDL_Surface *surface = NULL;
                char tmp[10] = "";
                
                fgets(tmp,10,fp_txt);
                width = atoi(tmp);
                fgets(tmp,10,fp_txt);
                frame = atoi(tmp);

                surface = SDL_LoadBMP(path_img);
                if(surface != NULL)
                {
                    int num;
                    int flg;
                    const int w = width;
                    const int h = width;

                    /********************************/
                    /*      ポインタ配列を取得      */
                    /********************************/
                    bomm_img[i].arr = (SDL_Surface**)malloc(sizeof(SDL_Surface*)*frame);

                    if(bomm_img[i].arr == NULL)
                        return FALSE;

                    memset(bomm_img[i].arr,0,sizeof(SDL_Surface*)*frame);
                    for(num = 0;num < frame;num++)
                    {
                        SDL_Rect r;
                        
                        r.x = num*w;
                        r.y = 0;
                        r.w = w;
                        r.h = h;

                        bomm_img[i].arr[num] = SDL_AllocSurface(screen->flags, w, h,
                                screen->format->BitsPerPixel,
                                screen->format->Rmask,
                                screen->format->Gmask,
                                screen->format->Bmask,
                                screen->format->Amask
                            );

                        if(bomm_img[i].arr[num] == NULL)
                            return FALSE;

                        flg = SDL_BlitSurface(surface, &r, bomm_img[i].arr[num], NULL);//画像転送
                        flg = SDL_SetColorKey(bomm_img[i].arr[num],
                            SDL_SRCCOLORKEY,get_pixel(bomm_img[i].arr[num],0,0));
                    }

                    if( surface )
                        SDL_FreeSurface( surface );
                } else {
                    return FALSE;
                }
            } else {
                return FALSE;
            }
        }
    }
    return TRUE;
}


static
boolean container_fire_load(void)
{
    const char *img = "container_fire.bmp";
    const char *txt = "info.txt";
    FILE *fp_txt;

    if(container_fire.arr == NULL)
    {
        char path_img[255] = "";
        char path_txt[255] = "";
        //char slash[] = { '1'+i,'/','\0' };    拡張する際はこちら
        char slash[] = "/";
        int width;
        int frame;

        strncpy(path_img,PATH_FIRE_CONTAINER,200);
        strncat(path_img,slash,30);
        strncat(path_img,img,25);

        strncpy(path_txt,PATH_FIRE_CONTAINER,200);
        strncat(path_txt,slash,30);
        strncat(path_txt,txt,25);

        fp_txt = fopen(path_txt,"r");
        if(fp_txt != NULL)
        {
            SDL_Surface *surface = NULL;
            char tmp[10] = "";
            
            fgets(tmp,10,fp_txt);
            width = atoi(tmp);
            fgets(tmp,10,fp_txt);
            frame = atoi(tmp);

            surface = SDL_LoadBMP(path_img);
            if(surface != NULL)
            {
                int num;
                int flg;
                const int w = width;
                const int h = width;

                /********************************/
                /*      ポインタ配列を取得      */
                /********************************/
                container_fire.arr = (SDL_Surface**)malloc(sizeof(SDL_Surface*)*frame);

                if(container_fire.arr == NULL)
                    return FALSE;

                memset(container_fire.arr,0,sizeof(SDL_Surface*)*frame);
                for(num = 0;num < frame;num++)
                {
                    SDL_Rect r;
                    
                    r.x = num*w;
                    r.y = 0;
                    r.w = w;
                    r.h = h;

                    container_fire.arr[num] = SDL_AllocSurface(screen->flags, w, h,
                            screen->format->BitsPerPixel,
                            screen->format->Rmask,
                            screen->format->Gmask,
                            screen->format->Bmask,
                            screen->format->Amask
                        );

                    if(container_fire.arr[num] == NULL)
                        return FALSE;

                    flg = SDL_BlitSurface(surface, &r, container_fire.arr[num], NULL);//画像転送
                    flg = SDL_SetColorKey(container_fire.arr[num],
                        SDL_SRCCOLORKEY,get_pixel(container_fire.arr[num],0,0));
                }

                if( surface )
                    SDL_FreeSurface( surface );
            } else {
                return FALSE;
            }
        } else {
            return FALSE;
        }
    }
    return TRUE;
}


static
int human_load(void)
{
    FILE *fp;
    int i,w;
    int imgw;
    char tmp[10] = "";

    SDL_Surface *t = SDL_LoadBMP(PATH_HUMAN);
    fp = fopen(PATH_TEXT01,"r");
    
    if(!t || !fp)
        return FALSE;

    fgets(tmp,10,fp);
    imgw = atoi(tmp);

    for(i = w = 0;i < t->w/imgw; i++,w += imgw)
    {
        SDL_Rect r;

        humanoid.arr[i] = 
            SDL_AllocSurface(
                t->flags,
                imgw,
                t->h,
                t->format->BitsPerPixel,
                t->format->Rmask,
                t->format->Gmask,
                t->format->Bmask,
                t->format->Amask
            );

        if( !humanoid.arr[i] )
        {
            printf("err humanoid\n");
            continue;
        }

        r.h = t->h;
        r.w = imgw;
        r.x = w;
        r.y = 0;
        SDL_BlitSurface(t,&r,humanoid.arr[i],NULL);
        SDL_SetColorKey(humanoid.arr[i],
            SDL_SRCCOLORKEY,get_pixel(humanoid.arr[i],0,0));
    }

    if(t != NULL)
        SDL_FreeSurface( t );

    return TRUE;
}


static
void push(SDL_Rect *r)
{
    if(numrect.update < UPDATE_MAX)
    {
        int i = numrect.update;
#if 0
        rects[i].x = r->x < 0 ? 0 : r->x%FRAME_WIDTH;
        rects[i].y = r->y < 0 ? 0 : r->y%FRAME_HEIGHT;
        rects[i].w = r->w % (FRAME_WIDTH - rects[i].x);
        rects[i].h = r->h % (FRAME_HEIGHT - rects[i].y);
#else
        rects[i] = (*r);
#endif
        numrect.update++;
    }
}


//----------------------------------------------

static
void bomm_count(void)
{
    Bomm_List *tmp;
    int anim_rate = (FRAME_RATE/2);
    float interval = (FRAME_RATE/8.0f);

    tmp = bomm_top;
    if(tmp == NULL)
    {
        del_func( bomm_count ); //爆弾アニメーションを解除する
        bomm_reset();
    } else {
        do {
            if(++(tmp->cnt) % FRAME_RATE < anim_rate)
            {
                int cnt = tmp->cnt % anim_rate;
                if(cnt < interval)      blit(tmp->x,tmp->y,images.bomm1,tmp->id);   else
                if(cnt < interval*2)    blit(tmp->x,tmp->y,images.bomm2,tmp->id);   else
                if(cnt < interval*3)    blit(tmp->x,tmp->y,images.bomm3,tmp->id);   else
                if(cnt < interval*4)    blit(tmp->x,tmp->y,images.bomm4,tmp->id);   else
                printf("Un Drawing\n");
            } else {
                int cnt = tmp->cnt % anim_rate;
                if(cnt < interval)      blit(tmp->x,tmp->y,images.bomm4,tmp->id);   else
                if(cnt < interval*2)    blit(tmp->x,tmp->y,images.bomm3,tmp->id);   else
                if(cnt < interval*3)    blit(tmp->x,tmp->y,images.bomm2,tmp->id);   else
                if(cnt < interval*4)    blit(tmp->x,tmp->y,images.bomm1,tmp->id);   else
                printf("Un Drawing\n");
            }

            /****************************/
            /*  爆弾時間切れ・誘発爆発  */
            /****************************/
            if((tmp->cnt == OVER_COUNT) || (map[tmp->map_y][tmp->map_x] >= FIELD_DEATH))
            {
                Bomm_List *t = tmp;
                int x = t->map_x;
                int y = t->map_y;

                printf("bomm_clear\n");
                printf("ID:%d\n",t->id);
                
                //clean_screen(tmp->x,tmp->y,BLOCK_SIZE,BLOCK_SIZE,tmp->id);
                //map[y][x] = map[y][x] & (~FIELD_BOMM);    // フラグを落とす
                map[y][x] -= FIELD_BOMM;
                fire(t->x + BLOCK_SIZE/2 , t->y + BLOCK_SIZE/2);
                
                switch( get_level() ) {         //効果音再生
                case 1: play_se(effect.fire1);  break;  
                case 2: play_se(effect.fire2);  break;
                default:break;
                }

                tmp = tmp->next;    //次の爆弾へ
                del_bomm(t->id);
            } else {
                tmp = tmp->next;    //次の爆弾へ
            }
        } while(tmp != NULL);
    }
}

static
void add_bomm(int x, int y)
{
    Bomm_List *bomm = (Bomm_List*)malloc(sizeof(Bomm_List));

    if(bomm == NULL)
        return;

    memset(bomm,0,sizeof(Bomm_List));
    bomm->id = bomms;
    bomm->x = x*BLOCK_SIZE;
    bomm->y = y*BLOCK_SIZE;
    bomm->map_x = x;
    bomm->map_y = y;
    bomm->next = bomm_top;

    bomm_top = bomm;
    printf("id:%d\n",bomm->id);

    bomms++;
    printf("bomm num:%d",bomms);
}

static
void del_bomm(int id)
{
    Bomm_List *tmp;
    Bomm_List *prev;

    tmp = bomm_top;
    prev = NULL;
    while(tmp != NULL)
    {
        if(tmp->id == id)
        {
            if(prev != NULL)
            {
                prev->next = tmp->next;
                free(tmp);
                break;
            } else {
#if 0
                free(tmp);
                bomm_top = NULL;
#else
                bomm_top = tmp->next;
                free(tmp);
#endif
                break;
            }
        }
        prev = tmp;
        tmp = tmp->next;
    }
}

//----------------------------------------------

static
void fire(int x,int y)
{
    int mx,my;
    mx = x/BLOCK_SIZE;
    my = y/BLOCK_SIZE;

//  map[y1][x1] = FIELD_BOMM;
    add_fire(x,y,mx,my);

    add_func( fire_count );
}

static
void fire_count(void)
{
    Bomm_List *tmp;
#if 1
    int anim_rate = (FRAME_RATE/2);
    float interval = (FRAME_RATE/2/10.0f);
#else
    int anim_rate = (FRAME_RATE/2);
    float interval = (FRAME_RATE/8.0f);
#endif
    const int fire_level = get_level() - 1;

    tmp = fire_top;
    if(tmp == NULL)
    {
        del_func( fire_count ); //爆弾アニメーションを解除する
        fire_reset();
    } else {
        do {
            if(++(tmp->cnt) < anim_rate)
            {
                //TODO 爆弾の画像を張る
                int i, cnt = tmp->cnt;

                for(i = 0;i < 10;i++)
                {
                    if(cnt < interval*(i+1))
                    {
                        int x = tmp->x - bomm_img[fire_level].arr[i]->w / 2;
                        int y = tmp->y - bomm_img[fire_level].arr[i]->h / 2;
                        front_blit(x,y,bomm_img[fire_level].arr[i],tmp->id);
                        break;
                    }
                }
                if(tmp->cnt == anim_rate/5)
                    fire_calc(tmp->map_x, tmp->map_y, get_level(), TRUE);   //爆風フラグをセット
            }

            if(tmp->cnt == 30)  //爆風カウント時間切れ
            {
                Bomm_List *t = tmp;
                
                clean_screen(tmp->x,tmp->y,
                    bomm_img[fire_level].arr[0]->w,
                    bomm_img[fire_level].arr[0]->h,
                    tmp->id
                );
                tmp = tmp->next;    //次の爆風へ
                fire_calc(t->map_x, t->map_y, get_level(), FALSE);  //爆風リセット
                del_fire(t->id);
            } else {
                tmp = tmp->next;    //次の爆風へ
            }
        } while(tmp != NULL);
    }
}

static
void add_fire(int x, int y,int mapx,int mapy)
{
    Bomm_List *bomm = (Bomm_List*)malloc(sizeof(Bomm_List));

    if(bomm == NULL)
        return;

    memset(bomm,0,sizeof(Bomm_List));
    bomm->id = fires;
    bomm->x = x;
    bomm->y = y;
    bomm->map_x = mapx;
    bomm->map_y = mapy;
    bomm->next = fire_top;

    fire_top = bomm;
    printf("id:%d\n",bomm->id);

    fires++;
    printf("fire num:%d",fires);
}

static
void del_fire(int id)
{
    Bomm_List *tmp;
    Bomm_List *prev;

    tmp = fire_top;
    prev = NULL;
    while(tmp != NULL)
    {
        if(tmp->id == id)
        {
            if(prev != NULL)
            {
                prev->next = tmp->next;
                free(tmp);
                break;
            } else {
                free(tmp);
                fire_top = NULL;
                break;
            }
        }
        prev = tmp;
        tmp = tmp->next;
    }
}


//----------------------------------------------

static
void fire_container(int x,int y)
{
    int mx,my;
    mx = x/BLOCK_SIZE;
    my = y/BLOCK_SIZE;

    add_fire_container(x,y,mx,my);

    add_func( fire_count_container );
}

static
void fire_count_container(void)
{
    Bomm_List *tmp;
    int anim_rate = (FRAME_RATE/2);
    float interval = (FRAME_RATE/2/20.0f);

    tmp = container_top;
    if(tmp == NULL)
    {
        del_func( fire_count_container );   //コンテナ爆風アニメーションを解除する
        fire_container_reset();
    } else {
        do {
            if(++(tmp->cnt) < anim_rate)
            {
                int i, cnt = tmp->cnt;

                for(i = 0;i < 20;i++)
                {
                    if(cnt < interval*(i+1))
                    {
                        int x = tmp->x;
                        int y = tmp->y;
                        front_blit(x, y, container_fire.arr[i], tmp->id);
                        break;
                    }
                }
            }

            if(tmp->cnt == anim_rate)   //爆風カウント時間切れ
            {
                Bomm_List *t = tmp;
                SDL_Rect r = {0,0,0,0};
                
                r.x = (tmp->x / BLOCK_SIZE) * BLOCK_SIZE;
                r.y = (tmp->y / BLOCK_SIZE) * BLOCK_SIZE;

                SDL_BlitSurface(images.back,NULL,back_buffer,&r);   //裏画面に描画.アイテム出現?
                clean_screen(
                    tmp->x,tmp->y,container_fire.arr[0]->w,container_fire.arr[0]->h,tmp->id
                );
                tmp = tmp->next;    //次の爆風へ
                del_fire_container(t->id);
            } else {
                tmp = tmp->next;    //次の爆風へ
            }
        } while(tmp != NULL);
    }
}

static
void add_fire_container(int x, int y,int mapx,int mapy)
{
    Bomm_List *bomm = (Bomm_List*)malloc(sizeof(Bomm_List));

    if(bomm == NULL)
        return;

    memset(bomm,0,sizeof(Bomm_List));
    bomm->id = containers;
    bomm->x = x;
    bomm->y = y;
    bomm->map_x = mapx;
    bomm->map_y = mapy;
    bomm->next = container_top;

    container_top = bomm;
    printf("id:%d\n",bomm->id);

    containers++;
    printf("fire num:%d",containers);
}

static
void del_fire_container(int id)
{
    Bomm_List *tmp;
    Bomm_List *prev;

    tmp = container_top;
    prev = NULL;
    while(tmp != NULL)
    {
        if(tmp->id == id)
        {
            if(prev != NULL)
            {
                prev->next = tmp->next;
                free(tmp);
                break;
            } else {
                free(tmp);
                container_top = NULL;
                break;
            }
        }
        prev = tmp;
        tmp = tmp->next;
    }
}


static
void clean_screen(int x,int y,int w,int h,int id)
{
#if 0
    SDL_Rect r;

    r.x = (x < 0) ? 0 : x%(back_buffer->w - x);
    r.y = (y < 0) ? 0 : y%(back_buffer->h - y);
    r.w = w;
    r.h = h;

    push( &r );
    SDL_BlitSurface(back_buffer, &r, screen, &r);
#else
    if(numrect.now < UPDATE_MAX)
    {
        int i = numrect.now;

        now_draw[i].r.x = (x < 0) ? 0 : x%FRAME_WIDTH;
        now_draw[i].r.y = (y < 0) ? 0 : y%FRAME_HEIGHT;
        now_draw[i].r.w = w;
        now_draw[i].r.h = h;
        now_draw[i].surface = back_buffer;
        now_draw[i].id = id;

        numrect.now++;
    }
#endif
}

static
void bomm_reset(void)
{
    bomms = ID_BOMM;
}

static
void fire_reset(void)
{
    fires = ID_FIRE;
}

static
void fire_container_reset(void)
{
    containers = ID_CONTAINER;
}

static
boolean lock(SDL_Surface *s)
{
    if( SDL_MUSTLOCK(s) )
    {
        if( SDL_LockSurface( s ) < 0)
            return FALSE;
    }
    return TRUE;
}

static
void unlock(SDL_Surface *s)
{
    if( SDL_MUSTLOCK(s) )
    {
        SDL_UnlockSurface( s );
    }
}

static
void set_alpha(SDL_Surface *s, Uint32 col)
{
    int x,y;
    int w,h;                                    /*  マスクする画像の幅、高さ        */
    SDL_PixelFormat *fmt    = s->format;        /*  ピクセルフォーマットを取得      */
    Uint8       bit_pxl = fmt->BitsPerPixel;    /*  1ピクセルのビット数を算出       */
    Uint8       byt_pxl = fmt->BytesPerPixel;   /*  1ピクセルのバイト数を算出       */
    Uint32      *pixels = s->pixels;            /*  ピクセルデータの先頭アドレス    */
    Uint16      width   = s->w;
    Uint32      *msk_pxl;                       /*  マスクするピクセルのアドレス    */

    /************************/
    /*      排他制御        */
    /************************/
    if( !lock(s) )
        return;

    y = 0;                                      /*  マスクする画像データの縦軸  */
    h = s->h;                                   /*  マスクする画像データの高さ  */
    while( y < h )
    {
        x = 0;                                  /*  マスクする画像データの横軸  */
        w = s->w;                               /*  マスクする画像データの幅    */
        while( x < w )
        {
            msk_pxl = pixels + (width*y) + (x);     /*  マスクするアドレスを取得    */
            if( *(Uint32*)msk_pxl == col )
            {   
                *(Uint32*)msk_pxl = SDL_MapRGBA(fmt,0,0,0,0);
            }
            x++;            /*  次の横軸にアクセスする          */
        }
        y++;                /*  次の縦軸にアクセスする          */
    }                       /*  カラー変更の終了                */

    unlock(s);
}

static
Uint32 get_pixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
{

   Uint8  *bits;
   Uint32 Bpp;

   if (X<0) puts("SFONT ERROR: x too small in GetPixel. Report this to hogehoge");
   if (X>=Surface->w) puts("SFONT ERROR: x too big in GetPixel. Report this to hogehoge");
   
   Bpp = Surface->format->BytesPerPixel;

   bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;

   // Get the pixel (借り物ソースコード)
   switch(Bpp) {
      case 1:
         return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
         break;
      case 2:
         return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
         break;
      case 3: { // Format/endian independent 
         Uint8 r, g, b;
         r = *((bits)+Surface->format->Rshift/8);
         g = *((bits)+Surface->format->Gshift/8);
         b = *((bits)+Surface->format->Bshift/8);
         return SDL_MapRGB(Surface->format, r, g, b);
         }
         break;
      case 4:
         return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
         break;
   }

    return -1;
}


static
void fire_calc(int x,int y,int range,boolean flg)
{
    int x1,y1;
    int signe;
    boolean up, down, right, left;

    if(x < 1 || x > WIDTH_SIZE-1
    || y < 1 || y > HEIGHT_SIZE-1)
        return;

    signe = (flg) ? 1 : -1;
    up = down = right = left = FALSE;

    /****************************/
    /*   bottom range fire      */
    /****************************/
    for(y1 = y;y1 <= y+range; y1++)
    {
        if(y1 < HEIGHT_SIZE && !down)
        {
            if(map[y1][x] == FIELD_CONTAINER && flg)    //下のコンテナ爆破
            {
                down = TRUE;
                map[y1][x] = FIELD_DEATH * signe;
                fire_container(x * BLOCK_SIZE, y1 * BLOCK_SIZE);    //コンテナ爆発!!
            } else
            if((map[y1][x] == FIELD_STONE)
            || (map[y1][x] == FIELD_WALL)  && flg){
                down = TRUE;
            } else {
                if((signe > 0) || (signe < 0 && map[y1][x] >= FIELD_DEATH))
                    map[y1][x] += FIELD_DEATH * signe;
                if(map[y1][x] < 0)
                    map[y1][x] = 0;
            }
        }
    }

    /****************************/
    /*      up range fire       */
    /****************************/
    for(y1 = y;y1 >= y-range; y1--)
    {
        if(y1 > 0 && !up)
        {
            if(map[y1][x] == FIELD_CONTAINER && flg)    //上のコンテナ爆破
            {
                SDL_Rect r = {0,0,0,0};

                up = TRUE;
                map[y1][x] = FIELD_DEATH * signe;
                r.x = x * BLOCK_SIZE;
                r.y = y1 * BLOCK_SIZE;
                fire_container(r.x,r.y);    //コンテナ爆発!!
            } else
            if((map[y1][x] == FIELD_STONE)
            || (map[y1][x] == FIELD_WALL) && flg){
                up = TRUE;
            } else {
                if((signe > 0) || (signe < 0 && map[y1][x] >= FIELD_DEATH))
                    map[y1][x] += FIELD_DEATH * signe;
                if(map[y1][x] < 0)
                    map[y1][x] = 0;
            }
        }
    }

    /****************************/
    /*   right range fire       */
    /****************************/
    for(x1 = x;x1 <= x+range; x1++)
    {
        if(x1 < WIDTH_SIZE && !right)
        {
            if(map[y][x1] == FIELD_CONTAINER && flg)    //右のコンテナ爆破
            {
                SDL_Rect r = {0,0,0,0};

                right = TRUE;
                map[y][x1] = FIELD_DEATH * signe;
                r.x = x1 * BLOCK_SIZE;
                r.y = y * BLOCK_SIZE;
                fire_container(r.x,r.y);    //コンテナ爆発!!
            } else
            if((map[y][x1] == FIELD_STONE)
            || (map[y][x1] == FIELD_WALL) && flg){
                right = TRUE;
            } else {
                if((signe > 0) || (signe < 0 && map[y][x1] >= FIELD_DEATH))
                    map[y][x1] += FIELD_DEATH * signe;
                if(map[y][x1] < 0)
                    map[y][x1] = 0;
            }
        }
    }

    /****************************/
    /*   left range fire        */
    /****************************/
    for(x1 = x;x1 >= x-range; x1--)
    {
        if(x1 > 0 && !left)
        {
            if(map[y][x1] == FIELD_CONTAINER && flg)    //左のコンテナ爆破
            {
                SDL_Rect r = {0,0,0,0};

                left = TRUE;
                map[y][x1] = FIELD_DEATH * signe;
                r.x = x1 * BLOCK_SIZE;
                r.y = y * BLOCK_SIZE;
                fire_container(r.x,r.y);    //コンテナ爆発!!
            } else
            if((map[y][x1] == FIELD_STONE)
            || (map[y][x1] == FIELD_WALL) && flg){
                left = TRUE;
            } else {
                if((signe > 0) || (signe < 0 && map[y][x1] >= FIELD_DEATH))
                    map[y][x1] += FIELD_DEATH * signe;
                if(map[y][x1] < 0)
                    map[y][x1] = 0;
            }
        }
    }
}

// monster code 
//
//

static
void go_enemy(int x,int y)
{
    int mx,my;
    mx = x/BLOCK_SIZE;
    my = y/BLOCK_SIZE;

    add_enemy(x,y,mx,my);

    add_func( enemy_count );
}

static
void enemy_count(void)
{
    Bomm_List *tmp;
    mvdrc drc;      //direction

    drc = MV_DOWN;
    tmp = enemy_top;
    if(tmp == NULL)
    {
        del_func( enemy_count );    //爆弾アニメーションを解除する
        enemy_reset();
    } else {
        do {
            Uint8 idx;

            idx = (++tmp->cnt / (FRAME_RATE/8)) % 4;
            drc = routing_01(screenX, screenY, &tmp->x, &tmp->y, MOVE_VALUE);   //敵のルートを計算,敵の移動
            // 一時的に人間風の画像を使いまわしてる
            switch( drc ) {
            case MV_UP:     blit(tmp->x,tmp->y,humanoid.up[idx],tmp->id);   break;
            case MV_DOWN:   blit(tmp->x,tmp->y,humanoid.down[idx],tmp->id); break;
            case MV_RIGHT:  blit(tmp->x,tmp->y,humanoid.right[idx],tmp->id);    break;
            case MV_LEFT:   blit(tmp->x,tmp->y,humanoid.left[idx],tmp->id); break;
            default:        break;
            }

            /****************************/
            /*      モンスター爆発      */
            /****************************/
            if( isdeath(tmp->x,tmp->y) )
            {
                Bomm_List *t = tmp;
                int x = t->map_x;
                int y = t->map_y;

                printf("ID:%d\n",t->id);
                
                fire_container(tmp->x,tmp->y);
                play_se(effect.death);

                tmp = tmp->next;    //次の怪物へ
                del_enemy(t->id);
            } else {
                tmp = tmp->next;    //次の怪物へ
            }
        } while(tmp != NULL);
    }
}

static
void add_enemy(int x, int y,int mapx,int mapy)
{
    Bomm_List *bomm = (Bomm_List*)malloc(sizeof(Bomm_List));

    if(bomm == NULL)
        return;

    memset(bomm,0,sizeof(Bomm_List));
    bomm->id = enemys;
    bomm->x = x;
    bomm->y = y;
    bomm->map_x = mapx;
    bomm->map_y = mapy;
    bomm->next = enemy_top;

    enemy_top = bomm;
    printf("id:%d\n",bomm->id);

    enemys++;
    printf("enemy num:%d",enemys);
}

static
void del_enemy(int id)
{
    Bomm_List *tmp;
    Bomm_List *prev;

    tmp = enemy_top;
    prev = NULL;
    while(tmp != NULL)
    {
        if(tmp->id == id)
        {
            if(prev != NULL)
            {
                prev->next = tmp->next;
                free(tmp);
                break;
            } else {
                enemy_top = tmp->next;
                free(tmp);
                break;
            }
        }
        prev = tmp;
        tmp = tmp->next;
    }
}

static
void enemy_reset(void)
{
    enemys = ID_MONSTER;
}