ボタン入力機能を実装した
こいつ…動くぞ!
こんな風に、ユーザのボタン入力に応じてリアクションできるようになったぞ。
グラフィックの表示、ボタン入力ときて、かなりゲームの土台が出来上がってきたと言える。
使用するボタンは「上下左右+3ボタン」の計7ボタンで足りる想定。
今回はハマりポイントなかったなあ。わりとすんなりと動いた。
インターフェースや階層の分離などの設計方針で悩んだくらいか?
ただ、ちょっと困ったことが
Windows でキーを押下した時に発行される WM_KEYDOWN
メッセージなのだが、入力機器や環境設定によっては、ボタンを離した後もちょっと持続しちゃう らしいのよね。
ゲームでこのラグはけっこう致命的である。
キーボード入力のオートリピートとかが絡んでるっぽいんだが、ちょっとプログラム側では如何ともしがたい感じ。
ゲームパッド等の専用ガジェットを使ってもらうとか、環境設定をいじってもらうとか、ユーザ側に対応してもらうしかないかもしれん…。
ぐぬぬ…
グラフィックの表示に成功した
こんな感じ
デモ用のスプライトを画面内に撒き散らしてみた
やっぱり絵が表示されると気分もあがるなあ。
あとドット絵っていいよねー
じつは、ざっくりしたグラフィックの表示自体は6月3日あたりで達成していたんだが、やっぱり公開するならちゃんと体裁を整えたい!…ということで色々やっていたら、なんやかんやてこずって時間がかかった。
だって、動きもしないただの市松模様を見せられてもおもんないでしょ…?
ハマりポインツ
DirectX11 定数バッファのパッキング規則
グラフィックの描画には DirectX11 を使っている。
ゲームエンジンとかは使わず、生の API を直接叩いて実装していくスタイル。
で、何にハマったかというと、DirectX11 の定数バッファの仕様だ。
頂点バッファにパラメータを送る際に、「四辺形だから4頂点あるし」とか思って配列を使ったんだが、このせいでドはまりしてしまった。
DirectX11 の定数バッファでは、16bytes を境界としてアラインメントの再配置が起こる。
これについてはネット上に情報がいっぱいあったし、筆者も警戒してコーディングしていたんだが…
問題は、配列の場合は このルールが1要素ずつ適用される ということ。
だから、パラメータとしてこのように定義していたとしても…
// D言語 struct VSNormalArg { float[2][4] vertexes; } // HLSL cbuffer VSNormalParams : register(b0) { float2 vertexes[4]; }
HLSL 側は(イメージとしては)パラメータをこのように解釈する。
// えぇ… cbuffer VSNormalParams : register(b0) { // 16bytes float2 vertex0; float2 dummy0; // 16bytes float2 vertex1; float2 dummy1; // 16bytes float2 vertex2; float2 dummy2; float2 vertex3; }
渡したつもりのデータは、まるっきりズレた領域に書き込まれるので、レンダリングがさっぱりうまくいかないのだ。
こんなん分かるか。
あたまおかしくなるかと思ったぞ。
解決方法としては至極単純で、16bytes に調整されてしまうなら最初っから1頂点を 16bytes として渡せばいい。
こんな風にね。
// D言語 struct VSNormalArg { float[4][4] vertexes; // float * 4 [2] と [3] は使わない } // HLSL cbuffer VSNormalParams : register(b0) { float4 vertexes[4]; // float4 'z' と 'w' は使わない }
使わない末尾 8bytes がもったいない気もするが、まあいいや。配列で処理できたほうが断然便利だし。
シンプルイズベスト。
いやはや、しかし、知ってる人には当たり前の話なのかもしれないが、大変だったぞ。
DUB の stringImportPaths
まあこれはしょうもない話かもしれない…
パスを複数指定していた場合、各パスに同じ名前のファイルがあると、一番先頭にあるパスのものを参照しちゃうっぽい。
// ディレクトリ構成 aaa\bbb\ccc\name.bin xxx\yyy\zzz\name.bin
// dub.json "stringImportPaths": [ "aaa/bbb/ccc", "xxx/yyy/zzz" ]
// Dソースコード import("name.bin"); // <- aaa\bbb\ccc のファイルが参照される。
これ、コンパイルエラーにならんのか…。まあならんよなー
でもさ、import
でシンボル名が被ったときは「どっちか分かんねえ!」ってコンパイルエラーになるやん…(´・ω・`)
この問題にも結構時間を食ってしまった。
以上
まあ色々と壁にはぶち当たったが、グラフィックを無事表示できて満足。
引き続き頑張っていきましょう。
うわああああああ!!
実装にあたっての参考文献
- https://ku6.jp/report/9.html
- https://qiita.com/mono_shoo/items/e4a45b7ed12114c04b51
- https://qiita.com/ousttrue/items/a4291fc996a063841bd7
本当に助かりました…。皆様ありがとうございます。
ウインドウを表示したぞ
本日の進捗
Windowsのフォームを表示することに成功した。
こんな感じ。やはり、目に見える進捗というのはいいものだ。
あっ、そこ! 殺風景で地味だとか言わない!
確かに今は ただの灰色の板 だが、これは重要な第一歩なのだ。
それに、見た目では伝わらないものの、内部的にはすでに 60FPSで駆動するゲームループ が実装済みなのだ。
今後、描画やメイン処理を追加していけばもっとゲームらしくなるぞ。
ハマりポイントとか
その1:64bit版バイナリ
D言語で64bit版バイナリを吐くときに、user32.lib
などのライブラリとのリンクでエラーが出たあたりで少々てこずった。例の LNK1104
ってやつだ。
分かっちゃいたが、D言語は情報少ないからなあ。日本語の情報ともなるとなおさら…
自分の場合、最終的には dub.json
に libs
要素を追加して必要なライブラリ名を書くだけで解決した。
こういうのである。
... ほかの設定色々 ... "libs": [ "ole32", "kernel32", "user32", "comctl32", "comdlg32" ] ... ほかの設定色々 ...
わりと試行錯誤したぞ。LIB
環境変数を作って Windows Kit
のライブラリ群のパス追加するのかなあとか、sc.ini
の設定のせいかなあとか、正直いろいろ悩んだ。
どの環境変数使ってるんだこれ? また詳しく検証しておこう。
その2:dub.selections.json
???
D言語のパッケージマネージャとして、筆者はもちろん dub
を使っている。
ただ、dub build
とかでコンパイルすると dub.selections.json
とかいうファイルが dub.json
と同階層に出力されるのだ。なにこれ?
消してもコンパイルするたびに出るので、設定ファイルかなんかだろうと思い、.gitignore
にぶち込んじゃったけど、ええんかいな…?
その3:「これは!」というIDEがない
まあ、これはあらかじめ知ってた。ノーダメージ。
潔くあきらめて、シンタックスハイライトだけをする VSCode の拡張機能を自作して適用。
キーワードに色がつくだけで、わたしは満足です。
そもそも、IDE やデバッガの複雑な機能がないと、何やってるか追えないコード書いちゃうのもどうなのって話ですし(暴論)
ちなみに、キーワードの組み合わせに応じて色がちゃんと変わるのが個人的お気に入りポインツ。
疲れたので以上
まだ書きたいことはあるけど、今日はこんなところか。
1ページ目
このブログは何?
ここは、おもに ゲームの個人制作 や、その過程で得た プログラミングに関する情報 を記録していくブログです。
筆者のモチベーション維持の目的も兼ねています。
筆者は何者?
「えーさん ますめ」と申します。ゲームの個人制作がしたい人です。
昔はよくチラシの裏や方眼紙にゲームを書いたもんだ(懐旧)
プログラミングの経験はわりとそれなりに。Java とか C# とか。バッチファイルとか。
どんなゲーム作るの?
ジャンルは 横スクロールアクションRPG の予定です。
8bit感 のある ドット絵 ゲームを目指します。筆者がそういうビジュアルのゲーム好きなので。
配布形態はとりあえずデスクトップアプリということにします。
ブログの更新頻度は?
記事を書くタイミングは特に決めていませんが、何か進捗があって、なおかつ気力があれば書きます。
絵になるものができたら、その都度アップしたいなあ。
プログラミング言語とか決めてんの?
何を隠そうわたくし、c++ 挫折した勢なのです…。
そこで、文法が似通っていて書きやすいと もっぱらの評判の D言語 を用いて開発します。
D言語を選定した理由は以下のとおり。
- 学習曲線が緩やか(筆者が経験してきた言語を鑑みて)
- 便利そうな言語機能が多い
- ネイティブバイナリを吐く
- 実行速度が速そう
- コンパイル速度も速そう
エディタは Visual Studio Code を使用。
トレンディですね。
いつまでに完成させるの?
〆切は 2021/12/31 をめどに。
本記事の投稿日付から計算すると、期間は半年ちょいですね。
ストーリーや世界観はあらかた考えてあるので、プログラミングをどんどん進めよう。
個人制作ゲーム界隈は魔境ですよ?
ええ。失踪しないよう頑張りましょう。