FPSを作ってみる@wiki
02)
最終更新:
slice
-
view
(2014/02/23)
LuaとC++オブジェクトの仕様を固めている&実装途中なので現状あまり書くことがない。
以下、オブジェクトはLuaで記述したクラス。ベースクラスはC++で記述したクラスとすると
- スクリプトファイルはオブジェクト名を含んだ単一のスクリプトファイル(ObjectName.lua)を用いる=Java仕様
- オブジェクトは基本となるC++のクラス(キャラクターや銃弾など)を1つ指定してそのインスタンスを内部に持つ
- オブジェクトは状態遷移機構を持つ。C++のベースクラスも内部に持つ物があるが、Luaからその存在はわからない。
- オブジェクトはベースクラスのメンバやメソッドを参照できる
- オブジェクト間の情報交換や指示はLuaで行い、文字列と任意個のパラメータを含むメッセージを渡す形になる
- あくまでオブジェクトがベースクラスを「使う(知っている)」関係なのでベースクラスからオブジェクトのメンバを参照したりメソッドを呼んだりは出来ない。が、上記のようなメッセージを送るのは可
- Lua -> C++ へメッセージを送るのも可
- 描画(モデルの管理)や当たり判定はLuaからは扱わず、C++のみとする。Luaから制御したい時は必要に応じてベースクラスにメソッドを用意する
- オブジェクトのステート継承をサポート
- オブジェクト自体の継承は未定。複雑になりすぎないようだったら入れる
あとオブジェクトのstatic変数やグローバル変数の扱い、システム関数なんかもあるけどざっくりと、こんな感じで。
2月末までに動けばいいな。と、言った時には大体間に合わないんだけども。
2月末までに動けばいいな。と、言った時には大体間に合わないんだけども。
(2014/02/16)
自分の場合面倒臭がってコメントをあまり書かないし
コードがコピペっぽくなってる所は発見次第纏めてしまうせいもあってか
一日で1000行も行かない日が多い。
でも、世の中に2000、3000行は普通に書ける人は居るらしい・・
コードがコピペっぽくなってる所は発見次第纏めてしまうせいもあってか
一日で1000行も行かない日が多い。
でも、世の中に2000、3000行は普通に書ける人は居るらしい・・
御託はともかく。
スクリプトの組み込み
とりあえずWindowsで動いたから次はAndroidか、ゲームの実装を進めるか・・・と暫し迷って
「Androidで動かすにしてもサンプル程度じゃ面白くないよね」という事で
一刻も早くゲームを動かす方向で作業中。
「Androidで動かすにしてもサンプル程度じゃ面白くないよね」という事で
一刻も早くゲームを動かす方向で作業中。
当たり判定ルーチンに一抹の不安が残るがそれはさておき、
ゲームらしくと言えば次はいよいよスクリプトである。
自作エンジンのコンパイルに手持ちのCPU(PhenomII X4 955)で少なくとも20秒〜最悪2分は掛かる規模に膨らんでしまった現在
スクリプト無しにゲームバランスの試行錯誤など考えられないのだ。
ゲームらしくと言えば次はいよいよスクリプトである。
自作エンジンのコンパイルに手持ちのCPU(PhenomII X4 955)で少なくとも20秒〜最悪2分は掛かる規模に膨らんでしまった現在
スクリプト無しにゲームバランスの試行錯誤など考えられないのだ。
前回は「なんでもかんでもスクリプト」でやろうとして、結果として
コード補完が効かないし動作も遅いスクリプトでゲームの大半を動かす本末転倒な事態になってたので今回は慎重に。
言語は引き続き使い慣れたLuaを使い、以前乱用し過ぎていた擬似クラスは
ベクトルやクォータニオンなんかの基礎的な物にとどめ、極力使わない方針。
コード補完が効かないし動作も遅いスクリプトでゲームの大半を動かす本末転倒な事態になってたので今回は慎重に。
言語は引き続き使い慣れたLuaを使い、以前乱用し過ぎていた擬似クラスは
ベクトルやクォータニオンなんかの基礎的な物にとどめ、極力使わない方針。
下手に何にでも使える汎用クラスは作らずに例えばFPSのキャラクタークラスならC++で
ジャンプ、方向転換、移動などの関数を持つキャラクターのベースを用意し
キー入力に対応する動作などをスクリプトで関連付ける。
ジャンプ、方向転換、移動などの関数を持つキャラクターのベースを用意し
キー入力に対応する動作などをスクリプトで関連付ける。
銃弾ならC++で直進移動する銃弾クラスを作って、移動速度や追尾対象なんかをスクリプトで設定する。
軌跡に煙を残すならC++のスプライトクラスを一定間隔で現在位置に作成する〜みたいな。
軌跡に煙を残すならC++のスプライトクラスを一定間隔で現在位置に作成する〜みたいな。
と、まだ設計中なんで抽象的な事しか書けないが・・
またしてもラッパークラス
Luaの組み込み・・それ以前にLuaのAPIはスタックマシンベースで変数の操作に癖があり、
いちいちスタックの何番にどの値が〜とか、都度コメント残してくのは手間だし管理も大変なので
まずはC++風に変数とオペレータで値をコピーやセットできるようなクラスをば。
前にもラッパークラスで同じ様な事をしていたがあの時は不慣れなせいか色々と不満点(主に効率)があったので
現在書き直している。
いちいちスタックの何番にどの値が〜とか、都度コメント残してくのは手間だし管理も大変なので
まずはC++風に変数とオペレータで値をコピーやセットできるようなクラスをば。
前にもラッパークラスで同じ様な事をしていたがあの時は不慣れなせいか色々と不満点(主に効率)があったので
現在書き直している。
(2014/02/10)
動くと見せかけて動かない、かと思えば
さて、動いたからアップするかーと思ってデバッグで入れてたprintf系の命令を削除し、再ビルドしたら動かない。
え?と元に戻してビルドするもやっぱり動かない。訳が分からん。
結局一度cleanしてから再度ビルドかけて事なきを得た。
今更感ありありだけどWindows版をアップしておいた。
例のごとく、何時ものアップローダからどうぞ。
ドライバのバージョンが取得できてなくて変な数値になってるが、とりあえず動くようだ・・
え?と元に戻してビルドするもやっぱり動かない。訳が分からん。
結局一度cleanしてから再度ビルドかけて事なきを得た。
今更感ありありだけどWindows版をアップしておいた。
例のごとく、何時ものアップローダからどうぞ。
ドライバのバージョンが取得できてなくて変な数値になってるが、とりあえず動くようだ・・
で、バグの原因はアラインメントずれではなくOpenGLのAPIを自前で読み込んでる部分で関数宣言をstdcallにしていなかった事。
Linuxでは恐らくgccのデフォルトと同じcdeclなので問題ないけどWindowsのDLLではstdcallを使っている関係で不具合が起こる。
前にフレームポインタを省略しなければ動くと書いたがやはり「たまたま動いてただけ」だった。
Windows版だけstdcallで宣言するように修正したら-O2でも何事もなく動いた。
Linuxでは恐らくgccのデフォルトと同じcdeclなので問題ないけどWindowsのDLLではstdcallを使っている関係で不具合が起こる。
前にフレームポインタを省略しなければ動くと書いたがやはり「たまたま動いてただけ」だった。
Windows版だけstdcallで宣言するように修正したら-O2でも何事もなく動いた。
いやぁしかし、こんなので数日潰したなんて近年稀に見る大失態である。
Vim
Ubuntu版を公開してから実に一週間以上。
何をしていたかといえばご覧の通りMinGWで動くだの動かないだのでずっと足踏みしてた訳であるが
何をしていたかといえばご覧の通りMinGWで動くだの動かないだのでずっと足踏みしてた訳であるが
ただ救いがあるとすればMinGW版をフルでビルドするのに一回5分はかかる関係で
その間Vimの操作方法や設定を勉強していたら、結果的に開発環境を殆どVimに移行できた事か。
vimからmakeを呼ぶコマンドはあるのでMakefileを復習しつつ、
cmakeもmakeもデプロイもvimのコマンドで実行できるようにした。
gdbによるデバッグだけまだという感じで。これはまたの機会に。
その間Vimの操作方法や設定を勉強していたら、結果的に開発環境を殆どVimに移行できた事か。
vimからmakeを呼ぶコマンドはあるのでMakefileを復習しつつ、
cmakeもmakeもデプロイもvimのコマンドで実行できるようにした。
gdbによるデバッグだけまだという感じで。これはまたの機会に。
(2014/02/09)
とりあえず、動いたという事だけ。
諸処の御託はまた明日
(2014/02/07)
明日は広い範囲で雪が降るらしいが、ソースコードも雲行きが怪しい。
なんか毎回Windowsで動かすのに苦労してる気がする・・・
でもWindowsの方で環境構築してビルドしても動く保証が無いし何より面倒くさい。
なんか毎回Windowsで動かすのに苦労してる気がする・・・
でもWindowsの方で環境構築してビルドしても動く保証が無いし何より面倒くさい。
Windowsで動かない
さて。今回は何で詰まってるかと言えば「デバッグ版では動くのに最適化をかけると動かない」
よくあるっちゃあ、あるのかもしれないけど。
よくあるっちゃあ、あるのかもしれないけど。
どうやらOpenGL APIを呼んでる箇所でコケている模様。
正確にはvirtualなメンバ関数からOpenGLの関数を呼んだ後、その関数を抜ける時にSEGV(nullptrにwriteアクセス)が起きている。
アラインメントずれの悪夢再来か・・?と、一瞬思ったが今回はwineでも実機でもvirtualboxでも同じ所で落ちる。
という事は、恐らくAMD CatalystとVirtualBoxのドライバの差異に起因する問題ではない筈
正確にはvirtualなメンバ関数からOpenGLの関数を呼んだ後、その関数を抜ける時にSEGV(nullptrにwriteアクセス)が起きている。
アラインメントずれの悪夢再来か・・?と、一瞬思ったが今回はwineでも実機でもvirtualboxでも同じ所で落ちる。
という事は、恐らくAMD CatalystとVirtualBoxのドライバの差異に起因する問題ではない筈
ちなみにwglGetProcAddress()でアドレスを取得した関数をstaticメンバかグローバルに置いて呼ぶと大丈夫のようだ。
最適化オプションを幾つか試した結果-O1 と -fno-ommit-framepointers ならば動くが-O2以上になると駄目。
何故だかフレームポインタ省略を無効にすると動くのは何なんだろう。
最適化オプションを幾つか試した結果-O1 と -fno-ommit-framepointers ならば動くが-O2以上になると駄目。
何故だかフレームポインタ省略を無効にすると動くのは何なんだろう。
まぁ、そんな感じで悪戦苦闘中
(2014/02/02)
Ubuntu版の公開
とりあえずUbuntu版を公開。依存パッケージとか開発機でしか確認してないからこれでいいのかよく分からんが・・
SDL2とSDL2_imageはまだパッケージが出回ってないようなのでこちらで用意した。
何時ものアップローダからどうぞ。
SDL2とSDL2_imageはまだパッケージが出回ってないようなのでこちらで用意した。
何時ものアップローダからどうぞ。
まあ・・・ライティング無しだとあまりにもアレだから並行光源ライティングくらいはしておいた。
機能としては単にポリゴンを表示してOpenALによるサウンド再生、ウィンドウ最小化時のOpenGLリソース解放と復帰のテストだけ。
あとFreeType2によるフォント描画。
スクリーンショット見れば事足りるか。
あとFreeType2によるフォント描画。
スクリーンショット見れば事足りるか。
っと思ったら操作方法の記述を忘れているではないか。
- WASDでカメラ移動
- マウス左ホールドで方向転換
- QとEでサウンドの再生と停止
- Escでアプリケーション終了
である。面倒くさいから次のバージョンで直す。
Windows版
試す人がいるかどうかは別として、躓く所が無ければ今日中にもアップできる筈。
(2014/02/01)
プログラミング以外の事で色々あって
だいぶ遅れてしまってるが立方体が回って音楽を流すだけのデモをアップロードをしたく作業中。
だいぶ遅れてしまってるが立方体が回って音楽を流すだけのデモをアップロードをしたく作業中。
パッケージング
とりあえずデモプログラム的には完成しているんだけど
例のごとく忘れているのもあってLinux(Ubuntu)版のパッケージングにちょっぴり躓いたり。
まずはlddによる依存ライブラリのリストアップから始まり、OSに標準で入ってると思われるものについては除外。
残りは既に公式パッケージが存在していればそれを使い、そうでない物(例えばSDL2)は自前でdebパッケージを用意という形かね。
libjpegはバージョン8が広く出回ってるみたいだけど自分のとこでは9を使っていたので改めて8を使う様にしてビルドとか。
他にもlibfreetype6, libvorbisfile3, libogg0, libvorbis0a, libopenal1, libpng12-0, libjpeg8
とかあったがこれらはパッケージが既に存在していたので助かった。
例のごとく忘れているのもあってLinux(Ubuntu)版のパッケージングにちょっぴり躓いたり。
まずはlddによる依存ライブラリのリストアップから始まり、OSに標準で入ってると思われるものについては除外。
残りは既に公式パッケージが存在していればそれを使い、そうでない物(例えばSDL2)は自前でdebパッケージを用意という形かね。
libjpegはバージョン8が広く出回ってるみたいだけど自分のとこでは9を使っていたので改めて8を使う様にしてビルドとか。
他にもlibfreetype6, libvorbisfile3, libogg0, libvorbis0a, libopenal1, libpng12-0, libjpeg8
とかあったがこれらはパッケージが既に存在していたので助かった。
ポインタ比較?
clang++でリリースビルド(-O2)すると以下のようなルーチンでwhileがいつまで経ってもfalseにならずSEGVで落ちる、という現象に遭遇。
const char* ptr = &buffer[0], ptr_end = ptr + size;
while(ptr != ptr_end) { char c=*ptr; ... ++ptr; }
const char* ptr = &buffer[0], ptr_end = ptr + size;
while(ptr != ptr_end) { char c=*ptr; ... ++ptr; }
std::coutをかましポインタの値と比較結果を出力して逐一チェックを試みるも
数値は同じなのに!=比較結果がtrueという・・・。
一旦uintptr_tなどに変換してから比較も駄目だった。
数値は同じなのに!=比較結果がtrueという・・・。
一旦uintptr_tなどに変換してから比較も駄目だった。
原因がよくわからんけど一先ず whileの中を ptr < ptr_end とする事で解決。