弾幕関数の管理方法 [四聖龍神録2公式Twitter]

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

弾幕関数の管理方法 [四聖龍神録2公式Twitter]

投稿記事 by Dixq (管理人) » 9年前

今日は沢山ある弾幕関数の管理方法です。

龍神録プログラミングの館の方法で弾幕を管理しようとすると非常に大変なことでしょう。

例えば弾幕には「ボス」が出す弾幕と「雑魚」が出す弾幕があります。
そしてそれ全てに
・Easy
・Normal
・Hard
・Lunatic
があるわけですので、100種類(本来もっとありますが)弾幕があったとすれば、
弾幕メソッド数は単純計算で合計800個以上になります。
これ全部に関数ポインタを登録するのは大変です。
そこで楽ちん弾幕メソッド管理方法です。

弾幕(Barrage)クラスの抽象クラスをBarrageとして定義し、
そこから雑魚とボスにわけ、さらに全レベルに継承していきます。
class.png
class.png (21.75 KiB) 閲覧数: 733 回
Barrageクラスには
純粋仮装関数
virtual void Barrage000() = 0;
virtual void Barrage001() = 0;
virtual void Barrage002() = 0;
・・・を定義していきます。

ここで関数ポインタの登録は継承先で800個もいちいち格納したくないですよね。
そこで、継承元で登録してみます。

CODE:

class Barrage
{
protected:
	std::list> _bulletList;

	typedef void(Barrage::*FUNC)();
	std::vector _funcList;

	virtual void Barrage000() = 0;
	virtual void Barrage001() = 0;
	virtual void Barrage002() = 0;
	virtual void Barrage003() = 0;
	virtual void Barrage004() = 0;
	virtual void Barrage005() = 0;
	virtual void Barrage006() = 0;
	virtual void Barrage007() = 0;
	virtual void Barrage008() = 0;
	virtual void Barrage009() = 0;
	virtual void Barrage010() = 0;
        ...(略)
実装されていない純粋仮装関数のポインタ配列ってどうやって作るの?
という疑問にお答えするのがこのコード

typedef void(Barrage::*FUNC)();

の定義に対して

std::vector _funcList;

を定義

CODE:

void Barrage::setFunc() {
	_funcList.push_back(&Barrage::Barrage000);
	_funcList.push_back(&Barrage::Barrage001);
	_funcList.push_back(&Barrage::Barrage002);
	_funcList.push_back(&Barrage::Barrage003);
	_funcList.push_back(&Barrage::Barrage004);
	_funcList.push_back(&Barrage::Barrage005);
	_funcList.push_back(&Barrage::Barrage006);
	_funcList.push_back(&Barrage::Barrage007);
	_funcList.push_back(&Barrage::Barrage008);
	_funcList.push_back(&Barrage::Barrage009);
	_funcList.push_back(&Barrage::Barrage010);
}
で格納します。
すると継承先ではもう登録する必要はありません。
例えば雑魚のイージーだったら
Barrage* _barrage = new BarrageZakoEasy();
でインスタンスを作り、
その中で
_funcList[id]();
するだけで対象(id)のメソッドを呼び出せます。
どの弾幕であるかを示すidは館で紹介している方法でエクセルから取ってきます。
最後に編集したユーザー Dixq (管理人) on 2016年2月26日(金) 21:29 [ 編集 3 回目 ]

アバター
やふう!
記事: 4
登録日時: 10年前

Re: 弾幕関数の管理方法 [四聖龍神録2公式Twitter]

投稿記事 by やふう! » 9年前

私もちょうどC++でゲームプログラミングしているので、とても勉強になりました。
そこで質問があります。

Q. listをvectorに変えると、どのようなデメリットがありますでしょうか?

つくばさん
記事: 22
登録日時: 9年前

Re: 弾幕関数の管理方法 [四聖龍神録2公式Twitter]

投稿記事 by つくばさん » 9年前

一つ質問がありますがよろしいですか?

例えば雑魚のイージーだったら
Barrage* _barrage = new BarrageZakoEasy();
でインスタンスを作り、
その中で
_funcList[id]();
するだけで対象(id)のメソッドを呼び出せます。

と本文にありますが
_funcListはBarrageClassでは protectedメンバーとして宣言されていてアクセスできない気がするのですがどうなっているのでしょうか