スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【雑談】【絵】SOUND VOLTEX IV アピールカード用の絵

SOUND VOLTEX IV のアピールカード用にレイシス描いてみたのですがさすがに落ちましたねw
そういうわけで供養の意味もこめてこっちにも上げてみました。
次回またイラコンあると思うのでその時はマシな絵を描こうと誓いました。

うん、太もも描きたかってん・・・

download.png
スポンサーサイト

【雑談】SOUND VOLTEX IV

メインにしている音ゲー SOUND VOLTEX。
4作目となる今作で念願の 暴流天 になれました。
次回以降の SKILL ANALYZER が更新されても金枠を保ちたいですね・・・。
さすがに平均970の 暴流天 後光 は今の地力では到底及ばないので、金枠維持を今作目標にしたいと思います。

PC 全然触らなくなったな・・・。

std::list と boost::shared_ptr を使った弾生成、弾管理クラス

Twitter でぶつぶつ独り言のようにつぶやいてた部分について一旦まとまったので記事にしてみました。
なんてことない記事なのですが、いつものメモ代わりもこめて。

今回はシューティングを作成していることもあって、弾の生成、弾の管理についてまとめていきます。

- 弾の管理は std::list を使ってリストで管理
- 弾は動的に生成するため、スマートポインタの boost::shared_ptr を使ってみました
(C++11 の std::shared_ptr も代用はきくと思いますが、詳しくしは知りません)

弾のベースクラスを作成しよう
何はともあれ弾のメインとなる情報を持ったベースクラスを作成しました。


// 弾ベースクラス
class CBulletBase
{
public:
virtual void update() { std::cout << "CBulletBase::update()\n"; }

CBulletBase() { };
virtual ~CBulletBase() {};
};

ベースクラスから派生しよう
このクラスを派生し、自機狙いや円形弾など固有の動きをするクラスを作成してみました。



// 自機狙い弾クラス
class CBulletAiming : public CBulletBase
{
public:
virtual void update() override { std::cout << "CBulletAiming::update()\n\n"; }
CBulletAiming() { std::cout << "Create CBulletAiming\n"; };
virtual ~CBulletAiming() { };
};

// 円形弾
class CBulletCircle : public CBulletBase
{
public:
virtual void update() override { std::cout << "CBulletCircle::update()\n\n"; }
CBulletCircle() { std::cout << "Create CBulletCircle\n"; };
virtual ~CBulletCircle() { };
};


弾生成の骨組みを作成しよう
この辺をどうしようかなと思ったのですが、とりあえずファクトリクラスなるものを作成し、
弾の ID を引数として受け取り、その ID を元に、自機狙い弾、円形弾などを生成します。
簡単ではありますが、実装はこんな感じになりました。


// 弾生成
class CBulletFactory
{
public:
boost::shared_ptr<CBulletBase> create(int bulletID)
{
switch (bulletID)
{
case 0: return boost::shared_ptr<CBulletBase>(new CBulletAiming());
case 1: return boost::shared_ptr<CBulletBase>(new CBulletCircle());
}
return NULL;
}
};


case 0、case 1 とかマジックナンバーになってますが、
enum で列挙しておくと使いやすそうですね。(今回はマジックナンバーにしました)

また、スマートポインタを使わず管理してもよさそうですが、
せっかく便利な機能があるので使ってみようかなということでこうしてます。
これで、弾の生成や弾の基本情報を持ったクラスの作成が完了しました。


弾管理クラスを作成しよう
これらのクラスをどう扱うか考えたのですが、
弾の管理クラスを作成し、その中でリスト管理してみる方向にしました。
弾管理クラスはこんな実装になりました。


// 弾管理マネージャ
class CBulletMng
{
private:
CBulletFactory m_Factory; // 弾生成クラス
std::list< boost::shared_ptr<CBulletBase> > m_List; // リスト

public:
void create(int bulletID)
{
m_List.push_back( m_Factory.create(bulletID) );
}

void update()
{
std::list< boost::shared_ptr<CBulletBase> >::iterator wIt;

// リスト内を全て更新
for (wIt = m_List.begin(); wIt != m_List.end(); ++wIt)
(*wIt)->update();
}
};


std::list で弾をリストで保持するメンバ変数を用意し、
create メソッドに引数である bulletID(この例では、0か1)を渡すと、対象の弾が生成され
このリストの中に push_back されます。

