ホームへ戻る

19章. 弾の画像管理クラスを作る

 この章から弾幕クラスを作る準備をします。
弾幕を作るにはまた準備が必要なので、実行結果が代わり映えしなくてつまらないかもしれませんが、お付き合いください。
まず、弾の画像(ImageBullet)クラスもImageクラスと似たような造りにします。
しかし、弾は全て8色で同じ規則でリソースを作っていますので機械的に処理するような実装にします。

弾の画像データクラスには弾のサイズと、弾の当たり判定の大きさと、弾のZソートの順番の情報を定義します。
Zソートとは、例えば大きな弾の下に小さな弾が表示されてしまうと隠れてしまいます。
従って、小さな弾ほど、上に(後に)描画しなければなりません。
ですので、描画時に大きさ順でソートしなければならないのです。
この時、Zソートする順番は画像サイズでも当たり判定サイズでもありません。
というのも、見た目大きいが、当たり判定が小さい画像や、その逆もあります。
周りが透過しているので、画像自体は大きいが実質隠れる部分は小さいので、あまり下に描画してはいけないということもあります。
従ってZソートの順番の情報は別に定義します。
それではクラスの中身を見て行きましょう。


ImageBullet.h


#pragma once
#include "Singleton.h"
#include <vector>

class Size {
public:
    Size() : w(0), h(0) {}
    Size(int w, int h) : w(w), h(h) {}
    int getWidth()  const { return w; }
    int getHeight() const { return h; }
private:
    int w, h;
};

class ImageBullet final : public Singleton<ImageBullet> {

public:
    enum eBulletType {
        eSmall,	//0
        eBarrier,	//1
        eSparkSmall,   //2
        eKome,		//3
        eUmaibo,	//4
        eSparkBig,	//5
        eKodama,	//6
        eYosei,	//7
        eRing,		//8
        eAme,		//9
        eTama,		//10
        eOdama,	//11
        eLaser,	//12
        eOfuda,	//13
        eStar,		//14
        eRain,		//15
        eRainbow,	//16
        eTypeNum,
    };

    enum eBulletColor {
        eBlue,
        ePurple,
        ePink,
        eOrenge,
        eYellow,
        eGreen,
        eLime,
        eAqua,
        eColorNum,
    };

    const static float RANGE[];
    const static float SORT_Z[];

    ImageBullet::ImageBullet();

private:
    std::vector<int*> _list;
    std::vector<Size*> _sizeList;

    void load() {}
    void myLoadDivGraph(char* fname);
    int get(unsigned int type, unsigned int color) const;
    const Size* getSize(unsigned int type) const;
};

ImageBullet.cpp


#include "ImageBullet.h"
#include "Macro.h"

const float WEIGHT = 0.71f;//下の当たり判定範囲の調整値
//当たり判定半径
const float RANGE[] = 
{
     5.5f * WEIGHT,//Small
     4.0f * WEIGHT,//Barrier
     4.0f * WEIGHT,//SparkSmall
     5.0f * WEIGHT,//Kome
     4.5f * WEIGHT,//Umaibo
     9.0f * WEIGHT,//SparkBig
    10.0f * WEIGHT,//Kodama	//実測12.0f
     6.5f * WEIGHT,//Yosei
     9.0f * WEIGHT,//Ring
    11.0f * WEIGHT,//Ame
    19.5f * WEIGHT,//Tama	//実測23.0f
    38.0f * WEIGHT,//Odama
     2.8f * WEIGHT,//Laser
    10.0f * WEIGHT,//Ofuda
     5.0f * WEIGHT,//Star
     6.0f * WEIGHT,//Rain
     9.0f * WEIGHT,//Rainbow
};
//Zソート
const int SORT_Z[] = 
{
     1,//Small
     5,//Barrier
     4,//SparkSmall
     2,//Kome
     7,//Umaibo
     8,//SparkBig
    12,//Kodama
    10,//Yosei
    11,//Ofuda
    12,//Ring
    14,//Ame
    15,//Tama
    16,//Odama
     3,//Laser
     5,//Star
     6,//Rain
     9,//Rainbow
};

