FPSを作ってみる@wiki
06)
最終更新:
slice
-
view
(2012/06/27)
いやいや。
........
いやいやいやいやいや。
前回から2週間の間に色々やってた気がするけど忘れてしまった。
そうならない為に書き留めるんじゃなかったっけな。全く。
何処から話を始めたもんかねぇ・・
前回から2週間の間に色々やってた気がするけど忘れてしまった。
そうならない為に書き留めるんじゃなかったっけな。全く。
何処から話を始めたもんかねぇ・・
基礎固めその6: ファイル読み込みの抽象化
エンジンとか名乗る割にAPIを直接叩いてファイルを読み込むのは格好悪いので
予め「読み込み専用パス」「書き込み専用パス」をファイルマネージャにセットしておき
例えば読み込みパスを "C:/", "./resource" としてファイル名 "background.bmp" としたなら
まずC:/background.bmpが無いか探しに行きあったらそれを読み、無ければ./resource/background.bmpを探す
どちらにも見つからなければ読み込み失敗の旨を通知といった具合。
ただまあWINAPIのファイルハンドルをそのまんま渡すのもやはりシャクなんでそこもクラスでカプセル化。
予め「読み込み専用パス」「書き込み専用パス」をファイルマネージャにセットしておき
例えば読み込みパスを "C:/", "./resource" としてファイル名 "background.bmp" としたなら
まずC:/background.bmpが無いか探しに行きあったらそれを読み、無ければ./resource/background.bmpを探す
どちらにも見つからなければ読み込み失敗の旨を通知といった具合。
ただまあWINAPIのファイルハンドルをそのまんま渡すのもやはりシャクなんでそこもクラスでカプセル化。
読み書きするのはHDD上のファイルだけとも限らず、ファイルパスの最初を@にすればメモリ上のファイルを表すとか
あとハフマン符号による圧縮ファイル(複数ファイルを纏めた物)にも読み込みだけ対応してたり。
ハフマンに関しちゃちょっとテストが不十分だが・・まぁリリース時に悩めばよし。
あとハフマン符号による圧縮ファイル(複数ファイルを纏めた物)にも読み込みだけ対応してたり。
ハフマンに関しちゃちょっとテストが不十分だが・・まぁリリース時に悩めばよし。
というわけで行く行くはリリース時のリソースはパックしたファイルに入れたままでMODなんか作る時は
書き換えたファイルだけ別途フォルダに入れてあげればそちらを優先して読むなんて事も可。
パックファイルの拡張子末尾を連番にすれば古い方から新しい方へ上書きして読むのでパッチもファイル1つで楽々だ。
っていうかそれがしたかっただけとも・・
書き換えたファイルだけ別途フォルダに入れてあげればそちらを優先して読むなんて事も可。
パックファイルの拡張子末尾を連番にすれば古い方から新しい方へ上書きして読むのでパッチもファイル1つで楽々だ。
っていうかそれがしたかっただけとも・・
なんなら重複するファイルは省いて新たに1つパックファイルを生成する事だって・・・やってたような、頓挫したような。なんせ前に書いたソースだし。
基礎固めその7: Luaの組み込み
賢明な人はtoLuaとか使ったほうがいいかもね。
自分は馬鹿だから自分で書いた。とはいえ半分以上は前のソースをコピペ。
リソースハンドルの受け渡しやLuaの変数をC++上で楽に扱えるようにカプセル化など。関数呼び出しの変数渡し部分はテンプレートの嵐。
(引数の個数分だけパターン書かなきゃいけない)
自分は馬鹿だから自分で書いた。とはいえ半分以上は前のソースをコピペ。
リソースハンドルの受け渡しやLuaの変数をC++上で楽に扱えるようにカプセル化など。関数呼び出しの変数渡し部分はテンプレートの嵐。
(引数の個数分だけパターン書かなきゃいけない)
C++11の可変引数テンプレートあればもっとスマートに書けそうなんだがねぇ。
でもVisualC++に実装されるのは2012だろうし、その為だけにwin7とか買う予定ないし。
もうひとつ言えばgccは普通に対応してるからそっちで欲を満たしている。
でもVisualC++に実装されるのは2012だろうし、その為だけにwin7とか買う予定ないし。
もうひとつ言えばgccは普通に対応してるからそっちで欲を満たしている。
基礎固めその8: リソースマネージャ各種 (テクスチャ、エフェクト(シェーダ)、ゲームOBJ)
テクスチャとエフェクトは基本的に前のソースから移植しただけなんでなんとも。
アサートとエラー処理を若干強化したくらいかな?
アサートとエラー処理を若干強化したくらいかな?
ゲームOBJというのはゲーム中に登場するオブジェクトのベースである。ってだけじゃ訳がわからんと思うので少し説明すると
他のOBJへメッセージ(命令や変数)の受け渡しやシーンへの登録、
あるOBJの状態が変化した時に通知を受け取ったり
C++のクラスに引数として渡せば条件が揃った時にC++からLuaのOBJへメッセージを送ったりもできるし
OBJの破壊時に関連OBJ(描画用のOBJや当たり判定用のOBJなど)を自動的に破棄したりなど
色々やってくれるクラス。
内部にステート(状態)を持ち、ステートXの時にAというメッセージを受けたら何も起こらないがBだと破壊され
ステートYの時にはその逆。なんて事も。
他のOBJへメッセージ(命令や変数)の受け渡しやシーンへの登録、
あるOBJの状態が変化した時に通知を受け取ったり
C++のクラスに引数として渡せば条件が揃った時にC++からLuaのOBJへメッセージを送ったりもできるし
OBJの破壊時に関連OBJ(描画用のOBJや当たり判定用のOBJなど)を自動的に破棄したりなど
色々やってくれるクラス。
内部にステート(状態)を持ち、ステートXの時にAというメッセージを受けたら何も起こらないがBだと破壊され
ステートYの時にはその逆。なんて事も。
今取り組んでるのは
前までのソースはシーンや当たり判定、描画の管理やアップデート処理の仕組みがゴタゴタだったのでその辺の整理。
前までのソースはシーンや当たり判定、描画の管理やアップデート処理の仕組みがゴタゴタだったのでその辺の整理。
毎フレームのアップデート処理は伝統的なタスクシステムを使えば軽そうだが優先度でソートするしかできない。
シンプルなゲームならそれでいいんだろうけど
例えばFPSなんかでプレイヤーの居る部屋とそこから見える部屋に居る敵はちゃんと処理を行うが
壁の向こうで見えない敵は手抜きをする、なんて事はマップの構造を考慮しないとちょっと難しいかなと。
描画も然り。
シンプルなゲームならそれでいいんだろうけど
例えばFPSなんかでプレイヤーの居る部屋とそこから見える部屋に居る敵はちゃんと処理を行うが
壁の向こうで見えない敵は手抜きをする、なんて事はマップの構造を考慮しないとちょっと難しいかなと。
描画も然り。
これはプログラムとあまり関係ないのだが
バージョン管理システムをSVNからGitにほぼ移行した。
別にSVNに不満という訳ではないがGitHubの件でちょっと勉強してみたら結構いいじゃないという感じで。
バージョン管理システムをSVNからGitにほぼ移行した。
別にSVNに不満という訳ではないがGitHubの件でちょっと勉強してみたら結構いいじゃないという感じで。
(2012/06/14)
物凄い手抜き.
いくつか実装したけど記事書くのを面倒くさがって空いてしまった.
いくつか実装したけど記事書くのを面倒くさがって空いてしまった.
基礎固めその3: 名前付きリソースマネージャ
どんな物かは前回説明してしまったんで,特に・・・
基礎固めその4: 複数変数を返す構造体
普通の人は無難にboost::tuple使う場面なのだが.
中どうなってんだろう?小間物くらい自分でも書けないか??と思ったのが運の尽き.
右辺値参照で返した時に内部に値を格納しておいて関数が終了した後もクラスが生存しているように等,
自分なりに使いやすくしてみたとか.
ま,言い訳にしかならんか.
中どうなってんだろう?小間物くらい自分でも書けないか??と思ったのが運の尽き.
右辺値参照で返した時に内部に値を格納しておいて関数が終了した後もクラスが生存しているように等,
自分なりに使いやすくしてみたとか.
ま,言い訳にしかならんか.
基礎固めその5: JSON読み書き
これも普通の人はライブラリなど使うとは思うが,前に作った物があったんで流用.
メモリ確保の所を先日作ったTLSFアロケータに変えてエラー処理はちゃんと例外を投げるなど手直し.
メモリ確保の所を先日作ったTLSFアロケータに変えてエラー処理はちゃんと例外を投げるなど手直し.
次はスクリプトの組み込みかねぇ・・
(2012/06/09)
基礎固めその2: ハンドルベースのリソースマネージャ(シングルスレッド版)
予定通りリソースマネージャをサクッと実装。
前のソースを見ながらやろうかとも思ったがあちらは中途半端にマルチスレッドを意識しており処理効率が微妙だったので
スレッド同期機構などバッサリ切り落としつつ、書きなおした。リソースマネージャ書いたの3回目くらいか。
前のソースを見ながらやろうかとも思ったがあちらは中途半端にマルチスレッドを意識しており処理効率が微妙だったので
スレッド同期機構などバッサリ切り落としつつ、書きなおした。リソースマネージャ書いたの3回目くらいか。
結局の所リソースを複数スレッド間でどうこうなんて個人プロジェクトではまずやらないだろう。
そんなに重い処理をさせる前に最適化を考えようぜと。
ついでに言えばLuaの仮想実行マシンもマルチスレッドには対応してないし。
大きいファイルの読み込み中にnow loading画面など別の処理をさせたかったらファイル読み込み用に1つ専用スレッドを作ればいい話なのだ。
そんなに重い処理をさせる前に最適化を考えようぜと。
ついでに言えばLuaの仮想実行マシンもマルチスレッドには対応してないし。
大きいファイルの読み込み中にnow loading画面など別の処理をさせたかったらファイル読み込み用に1つ専用スレッドを作ればいい話なのだ。
ハンドルベースのリソースマネージャとは簡単に説明すると
リソースに一意のハンドル値を割り振り、ユーザーはそれをマネージャに渡してアクセス・管理する方式である。
アクセスにワンクッション入るので微量のオーバーヘッドは生ずるが生のポインタでない分、
リソースが使われていない間ならマネージャが好きにメモリ位置を変更可能(デフラグとか)だし
内部に参照カウンタを持っているのでC++特有の「誰がメモリを破棄するのか」問題に対処できる。
加えてデバッグ用にハンドル値へマジックナンバーを組み込むなどすれば「一度解放されたはずのリソースに再度アクセスした」場合
アサートを発して早期にバグを発見できる利点も。
リソースに一意のハンドル値を割り振り、ユーザーはそれをマネージャに渡してアクセス・管理する方式である。
アクセスにワンクッション入るので微量のオーバーヘッドは生ずるが生のポインタでない分、
リソースが使われていない間ならマネージャが好きにメモリ位置を変更可能(デフラグとか)だし
内部に参照カウンタを持っているのでC++特有の「誰がメモリを破棄するのか」問題に対処できる。
加えてデバッグ用にハンドル値へマジックナンバーを組み込むなどすれば「一度解放されたはずのリソースに再度アクセスした」場合
アサートを発して早期にバグを発見できる利点も。
次は名前付きリソースマネージャ。これはモデルやサウンドファイルを複数オブジェクト間で共有する時に便利で
例えば名前としてファイルパスをセットすれば初回は普通にファイルから読み込み
次回以降同じファイルパスが指定された際は前回読み込んだ結果を渡す。
勿論参照カウンタ付きなので誰も使ってなければ自動で破棄される。
例えば名前としてファイルパスをセットすれば初回は普通にファイルから読み込み
次回以降同じファイルパスが指定された際は前回読み込んだ結果を渡す。
勿論参照カウンタ付きなので誰も使ってなければ自動で破棄される。
(2012/06/08)
基礎固めその1: メモリアロケータ
ゲームの基礎はリソース管理。リソース管理の基礎はメモリ割り当てから。
という事でメモリアロケータを実装していた。
既にあるnewで十分だって?いやいや。
ひょっとしたら数msかかるかも知れない物をゲーム実行中気軽に呼べない。
という事でメモリアロケータを実装していた。
既にあるnewで十分だって?いやいや。
ひょっとしたら数msかかるかも知れない物をゲーム実行中気軽に呼べない。
とはいえ勿論自分でアルゴリズムを1から考えるのは手間すぎるので既存のを使用。
今回実装したのはTLSF (two level segregated fit)アロケータといって詳細はググるなりして欲しいのだが
要は最初から要求されたサイズぎちぎち1バイトも無駄にするなとやるんではなく
ある程度大雑把なサイズ区分でもって割り当てる。
この「大雑把な」というのが2のべき乗だったりして
という事はビットテーブルやビット演算を使ってフリーブロックやブロック分割を高速に出来るねという話。
今回実装したのはTLSF (two level segregated fit)アロケータといって詳細はググるなりして欲しいのだが
要は最初から要求されたサイズぎちぎち1バイトも無駄にするなとやるんではなく
ある程度大雑把なサイズ区分でもって割り当てる。
この「大雑把な」というのが2のべき乗だったりして
という事はビットテーブルやビット演算を使ってフリーブロックやブロック分割を高速に出来るねという話。
考えてみりゃメモリの確保と開放に制限を設けなければどうやったって断片化する訳なので最初からそこは諦め
せめて一定以上は断片化しないようにする方向性に持ってくのは極自然ではある。
せめて一定以上は断片化しないようにする方向性に持ってくのは極自然ではある。
で、このアロケータ。
空きブロックをループ探索しないので確保がほぼ定数時間で終わり
解放も空き隣接ブロックを結合するか否か位なので処理時間にそれ程バラつきはないと予想される。
正にゲーム向きである。
次はこれを組み込んだリソースハンドルマネージャに取り掛かろうと思う。
空きブロックをループ探索しないので確保がほぼ定数時間で終わり
解放も空き隣接ブロックを結合するか否か位なので処理時間にそれ程バラつきはないと予想される。
正にゲーム向きである。
次はこれを組み込んだリソースハンドルマネージャに取り掛かろうと思う。
これで終わりなのだが、ふと思いついた自前アロケータを用意する利点。
最初に大きなメモリの塊を渡し以後はそれをやりくりする性格上
ポインタの範囲を見れば自前アロケータで確保した物か、そうでないかが一発でわかる。まぁどうでもいいか・・
最初に大きなメモリの塊を渡し以後はそれをやりくりする性格上
ポインタの範囲を見れば自前アロケータで確保した物か、そうでないかが一発でわかる。まぁどうでもいいか・・
#追記
真面目に考えれば「メモリ割り当てコストが予測可能」なとこかな < 利点
(2012/06/07)
次の手
なんだかんだ言ってQtフレームワーク弄り(その練習としてツイッタークライアント作成)は既に日課である.
あれからQt Linguistというのを使って英語・日本語両対応にしてみたり,
RTやFavの表示を背景の色変えじゃ安っぽいからとアイコン表示にしたりした.
配信中に外人さんから「オープンソースしないの?」と言われ,つい「It will be.」とか答えてしまったんで
一通り動く段階まで来たらGithubで公開すると思う.
基礎から全部自前のゲームと違ってフレームワークの上で組んでるから割と進行がリニア.
完璧主義なきらいがある自分だけどこれは今月中に公開まで行けそうかと踏んでいる.
あれからQt Linguistというのを使って英語・日本語両対応にしてみたり,
RTやFavの表示を背景の色変えじゃ安っぽいからとアイコン表示にしたりした.
配信中に外人さんから「オープンソースしないの?」と言われ,つい「It will be.」とか答えてしまったんで
一通り動く段階まで来たらGithubで公開すると思う.
基礎から全部自前のゲームと違ってフレームワークの上で組んでるから割と進行がリニア.
完璧主義なきらいがある自分だけどこれは今月中に公開まで行けそうかと踏んでいる.
前にも書いたけどそもそも何でQtフレームワークやってんのかと言えば「ゲームのエディタ周りを固めたい」為.
WIN32APIを直でとか効率悪くてやってられんし(WPFには興味ないし)
ついでにクロスプラットフォームなら色々な場所で動かせて嬉しいよね.
WIN32APIを直でとか効率悪くてやってられんし(WPFには興味ないし)
ついでにクロスプラットフォームなら色々な場所で動かせて嬉しいよね.
で.メインである(筈の)ゲーム.
先週でモデリングは一段落した訳だが相変わらずというか,次の一歩を決めかねている.
現在ぼんやりと浮かんでる事を列挙すると・・・
先週でモデリングは一段落した訳だが相変わらずというか,次の一歩を決めかねている.
現在ぼんやりと浮かんでる事を列挙すると・・・
- 無機物だけでなく生物系もモデリングしてみたい
- 物理エンジンを導入
- ゲームの基礎を書き直し
- 作りかけのハイトフィールドを仕上げる
- javascript/PHP/SQLを使ったアンケートフォームの作りかけにケリをつける
こんなとこだろうか.
物理エンジンは過去に2回ほど自前でやろうとして玉砕しているのでリベンジしたい所だがまた軽く1ヶ月は吹っ飛ぶから当分はパス.
そろそろ動くゲーム出さんとマズい.外面的にも,モチベーション的にも.
物理エンジンは過去に2回ほど自前でやろうとして玉砕しているのでリベンジしたい所だがまた軽く1ヶ月は吹っ飛ぶから当分はパス.
そろそろ動くゲーム出さんとマズい.外面的にも,モチベーション的にも.
「作りかけのハイトフィールド」を気合入れて仕上げた後に
「ゲームの基礎を書き直し」が一番堅いかな・・
ちなみに自前のゲームエンジンを作るのはもう止めにする.理由は後ほど.
「ゲームの基礎を書き直し」が一番堅いかな・・
ちなみに自前のゲームエンジンを作るのはもう止めにする.理由は後ほど.
(2012/06/02)
モデリング
先週はモデリング強化週間と称してひたすらモデリングソフトを触る企画をしていたが
出来た物はトップの画像くらいっていうのがアレ。
(本当はもう1つくらい出せる予定だった)
他にはモデリングの際の手際が少しだけ良くなった程度か。まぁ一週間だしね。
あとちょっとだけモデリングをしたらプログラムに戻る。
出来た物はトップの画像くらいっていうのがアレ。
(本当はもう1つくらい出せる予定だった)
他にはモデリングの際の手際が少しだけ良くなった程度か。まぁ一週間だしね。
あとちょっとだけモデリングをしたらプログラムに戻る。
結構前からだがatwikiが公式にtwitterパーツをサポートするようになってたんで
メニューバーに貼りつけてみた。
けどカスタマイズがCSSの範囲でしか出来なくて
今の状態だと本来のメニューより自己主張が強くてあまり好きじゃない。ページ移動する度に再読み込みというのも微妙だ。
そのうち移動させようか・・
メニューバーに貼りつけてみた。
けどカスタマイズがCSSの範囲でしか出来なくて
今の状態だと本来のメニューより自己主張が強くてあまり好きじゃない。ページ移動する度に再読み込みというのも微妙だ。
そのうち移動させようか・・
ちなみに現在のTwilveQt。
発言もできるしRTやFavも動作する。緑で表示されているのは他人の公式ReTweet
OAuthも勿論対応。
OAuthも勿論対応。
添付ファイル