合計 昨日 今日

アバター
Dixq (管理人)
管理人
 
記事: 1394
登録日時: 2010年10月12日(火) 20:16
お住まい: 北海道札幌市
日記: 日記を見る (544)
日記
- 5月 2017
アメリカに着きました (4)
   2017年5月17日(水) 08:22
新車購入しました! (4)
   2017年5月07日(日) 18:40
改竄されない変数の作り方 (9)
   2017年5月04日(木) 03:16

+ 4月 2017
+ 3月 2017
+ 2月 2017
+ 1月 2017
+ 12月 2016
+ 11月 2016
+ 10月 2016
+ 9月 2016
+ 8月 2016
+ 7月 2016
+ 6月 2016
+ 5月 2016
+ 4月 2016
+ 3月 2016
+ 2月 2016
+ 1月 2016
+ 12月 2015
+ 11月 2015
+ 10月 2015
+ 9月 2015
+ 8月 2015
+ 7月 2015
+ 6月 2015
+ 5月 2015
+ 4月 2015
+ 3月 2015
+ 2月 2015
+ 1月 2015
+ 12月 2014
+ 11月 2014
+ 10月 2014
+ 9月 2014
+ 8月 2014
+ 7月 2014
+ 6月 2014
+ 5月 2014
+ 4月 2014
+ 3月 2014
+ 2月 2014
+ 1月 2014
+ 12月 2013
+ 11月 2013
+ 10月 2013
+ 9月 2013
+ 8月 2013
+ 7月 2013
+ 6月 2013
+ 5月 2013
+ 4月 2013
+ 3月 2013
+ 2月 2013
+ 1月 2013
+ 12月 2012
+ 11月 2012
+ 10月 2012
+ 9月 2012
+ 8月 2012
+ 7月 2012
+ 6月 2012
+ 5月 2012
+ 4月 2012
+ 3月 2012
+ 2月 2012
+ 1月 2012
+ 12月 2011
+ 11月 2011
+ 10月 2011
+ 9月 2011
+ 8月 2011
+ 7月 2011
+ 6月 2011
+ 5月 2011
+ 4月 2011
+ 3月 2011
+ 2月 2011
+ 1月 2011
+ 12月 2010
+ 11月 2010
+ 10月 2010
フォロー
カテゴリー
日常
1 記事

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

パーマリンクby Dixq (管理人) on 2016年2月26日(金) 20:52

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

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

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

弾幕(Barrage)クラスの抽象クラスをBarrageとして定義し、
そこから雑魚とボスにわけ、さらに全レベルに継承していきます。

class.png
class.png (21.75 KB) 表示数: 690 回


Barrageクラスには
純粋仮装関数
virtual void Barrage000() = 0;
virtual void Barrage001() = 0;
virtual void Barrage002() = 0;
・・・を定義していきます。

ここで関数ポインタの登録は継承先で800個もいちいち格納したくないですよね。
そこで、継承元で登録してみます。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Barrage
{
protected:
    std::list<std::shared_ptr<Bullet>> _bulletList;
 
    typedef void(Barrage::*FUNC)();
    std::vector<FUNC> _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<FUNC> _funcList;

を定義
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
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 (管理人) [ 2016年2月26日(金) 21:29 ], 累計 3 回

コメント数: 2 閲覧数: 7790
コメント

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

パーマリンクby やふう! on 2016年3月13日(日) 22:06

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

Q. listをvectorに変えると、どのようなデメリットがありますでしょうか?
ドット絵修行中 . . .
アバター
やふう!
 
記事: 4
登録日時: 2015年3月03日(火) 13:40
日記: 日記を見る (0)

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

パーマリンクby つくばさん on 2016年3月28日(月) 16:54

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

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

と本文にありますが
_funcListはBarrageClassでは protectedメンバーとして宣言されていてアクセスできない気がするのですがどうなっているのでしょうか
つくばさん
 
記事: 22
登録日時: 2016年2月25日(木) 18:46
日記: 日記を見る (0)

オンラインデータ

登録ユーザー: なし