もっとLuaからゲーム本体の動作を変更できるようにする仕組み
結局、前回の3連休では
VC++ロジックをLuaに持っていくことを具体的に考える
というのが途中までで終わってしまった。
特に3連休の最終日は、
体調が悪くて一日中寝てたんじゃないかというくらい
起き上がれなかった・・・
さすがに今週末のうちには、やっつけてしまいたい。
ということで、具体的に考えるのの続きから。
まずは、おさらいとして
現在、VC++側で「マップごとにやっていること」を書き出してみる。
・マップの初期処理
・マップのオープニング
・マップレイヤー1の描画
・マップレイヤー2の描画
・マップレイヤー3の描画
・マップレイヤー4の描画
・マップレイヤー5の描画
・ミクの描画より奥に描画するイベント(★)
・ミクの描画より手前に描画するイベント(★)
・敵の描画
・マップのクリア判定
・マップのエンディング
さらにボスマップでは
・ボスに勝った後のイベント
それからイベントでプレイヤーが操作していないのにミクがに動く時に
・イベントからのキー入力の受け取り(★)
といったことをやっている。
現時点でもLua側で処理しているのが(★)の部分だ。
この中には絶対にVC++側でやらないとイケないことってのは存在しない。
強いて挙げるとするなら、処理速度が求められそうな描画系の処理だろう。
マップや敵の描画といったあたりだ。
しかし、マップの作成中は、お試しでマップチップを配置したりしてみたい。
というか、既にマップクリエーターのロジックで
マップチップをLuaから描画する仕組みができている。
次に「敵の描画処理」だが
実際には「敵の描画処理」では、敵の思考ルーチンというか
敵の動きのコーディングもしているのだが
敵の動きってのは、微調整が必要になる部分なので
調整の都度、VC++側をリコンパイルというのは、
コンパイルの待ち時間が発生してしまうので開発の流れとしては良くない。
ということで、マップごとにVC++でやっていることは
全部Luaからもできるようにしたい。
これまでのLuaの呼び出しの流れは
マップごとの関数からLuaの該当処理を行う関数を呼び出す流れだった。
この流れで行くと、既存の20+αのマップ数分、これらの対応が必要になる。
力作業として、ゴリ書きしていくという作戦もあるが
基本的に、かげさんは面倒臭いことはイヤだと思う性格である。
労力が少なく、やりたいことをやりたい。
なので、もうちょっと考えてみる。
各マップのVC++から呼び出されるLuaの関数名は
mapXX_YYZZ
といった名前になっている。
XX:ステージ番号
YY:ステージ毎のマップ番号
ZZ:Lua関数を呼び出すVC++の各マップソースの関数のイベント名
例えば、
ステージ :02 ボカロタウン
マップ番号 :04 ルネッタ・キーア
VC++側の呼び出し関数 :checkMap02_04EventBehind
Lua で呼び出される関数:Map02_04EventBehind
といった具合だ。
「ステージ番号」と「ステージ毎のマップ番号」は、
VC++側のグローバル変数なので、どこからでも参照できる。
各マップのVC++側の関数は、VC++側で関数ポインタとして設定していて
initMapという関数で、以下のような処理がある。
checkMapEventBehind = checkMap02_04EventBehind;
ちなみに別のマップでも
checkMapEventBehind = checkMap02_05EventBehind;
といったコーディングをしている。
これは、どういうことかというと
checkMapEventBehind();と記載した時に
ステージ :02 ボカロタウン
マップ番号 :04 ルネッタ・キーア
であれば、checkMap02_04EventBehindが呼び出され
ステージ :02 ボカロタウン
マップ番号 :05 食わねーわよ
であれば、checkMap02_05EventBehindが呼び出される
という仕組みである。
オブジェクト指向プログラミングでいうところの
多態性に相当することを
言語仕様的にオブジェクト指向プログラミングが
できないがなかった頃のC言語では、
この関数ポインタを使って行っていたわけだ。
checkMap02_04EventBehindからは、LuaのMap02_04EventBehindが呼び出され
checkMap02_05EventBehindからは、LuaのMap02_05EventBehindが呼び出される。
つまりVC++でマップごとの関数の呼び出す箇所で
同じようにLuaの関数を呼び出せればOKだ。
上の例だと「EventBehind」という部分が分かれば
他はグローバル変数なので文字列操作でLuaの関数名が決定できる。
さて、このやり方だと、
「(20+α)のマップ数」×「(★)となっていない11のマップごとの関数」箇所の
Lua関数を呼び出す修正が、「(★)となっていない11のマップごとの関数」箇所だけで
済むようになるものの、
今度は、呼び出すLua側の関数をが無いと怒られる事になる。
ちなみに「マップの初期処理」と「マップのオープニング」以外は、
ゲームのメインループから呼び出されるので、
60FPSだと1秒間に60回ずつ呼び出される。
つまり、1秒間に11×60回、Lua関数が呼び出せないと怒られることになる。
1度怒られれば、呼び出せないことは分かるので
せめて1つのマップで「呼び出せない!」と怒られるのは11回で済ませたい。
このため、11個の呼び出しチェック用のグローバル変数を用意し、
マップが切り替わるinitMapの処理で、初期化して
呼び出しチェック用変数が初期値の場合、
Lua関数の呼び出しを試みて、呼び出せなかったら、呼び出し不要と値を変更、
呼び出せたら、呼び出し可能の値にする。
メインループでは、呼び出し可能な場合に、Lua関数を呼び出すことにする。
こうすることで、Luaに呼びだそうとしている関数が存在する場合だけ
呼び出されるようになる。
最終的に、必要なときだけLua側で関数を作って、処理を書くことで
初音ミク冒険記の本体側の動きを変更できるようになるって作戦だ。
ここまでできたら、各マップのVC++側のソースをLua側に持っていけるようになる。
おそらく、各マップの初期処理の一部と既存のマップ描画処理、
パズルエリアのギミックなど、Luaに持って行きづらい部分を除いて、
大部分がLuaに持っていけると思う。
とりあえず、昼ご飯を食べたら、Lua呼び出しする流れを作ってみよう。
| 【固定リンク】 | 【コメント (0)】 | 【トラックバック (0)】
このエントリーへのリンク
トラックバック
この記事へのトラックバックの一覧です: もっとLuaからゲーム本体の動作を変更できるようにする仕組み:



コメント
このブログの新着コメントをRSSリーダに登録する為のxml