ImageBullet::ImageBullet()
{
    _sizeList.push_back(new Size( 16,  16));//0
    _sizeList.push_back(new Size( 28,  30));//1
    _sizeList.push_back(new Size( 38,  38));//2
    _sizeList.push_back(new Size( 18,  31));//3
    _sizeList.push_back(new Size( 64,  64));//4
    _sizeList.push_back(new Size( 76,  76));//5
    _sizeList.push_back(new Size( 32,  32));//6
    _sizeList.push_back(new Size( 54,  54));//7
    _sizeList.push_back(new Size( 36,  36));//8
    _sizeList.push_back(new Size( 30,  57));//9
    _sizeList.push_back(new Size( 62,  62));//10
    _sizeList.push_back(new Size(108, 108));//11
    _sizeList.push_back(new Size( 12, 240));//12
    _sizeList.push_back(new Size( 28,  32));//13
    _sizeList.push_back(new Size( 34,  34));//14
    _sizeList.push_back(new Size( 20,  34));//15
    _sizeList.push_back(new Size( 20,  20));//16
    myLoadDivGraph("../dat/image/bullet/00.small.png");
    myLoadDivGraph("../dat/image/bullet/01.barrier.png");
    myLoadDivGraph("../dat/image/bullet/02.sparkSmall.png");
    myLoadDivGraph("../dat/image/bullet/03.kome.png");
    myLoadDivGraph("../dat/image/bullet/04.umaibo.png");
    myLoadDivGraph("../dat/image/bullet/05.sparkBig.png");
    myLoadDivGraph("../dat/image/bullet/06.kodama.png");
    myLoadDivGraph("../dat/image/bullet/07.yosei.png");
    myLoadDivGraph("../dat/image/bullet/08.ring.png");
    myLoadDivGraph("../dat/image/bullet/09.ame.png");
    myLoadDivGraph("../dat/image/bullet/10.tama.png");
    myLoadDivGraph("../dat/image/bullet/11.odama.png");
    myLoadDivGraph("../dat/image/bullet/12.laser.png");
    myLoadDivGraph("../dat/image/bullet/13.ofuda.png");
    myLoadDivGraph("../dat/image/bullet/14.star.png");
    myLoadDivGraph("../dat/image/bullet/15.rain.png");
    myLoadDivGraph("../dat/image/bullet/16.rainbow.png");
}

/*!
@brief 弾の画像をロードして_listに格納する
*/
void ImageBullet::myLoadDivGraph(char* fname) 
{
    int id = _list.size();
    Size* size = _sizeList[id];
    int *bullets = new int[eColorNum];
    LoadDivGraph(fname, eColorNum, eColorNum, 1, size->getWidth(), size->getHeight(), bullets);
    _list.push_back(bullets);
}

/*!
@brief type種別のcolor色の弾の画像ハンドルを取得
*/
int ImageBullet::get(unsigned int type, unsigned int color) const 
{
    if (eTypeNum <= type) {
        ERR("弾のtypeが不正です");
    }
    if (eColorNum <= color) {
        ERR("弾のcolorが不正です");
    }
    return _list[type][color];
}

/*!
@brief type種別の画像サイズを返す
*/
const Size* ImageBullet::getSize(unsigned int type) const 
{
    if (_sizeList.size() <= type) {
        ERR("wh_tのgetSizeの指定が間違っています");
    }
    return _sizeList[type];
}

ロードするのは以下の画像です。

00.small

01.barrier

02.sparkSmall

03.kome

04.umaibo

05.sparkBig

06.kodama

07.yosei

08.ring

09.ame

10.tama

11.odama

12.laser

13.ofuda

14.star

15.rain


eBulletTypeはこの弾の種別を名前付けして定義しています。
eBulletColorは全て同じ順番で8色構成になっているので、左から順番の色の定義です。
RANGEは当たり判定範囲です。弾幕シューティングにおいて当たり判定範囲は非常に大事なので、この辺お好みに応じて微調整してください。
SORT_Zは上で言った通りのZソートの順番情報です。
コンストラクタのsizeのpushは各画像の縦横サイズを格納しています。
myLoadGraphはそのサイズに応じて画像をロードし、_listに格納します。

外から弾の画像を取得するときは
int get(unsigned int type, unsigned int color);
で取得します。
取得したい弾の種別と色を指定して取得します。

次はこれを使った弾クラスを作ってみましょう。

→分からないことがあれば掲示板で質問して下さい


HPトップへ 質問掲示板へ

- Remical Soft -