この章から弾幕クラスを作る準備をします。
弾幕を作るにはまた準備が必要なので、実行結果が代わり映えしなくてつまらないかもしれませんが、お付き合いください。
まず、弾の画像(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);
で取得します。
取得したい弾の種別と色を指定して取得します。
次はこれを使った弾クラスを作ってみましょう。