update メソッドではリスト内にある弾クラスの update メソッドを呼び出しているので
自機狙い、円形弾などのバリエーションごとに更新を呼び出してます。

特に必要ないとおもいますが、メインはこんな感じで生成と更新をするようになりました。



int main()
{
CBulletMng wMng;

// ID を1→ 0→ 1→ 0 と変化させて交互に生成
for (int i = 1; i < 6; ++i)
wMng.create(i%2);

wMng.update();

return 0;
}


ID さへ渡せば中で弾の生成やリストでの管理を行ってくれます。
今回はマジックナンバーなのでベタに for文で適当に交互に ID を渡すようにしました。

この部分は一例として

wMng.create(TYPE_AIMING);
wMng.create(TYPE_NWAY);

のようにしていれば、自機狙い弾、nway弾の生成してそうだな
ってのが一目で見て分かるかな…

スマートポインタになっているので、明示的な delete をする必要も(多分)なさそうですし、
より安全に動的作成してもよさそうかなと思いました。

m_List.clear(); と呼ぶとリスト内を全て消すことも出来ますし
リスト管理は色々便利ですね。


一応出力結果は下記になります。


Create CBulletCircle
Create CBulletAiming
Create CBulletCircle
Create CBulletAiming
Create CBulletCircle

CBulletCircle::update()
CBulletAiming::update()
CBulletCircle::update()
CBulletAiming::update()
CBulletCircle::update()


それぞれの弾クラスの update メソッドが呼ばれておりますので多態勢も大丈夫そうです。


これだけではないのですが、大まかにこんな流れの骨組みをここ1-2日で作成しておりました。
現在はボタンを押すと弾が発射され、移動するというところまでの実装は出来ましたので
まずは気になっていた大きな部分を一つクリアしたかなという印象です。

プログラムやっぱり楽しいですが、知らん間に時間が経って睡眠時間が削られてたりすることが多いです。
しばらく離れていたのでなんとか進めたいです・・・

std:min、std::max 使用時に出る C2589 '(': スコープ解決演算子 (::) の右側にあるトークンは使えません

無事長崎から帰ってきました。
すごくいい所でした。
ハウステンボス楽しみにしてたので凄く満足です!
美味しいものいっぱいありますね・・・!


帰宅後はまたボチボチとプログラムをやってます。
今日出たエラーについて記事にしてみました。

#include <algorithm>
を定義し、std::min、std::max を使用した時下記エラーが出ました。

サンプルコード:
abc = std::max(abc - 1, 0);

C2589 '(': スコープ解決演算子 (::) の右側にあるトークンは使えません

何でだろうと思い調べてみるとこんな記事が。

https://support.microsoft.com/ja-jp/kb/143208 より抜粋。

問題は、min と max の競合する定義で発生します。
Min および max」は次のように Windef.h でマクロとして定義されます。


何気なしに使ってた <windows.h> との競合が原因だったようです。
解決方法については


NOMINMAX のプリプロセッサ シンボルを定義します。
これは、Developer Studio プロジェクトをビルド、設定、C または C++] タブの [プリプロセッサ] カテゴリで、上で実行できます。これは、最小、Windef.h で最大の定義に表示されません。


日本語については置いておくとして、

#define NOMINMAX
#include <windows.h>

windows.h を include する前にこんな感じで防ぐことが出来るみたいです。
サンプルプログラムでよく使ってたのですが何気に Windows アプリケーション開発の中では初だったんだなと思いました。

ふ~んって感じの記事でしたがとりあえず書いてみました。

マクロ展開しないとかほかの方法で回避も出来ると思いますが、せっかく公式に書いてたので
この方法を使ったら普通に使えるようになりました。

【雑談】長崎に旅行中

ただいま、大阪より旅立ち長崎へ来ております。
今日で2日目になりますが、1日目にハウステンボスの半分以上は見れました。

今日はアトラクション系をメイン回る予定なので楽勝だと思います。
イルミネーションは凄く綺麗でした。
帰りは明日ですが、思う存分楽しんできます。
お土産何にしよかなー
NEXT≫
検索フォーム
プロフィール

DVDM

Author:DVDM
自作ゲームの開発過程ブログ。
赤髪愛なら誰にも負けない。

 
Pixiv バナー


ブロとも申請フォーム
最新記事
カテゴリ
最新コメント
最新トラックバック
RSSリンクの表示
リンク
ブロとも一覧
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。