Sirius X

需要無視の自己満足ブログです。

【C++】【ゲーム開発】デザインパターン(State)導入

Category:C/C++, Rockman Reanimated, ゲーム開発, プログラミング入門・学習 Comment:0

eye-catch

ここ一週間悩みに悩んで実装しておりました、State patternです😅
これがやりたかった。。。

設計セオリーを知らない人なので、こういった場面において構築に苦戦してしまいますね。

とにかくメンテナンス性が高いソースコードを書く。
それが最終的な到達点。

デザインパターンはGoFと呼ばれている人たちによって書かれた書籍のコーディングスタイルの併称なのですが、実はC言語を古くからやっていた私も知りませんでした😵💫
初めて聞いた時にも「なにそれ?」ってな感じ(笑)

「デザインパターン」で検索するとそれに関係する内容が多く出てきます。
オブジェクト指向における分類なので、Javaの実装例が多い印象ですが、これを参考にC++にも導入してみました。

C++は理由あってインターフェースとかabstractクラスがないので、そこはプログラマー的に分かるように適応させてあります。
(具体的には名前空間名にキーワードを使用)


導入しようと思った経緯と元となるソースコード

まず元のコードだが、以下のようなもの。

...
    int nSeq;
    int* levels;
    
    /// <summary>
    /// ゲームプログラム本体。
    /// </summary>
    /// <param name="">なし。</param>
    /// <returns>エラーが発生した場合に 0 以外を返却する。</returns>
    int Fn_ExecuteMainGameSequencer(void) {

        nSeq = Get_gSequenceTraffic();

        switch (nSeq) {
// =============================================================================================================================
// *** CONSTRUCTOR PROCEDURE ***    
// =============================================================================================================================
        case PGBANKMAPPER_ZEROPAGE:

            /* ゲーム全体の初期化処理 */
            levels = new int;

            /* envファイルからのデータ取り込み */
            

            /* その他初期処理 */


            Set_gSequenceTraffic(PGBANKMAPPER_DEMO_STAGE);
            *levels = 0;
            break;

// =============================================================================================================================
// *** DEMO STAGE SCENE PROCEDURE ***    
// =============================================================================================================================
        case PGBANKMAPPER_DEMO_STAGE:
            
            switch (*levels) {
            case 0:
                /* 初期化処理 */
                if (!idx3A::Sub_Rawdata_Initialize()) {
                    return -0x3A01;  // エラー判定異常終了
                }
                if (!idx3A::Sub_Parameter_Initialize()) {
                    return -0x3A02;  // エラー判定異常終了
                }
                *levels = 1;
                break;
            case 1:
                /* 描画処理 */
                if (!idx3A::Sub_BackGround_DrawGraph()) {
                    return -0x3A12;  // エラー判定異常終了
                }
                if (!idx3A::Sub_Sprite_DrawGraph()) {
                    return -0x3A13;  // エラー判定異常終了
                }
                /* 発音処理 */
                if (!idx3A::Sub_Playing_SoundTone()) {
                    return -0x3A14;
                }
                /* 計算処理 */
                if (0 != idx3A::Sub_PlayerAllOperation()) {
                    return -0x3A11;  // エラー判定異常終了
                }
#ifdef DEVELOPER_MODE
                /* DEBUG MODE ONLY */
                idx3A::Debug_Code();
#endif
                break;
            }
            break;
        default:            
            break;
        }

        return 0;
    }

...

なんかかなり古いやつなんですが、switch文でPGコードを分岐しています。

確かにこれでもちゃんと動くのですが、これに肉付けしていけばいくほどどのゲームシーンがどこにあるか
探さないといけなくなります。

トレジャーハンターじゃないんだから関数名とかで分割しておきたい、と思う訳です。
必然的に。

そうなるとファイル分割ですが、それをするとゲームシーンのフラグが宙ぶらりんになって、しまいにはグローバル変数を使うようなオチになってしまうという事です。

そりゃまずいでしょ…と思い、探してみるとなんとswitch文を削除してロジカルなソースコードにする技が業界に存在している事を突き止めるわけです。

こんな本もあったりします( ^ω^)

Game Programming Patterns ソフトウェア開発の問題解決メニュー impress top gearシリーズ

美味しいフルーツを栽培する方法(が書かれているわけではありません)😂
結構ためになってます。

コメントを残す

メールアドレスが公開されることはありません。