2004/9
ここは技術メモにして、それ以外はmixi日記に書いていこう…と思ってたんだけど、
最近あまりに技術ネタが無いんで取りやめ。
とりあえず、最近やった/やってるゲームとか。
TC。TacticalCommanders。
1日2~3時間ペースでやり続けてそれなりに強くなってきたけど、
時間取られすぎで危機感を感じてきたのでアンインストール。
またやるかもしれないけど、しばらくは封印。
通常戦闘の時はベータの頃に戻ったような感覚で楽しかった。
タイタン所属の鳳来ってキャラが俺。
人狼BBS。
駆け引きはおろか、人と話すこと自体苦手な方なので、ログ読んで楽しむだけにしておこう。
…と思ってたんだけど、あまりにも面白そうなのでつい参加してしまった。
発言不足で疑われて吊られるのだけは避けたいところ…。
Ever17。
*激しくネタバレしてるけど、物語の核心部分には触れていないつもり。
YU-NO並に面白いらしい、とどこぞで聞いてやってみたんだけど、
設定に無理があるように思える(少年視点の舞台設定だとか)のと、
最後で過去の世界に干渉して歴史を改竄しているのの2点が納得いかなくて、
俺の評価はYU-NOへのそれと比べるととても低いものに留まった。
まあそれでも、ココ編で少年が鏡で自分の姿を見る場面とか、その後のこれまでの謎が次々と解明されていくところは、
次の一文を読むのが楽しみで楽しみで仕方が無かったし、
ここ最近プレイしたシナリオ重視のゲームの中では最高クラスではあったんだけど。
やはり一番納得いかないのは歴史を変えようとする場面。
BWは自分を発現させる歴史を築くために過去に干渉して非常にややこしい要求をしてるけど、
結局BWが発現する最初の歴史はどこから来たのか、というパラドックスは解決されていない。
あくまでBWの能力は他の世界を「見る」だけという設定だったら説得力が増していたように思う。
YU-NOでは時間と歴史の取り扱いについて明瞭で説得力のある回答を出していた(「時間は可逆、歴史は不可逆」というやつ)
んだけど、Ever17はどうもその辺が不明瞭だ。
時間は不可逆(確かゲーム中優が言ってたはず)で、
歴史は線形(並列世界は存在しない、もしくは完全に見えない)かつ可逆、という設定なんだろうか?
というか、プレイ動機が「YU-NO並に面白いらしいと聞いたから」ってせいで、
必要以上に穿った見方をしているかもしれない。
YU-NO同様2度目以降のプレイで見えてくるものもありそうなので、
時間を置いてもう一度やってみる予定。
つぐみさん萌。
それと上のコメント欄がこのサイトにしては過去に例を見ないくらい盛り上がっております。
書き込んでくれている方々に感謝を。
わけあってtga画像の代わりにpng画像を使い始めた。
png画像を扱うには
libpngと
zlibが必要なわけだけど、
これまた日本語ドキュメントが見当たらないので、サンプルコードと延々睨めっこしつつ使い方を模索。
幅、高さ、RGBAピクセルデータさえ引っ張ってこれれば十分なので、適当に簡略化したラッパーを書く。
こんな感じ。テストコードとかVC用ライブラリとかも含めてみた
もの。
スタティックリンクするとバイナリのサイズが150KB程増えるけど、
画像の容量はtgaの半分以下になったのでまあよし。
(ダイナミックリンクする場合、dllの容量がlibpngとzlibで400KBくらいに及ぶ)
色々慌しくて時間が取れないので停滞中。
スローペースながらも今やってることはユニットのバリエーション増やし。
いつぞや書いたようにキャラクタのコード書きは地道で面倒な作業なので、
今からバリエーション揃えておいて、後はできるだけデータ差し替えと能力値変更で済むようにしようという魂胆。
というわけで、特殊能力を持った極端なユニットが揃いつつある。
範囲攻撃、範囲回復、防御力無視攻撃、目標地点へ瞬時に移動、
指定したユニットを自分の付近に瞬時に移動、
敵ユニットを転向させて味方ユニットにする、
一定時間敵の自動攻撃のターゲットにならなくなる、
一定時間一切ダメージを受けなくなる、などなど。
効果が大きいものに関してはMPパラメータを設けてMPを消費して発動とかそんな感じで。
というか、能力のほとんどがStarCraftやTCからのパクリだ。
何か独自の面白そうな特殊能力を思いつかんもんか。
基本的にAoMを真似て作ってるけど、
ゲームとしての方向性はもしかしたらStarCraft系の方が俺の望むものに近いかもしれない。
近いうちにWarCraft3やって研究してみようか。
コメント欄にある通り、
テスト版置き場を設置。
この雑記に実装報告書くときはその成果物が置かれるはず。
Rome: Total War、デモ版が公開されたのでやってみた。
集団戦が主体で数千体のユニットが入り乱れるRTS。
集団戦を売りにしてるだけあって、大勢のユニットがぶつかり合う様子は圧巻。
映画の戦闘シーンを見ているような気分になる。
象が突進で人をボーリングのピンの如く跳ね飛ばしていくのに爆笑。
不満なのが、ユニットが指示を無視して後退しだすことがあること。
条件は疲れパラメータとか指揮官の有無とか戦況とか色々絡んでそうだけど、いまいちはっきりしない。
象が逃げ出したりなんかしたら味方を跳ね飛ばしまくって甚大な損害を被るというマヌケな事態に。
それとこれはユニットをグループにまとめる系全般に言える事だと思うけど、戦闘結果が予測しにくい。
経過がよくわからないまま勝ったり負けたりして釈然としない。
どちらも戦闘を数こなせ対処可能になるんだろうけど、これらの要素のせいでとっつきにくくなってるように思う。
説明が英語でろくに頭に入ってないので、基本的な操作や知識を見逃しているだけの可能性もありそうだけど…。
しかし何故
これがリアルタイムで動きますか。
どういう内部処理やってるのか予想がつかない。すごい。
(Pentium4 3G+GeForce4Ti4600な環境で、
ちょっと複雑なシーンになると描画がもたつくけどプレイにはそれほど差し支えない、という状態)
(クリックで原寸)
建設地点を選ぶ時に完成予想図出すようにしたり、細かい改良色々。
なんとなく負荷テストをやってみた。
Pentium4 3Gの作業マシンで、工場を建てまくって全力でユニットを生産しまくる。
カメラは何も無い場所を映したままで、内部処理でどんくらい手間取ってるかを見ていく。
2000体くらいから60FPSを切り、
3000体くらいから30FPSを切り、
4000体くらいでは15FPSとかそこらになってしまった。
何もしてない状態でこれなので、移動させたり戦闘させたりその場所を映したりしたらもっと低くなるだろう。
衝突判定や攻撃範囲内にいるか調べる処理は相互に行われるので、
ユニットの数の二乗に比例して処理負荷が増大していく。
やはりユニット数が増えてくるとこういう内部処理のウェイトが大きくなってくるようだ。
(分散させてこれらの処理が要求される状況を減らせばもう少し早くなるが…)
最大同時ユニット数は1000体くらいを見越してるんで特に対策を取らなくても大丈夫そうではあるけど、
ユニット大量に出す場合は5体とかそのくらいで1つのグループにまとめておいて、
周囲の状況の情報はグループで共有するようにしとくと色々都合がいいかもしれない。
5体なら周囲にいるユニットを調べる手間が5分の1になるし、
リーダーユニットを設定してリーダーユニットの攻撃範囲から自動攻撃のターゲットを選ぶようにすれば、
攻撃範囲内に敵がいるか調べる処理の手間も5分の1で済む。
同一グループ内のユニットとは衝突判定しないようにすれば衝突判定の手間も少しは減らせるだろう。
移動とかの指示も共有するようにすれば操作性の向上にもなる可能性もある。
(RoNの歩兵が3体一組になってるのと同様。
ただRoNはリーダーユニットしかステータス見られないのが気持ち悪かったんで、その辺の細かい配慮もやっておくべき)
そういえば、ロードオブザリングのRTSもザコユニットは10体で1グループになっているらしい。(
ここの2004/07/17の記事より)
ロードオブザリングのRTSもデモムービー見てると1000体くらいユニット出そうな感じだし、
近日発売のRTSの中には同時ユニット数が2000以上なのをウリにしているものなんかもあって、ちょっと悔しい気分…。
何やら流行ってて面白そうだったので本棚.orgに
登録。
小説類は登録するのが面倒なので…と言ってもそんなに多く持ってるわけでもないけど、最近読んで面白かった二つを。
参考書の類は「必要になった時手元にあれば心強い存在」と考えているので、
目次読んで中身断片的に読んでどんな内容が書かれているか確認したまま積んである本もある。
しかし他の人の本棚見ているともっと本読むことに費やす時間増やした方がいいような気がしてくる…。
類似本棚見ると見覚えのある名前もちらほら。
えらく間があいたけど建設実装。
次は資源の収集。
UI関係は文字列(std::string)とboost::anyオブジェクトのペアのやりとりで処理している。
文字列から命令を判別して、boost::anyから付加情報を得て実行、という流れ。
このせいでUI関係のコードはかなり泥臭いものになってしまっている。
こういう方法しかないような気もするけど…何かもっとスマートな方法は無いもんだろうか。うむむ…。
暑さと悪天候に気圧され、今回はコミケには行かず。
OpenGL2.0が発表されたらしく。
GL_ARB_draw_buffers、待ち望んだテクスチャにレンダリングする機能か…、と思いきや、
プログラマブルシェーダから複数の描画バッファへの出力する機能らしいので期待したものと少し違うようだ?
テクスチャにレンダリングする機能が未だに標準に無いのが謎で謎で仕方が無い。
GL_ARB_point_sprite、テクスチャを貼れるGL_POINT、要するにビルボード。
今まで板ポリゴンを自力で座標変換して代用してたけど、こっちの方が計算コストが少なくて済む。日常的に使えそう。
プログラマブルシェーダは…当分手出す余裕無さげ。
今までOpenGL1.1の機能しか使ってなかったけど、
これを機会に標準化されてる役立ちそうな拡張は遠慮なく使っていこうと思い立った。
拡張関数を引っ張ってくる一連の超面倒な作業は
GLEWに肩代わりしてもらう。
とりあえず減算合成を実現する拡張を見つけて無意味に減算合成しまくってみた(上図)。
glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
の二行を加えた後普段通り描いてるだけ。
前回の日記書いた後にTacticalCommandersがフリー化されていることを知り、久しぶりにやってみた。
フリー化で流れてきた新規ユーザーで初級の星はそれなりに賑わってるけど、
中級上級は相変わらず人数少なくてあまり戦闘が起こらず、面白くない。
あと4年以上前のゲームなだけあって、今見ると色々古臭い点も目立つ。
このゲーム、システムはとても面白いと思うんだけど、同時接続人数がそれなりに多くないと面白くないのが致命的だよなぁ。
一番人数多かったオープンベータの時期が一番楽しかった。
しかしこんなに面白いシステムのゲームがこのまま忘れ去られていくのは勿体無さ過ぎる。
このシステムでよりカジュアルユーザー向けなユニットデザインにしたゲームをどっかのメーカーさん作ってくれませんか。
ウケると思うんだけどなぁ。
2004/8
暑さのせいか、英伝VIの後遺症か、著しく集中力が低下してて作業が捗らない現状。
EmpireTohuの大雑把な方向性を確認しておくのも兼ねて、RTSのプレイ遍歴なんぞを書いておこうと思い立った。
今までやったRTSはAoC、EE、AoM、RoNの4つ。
AoK/AoC。
定番の歴史物RTS。
初プレイのRTSだけあって熱中していたけど、今思うと忙しすぎるのが不満だったように思う。
あと領主の時代までに時間かかりすぎるところとか、
その上領主の時代までは毎回全く同じことを繰り返す単調作業だったりとか。
EE。
類人猿がウホウホやってる原始から人型兵器が闊歩する未来まで時代が進化していく野心的な一作。
…なのはいいんだけど、時代の数、研究項目の数が多すぎてうんざりする、
ユニットのアンチ関係が時代が進む毎に大きく変わっていくのでついていけない、
早い話が複雑すぎ。
その割には大抵速攻で勝負がついてしまい、いまいち製作者の意図がわからなかった。
その膨大なリソースと、後になるにつれて戦闘がスケールアップしていく様子にはちょっと感動していた記憶も。
AoM/AoT。
神話物RTS。
現行のRTSの中では多分最高レベルのグラフィック。
描画負荷との兼ね合いでそうなってるんだと思われるけど、人口コストの上限が厳しすぎるのが不満。
そのせいで戦闘が完全に拠点取り合い合戦になってしまってるのも不満。
しかしそれ以外はAoCと比べてより洗練され、程よく簡略化されていて遊びやすく、現在一番気に入ってるRTS。
誰か一緒にやりませんか。
RoN。
原始から現代までを描く歴史物RTS。
前線システムが最大の特徴なんだけど、敵陣には建物建てられないのがどうも納得いかない。
これのせいで大幅に戦略を狭められてるように思う。
あと内政。送り込める農民の上限が決まっていたり、時間あたりに得られる資源に上限があったり…。
とにかく制限だらけなことが目に付くゲーム。
加えてグラフィックは同時期に出たAoMに大きく劣る。
あと戦闘バランス。アンチが極端すぎる気が。
4つの中で一番飽きるのが早かったのがこれ。
あと、MMORTSっぽいネットゲーのTacticalCommandersにのめりこんでいた時期も。
ああいうシステムのネットゲーまたどこかが出さんもんか。
延々NPCモンスターと単調な戦闘を繰り返してレベル上げするだけのMMORPGはやる気が起きん。
虎の穴に立ち寄ったらChronicle 2ndを発見。購入。燃える。
ゲームばっかり週間につき、適当なプレイメモでも。
グラディウスV。
過去の日記やコメント欄にあるように、前期待が物凄く大きかった一作。
そして、期待を裏切らない内容だった一作。
美しいグラフィック、美しいレーザー、ギミック満載なステージやボス…、
初回プレイの2面はBGMとのシンクロもあってプレイしてるだけで泣いてしまいそうな感動が。
デモがスキップできないとか、エフェクト派手すぎて自機見づらいとか、
1周するのにかかる時間が長すぎて(丁度1時間)途中で集中力切れるとか、細かい不満はいろいろあるけど、
買って大満足な出来だったことに揺るぎは無い。
5面がお気に入り。美しく相互作用(衝突)するジャガイモ群が見てて楽しい。
英雄伝説VI。
お使いイベントだらけな上に移動は徒歩のみでダルかったり、
戦闘システムがいまいち好きになれなかったり、
俺の嫌いな「レベル上がると取得経験値下がっていく制」だったりで、不満だらけ…、
に思われた割には、クリアまで40時間程かかるのに4日で終わらせるくらいのめり込んでしまった一作。
序章やってる時は途中で飽きそうな予感がしてたんだけど、2章3章が面白かったせいだろうか。
しかし、エンディングが「実はこれまでの冒険は長大なオープニングだったのです。次回にご期待」
的な内容で最後に裏切られた気分に。
次回作作るにしても今作は今作で完結させて欲しかった。
RPGの使用キャラは性能より好みで選ぶ、という信念により、最終メンバーはいつもの二人+クローゼさん+ティータさん。
何故か今更Cross Channel。
ボリューム不足な感が否めないのは置いとくとして、これまたエンディングが不満。
主人公はあの世界で一人死ぬことすら許されず、
アンテナを作っては巻き戻され作っては巻き戻されを永遠に繰り返すことを考えると薄ら寒いものすら感じられて後味悪い。
曜子さんと二人で永遠に暮らす方がまだマシなように思える。
英雄伝説VI終えた後の憂さ晴らしにやったつもりが今度は沈んだ気分に。
現在はFF2をやってたりするんだけど、まだ中盤あたりなのに飽きつつある。
あと、ひなたぼっこ、期待してたんだけどえらく評判悪いみたいなので見送り。
いい加減作業再開する頃合な気もするけど、
未だに俺の胸中を渦巻く英雄伝説VIのエンディング見た後のやるせない感を晴らすべく、
何か後味良く終わってくれるゲームをやっときたいところなわけで。
ああもう、俺みたいな焦らされるのが大嫌いな人間が今英雄伝説VIをプレイすべきではなかったのだ。
2004/7
来月まで作業が延びて強烈にやる気減衰中。
少しずつ自分の作業も平行して進める方向で行くべきか。
175△歌鶫。
122△連雀。
いかに生産性を高めるか、=いかにラクしつつ作るか、という方法の追求は、めんどくさがりやな俺には永遠のテーマ。
hl作ってた時は可能な限りスクリプトドリブン&データドリブンにする方向で模索してたんだけど、
スクリプトドリブンにしても開発効率は大して変わらない、しかも実行効率は大幅に悪くなる、これは割に合わない、
てわけで最適解とは程遠いだろうという結論に達する。
データドリブンは動きが定型化されてるキャラクタを実装する時有効だけど、恐らくSTG以外のジャンルでは使える場面は少ない。
最近は部分部分で独立性を高めてコードを再利用する方向で模索していて
・キャラクタは外部オブジェクトとして分離する
・キャラクタはイベントドリブン方式で動かす
・キャラクタコードは、二つ以上のクラスに分散するコードをテンプレートクラスとして抽出し、それらを継承しまくることで実装していく
という開発手法を採り始めている。
今のとこアクションゲームらしきものとRTSらしきものでこの方法を試してみて、
どちらも概ねうまく行ってるように見えなくもないし、この方法で開発しててしっくり来る。
これが今のところの自分なりの最適解と言える方法になりそうだ。
…というような内容を中間発表会で話す。
豆腐よりローポリなキャラモデルなんて無理だからキャラ数は制限しないといけなくなるんだろうけど、
俺のAoMへの一番の不満がユニット数制限がきつすぎること(120体とかそこら)なので、
少なくとも200機以上は出せるようにしたいところ。
あと制限は国によって違うとか、リミッター緩和モードや解除モードつけるとかの要素も入れるとか。
ザコモデルは多くても250ポリゴンくらいが目安だろうか…、きっつー…。
違うアプローチとして、Ys6や英伝6みたいにキャラモデルのプリレンダ画像をビルボードにするって手も考えられる。
モード切替できるようにしておくのが理想だけど、そこまで手が回るだろうか…。
220△斑鳩。
EmpireTohu、予想以上に色んなところから反応があって嬉しかったり恐縮だったり。
反応を見てて意外だったのが、不満な点としてクリック連打な操作性が多く挙げられていた点。
せめてユニットのナンバリングくらいは実装しておくべきだったかもしれない。
このへんも今から対策練っておかないと。
再開後の予定は、資源の収集と建設、操作性の改良、地形の考慮、視界の考慮、キャンペーンをつけてみる、あたり。
これらを実装して、快適に遊べるように調整してから次のバージョンをリリースしたいところ。
あと、豆腐の軍隊は俺自身気に入ってたりするんで、今後新しい国データ作った後も残していく予定。
鳳来の国vs大豆腐帝国とか、さぞかしアホらしい光景になるに違いない。
リリース後に友人から「範囲選択してる時エラー出て強制終了した」とゆー切腹したくなるような報告を受けて、
必死こいてテストし直してるんだけど全然再現しない。
詳細聞いてるとどうも工場が怪しいみたいなんだけど…。
EmpireTohuリリース。
というか、今月が終わるあたりまで完全に時間取れなくなったんで仕方なくな感が強い。
建物の建設などは再開後に。
現状豆腐が群れて暴れまわるだけで戦略もへったくれも無い内容だけど、
斑鳩のキャラにしてキャンペーンつけたりして冬コミあたりで売りたいねぇと計画中。
延々とテストと調整。
現状ユニットが自律的に敵を探して隊列を組んで攻撃していく様子を観察するのは楽しいんだけど、
ゲームとしてプレイしてみると驚くほどつまらんという致命的な問題があるんで、
もうちょっとプレイしてて面白くならんもんかと試行錯誤しているところ。
しかしもう片方の作業の期限が迫ってきてるんで、そろそろ適当なところで中断しないといけない…。
他のユニットにぶつかった時の挙動を改良してより美しい隊列を組むようにしてみた(上図)。
攻撃のために接近する時他のユニットにぶつかったら回りこむ、という挙動を加えたんだけど、
図体のでかいユニットはますますつっかえやすくなり、敵に接近しにくくなり、
接近しようともがいてる間は一方的に攻撃されるんで混戦の時とても不利になるという、
AoMにもある好ましくない挙動をなぞる結果となってしまった。ま、いっか。
あと、攻撃アニメーション。
基本はモーフィングだけど、少しでも計算負荷を抑えるために事前に1フレーム毎の頂点を保存して使うようにしてみた。
法線情報も欲しいんで法線も1フレーム毎に保存しておく。
この方法は描画は早いけど、とんでもなくメモリを食うのが問題。
例えば500三角ポリゴンのモデルを5秒(300フレーム)動かすとすると1500の頂点と法線が300セット必要になるわけで、
容量にして…10MB強…。
超ローポリなモデル使ってる今はそれほど問題でもないけど、将来的にヤバくなりそうな気がする…。
ユニット生産の実装、建物のバリエーション増やし、ハイライトされてるユニットは頭上にライフゲージ出すように、
可視判定の高速化、可能な場面では行列をキャッシュして計算の高速化、他細かい改良色々。
あとは攻撃アニメーションつけて、簡単な敵の行動パターン(ユニット単位ではなく国単位の行動)をつけてリリースする予定。
多分今週中には。
GeForce4Ti4600なメインマシンで自分の作ったSDL+OpenGLのプログラム動かすと、
何故か左図みたいにポリゴンが交差する部分がギザギザに表示されていた。
当然本来は右図のようなスムースな表示になるはず。
あまりの表示の汚さに我慢できなくなって徹底的に調べてみたところ、
OpenGL初期化時にステンシルバッファを有効にしたら解決できることが分かった。
解決策が分かったのはいいけど…何故?
ユニットの行動を色々弄ってみる。
今まで自動攻撃のルーチンは「射程内に敵がいたら攻撃」だったのを、
視界パラメータをつけて「視界内に敵がいたら射程内に捉えるまで接近して攻撃」に変更。
他、攻撃を食らったら攻撃してきた敵に接近して反撃する行動の追加、
付近に攻撃行動を取ってる味方がいたら攻撃に加わる行動の追加、
攻撃を優先する移動の指示(視界内に敵がいたら攻撃、そうじゃなければ移動。AoMで言うとこのAlt+R)の追加。
射程が違うユニット群が同時に接近行動を取ると隊列を組んでるように見えなくもなくて面白い。
タイトル画面をつけてタイトル画面とゲーム画面を行き来できるようにしたところで、リークしまくってることが発覚。
タイトル画面に戻ってゲーム開始して…を繰り返してると、メモリ使用量がガンガン上がっていく。
どうやらフィールドにスマートポインタを含むオブジェクトのせいで循環参照が生じ、解放されないオブジェクトが出てくるようだ。
スマートポインタを含むオブジェクトはKillイベントが来たら保持するスマートポインタを全部解放するように変更して解決。
…解決できてるといいなぁ。
今回はスマートポインタは主にboost::intrusive_ptrを使っている。
boost::shared_ptrは管理するオブジェクトとは別に参照カウンタオブジェクトをnewするので、
ものすごく頻繁に生成されるオブジェクトの管理にはboost::intrusive_ptrの方が向いていると思われる。
しばらく前にあったAoMのハデス亡霊バグを目にした時、亡霊が沸きまくってる間はなんともないけど、
移動しだすといきなり重くなる、という現象を見てなんでだろうと思ってたんだけど、
あれはひょっとすると移動中の衝突判定に手間取って遅くなってたのかもしれない。
と、今作ってるので同じような現象が起こるのを目にして思った。
2004/6
ミニマップ実装(画面右下)。
意外なほどあっさりとできてしまった。
やってることはミニマップ用のビューポートを設定してユニットの位置を点で描くのと、
ミニマップの幅とマウスカーソルの位置の比から対応する位置を割り出すことだけ。
ともあれ、これで一気に操作が快適になった。
あと攻撃のバリエーション増やしたりエフェクトを必要以上に発生させたり。
というか一番最初に入れた攻撃が隕石落としってのは何か間違ってる気がしなくもない。
残るはユニット生産だけど、これが予想外に苦労している。
建物やら国情報やらUIやらが絡み合ってなかなかスマートにいかない。
最大瞬間ユニット数は1000超を想定してるんで、処理負荷削減のための小細工も色々考えないといけない。
怠けることに全力を注ぐのだ。
今のとこ採ってる対策らしきものは…
・ユニットが周囲のものと衝突判定するのは移動してる時だけ
・ユニットが射程内に敵がいるか調べるのは30フレームくらいに一回
・範囲攻撃でない弾は事前に設定したターゲット以外とは衝突判定しない
・ゲーム進行に影響を与えないもの(エフェクト類)は、発生源が視界内に無い時は生成しない
このくらい。
3つめはかなり迷った末の苦肉の策。
こうしないと弾大量に出した時の処理落ちが酷い。
現状PenIII1G+GeForce2GTSのいつもの環境で、
500ユニットvs500ユニットが攻撃しあっても辛うじて60FPSを維持している。
(モデルは30ポリくらいの簡略化したもの。やはり視界内に大量にいると遅くなるが)
まだまだ早くする余地はありそうだが…。
攻撃、射程内の敵への自動攻撃と追尾まで実装。
思いの外手間取ってしまった。
あとはユニットの生産を実装してデモリリース…と行きたいところだけど、
だんだんミニマップが無い不便さに耐えられなくなってきた。
ミニマップの実装も必須か。
図は範囲攻撃の隕石落としらしきもの。
移動、ドラッグによる範囲選択、ダブルクリックによる画面内の同じ種類のユニットの選択、まで実装完了。
自分で操作していて楽しくてモチベーション上がりまくり。
次はいよいよ攻撃。
これもそんなに難しくないはず。
攻撃とユニットの生産までできたところでデモっぽいものを公開する予定。
そういえば先月誕生日を迎えていたのでプロフィールを少し更新。
RTS、ようやく「とりあえず動く」段階に。
まだカメラの移動とユニットの選択しかできないけど、ここから先は今までよりは比較的スムースに行くはず。
次は移動。
移動まで実装できたら開発中のやる気も大幅増に違いない。
拡張パックが発売されたっつうことで、RiseOfNations(以下RoN)を拡張パックごと購入。
AoMに比べるとグラフィックが粗かったり、エフェクトが筆舌に尽くしがたいほどしょぼかったり、
ぱっと見EmpireEarthに瓜二つだったりで第一印象は最悪だったけど、
何度か戦闘をこなしていくうちにそれなりに楽しめそうな気がしてきた。
しかし既にAoE系に慣れきってるせいか、前線システムには抵抗を感じる。
(前線システム:RoNには領土という概念があり、町や要塞を建設するとその周囲の領域が領土になる。
敵は自分の領土内には建物を建てられない。自分の領土内の敵は勝手にHPが減っていくなどの恩恵がある。
必然的に戦闘は領土の境=前線で行われる傾向になる)
というか、前線システムは守る側に有利に働くものなので、AoE系でありがちな速攻勝負が難しくなるのかと思いきや、
実際にはまだ領土があまり意味を持たない太古~古代での速攻がとても有効。
しかしそれ以降の時代は領土による影響が大きくなり、町の耐久力は上がってお互いに攻め落とすのが難しくなる。
この状況を打破する決め手となりそうなのはロケット弾や爆撃機や、大都市すら一撃で陥落させる核だけど、
それらは近代~現代にならないと作れない。
というわけでRoNの戦闘は、太古~古代の速攻で片方がリードして中世~ルネサンスあたりで勝負がつくか、
均衡状態を保ったまま現代までもつれこんで核を打ち合う泥沼の混戦になるかの二極になっているような気がする。
デバッグとリファクタリングと建設的とは言い難い内容の話し合いとその他雑務をこなしてる内に一週間経過。
やべ。急がんと…。
堕の人の頼まれ物の副産物として掲示板っぽいものができたので設置してみる。
地形のカリングも実装完了。
劇的に早くなった。これで安心して次の作業に移行できそう。
前回の視界内の一部のキャラまでカリングされてしまうのは、
アスペクト比に正常に対応できていなかっただけだったらしく。
今回はキャラクタも地形もグリッド分割式の空間で管理している。
キャラクタは移動する度に適切なマスへ再配置し、
地形はモデルデータのロード時にマスの大きさに合わせて切り刻んで格納しておき、
視錘台内にあるマスが保持するキャラクタ/地形のみ描画している。
3D空間管理で最もメジャーな方法のような気がする8分木(octree)は、実装がいくらかめんどくさそうなのと、
グリッド方式に対するアドバンテージがいまいち分からんので後回し。
残る描画速度改善のテクニックはLODだけど、
今から自動的にポリゴン減らすアルゴリズムの実装なんてやってられんので、
近距離時表示用、中距離時表示用、遠距離時表示用の3つのモデルを用意しておき、
カメラからの距離でモデルを差し替える単純な方法でやる予定。
デザイナさんがんばってくれ。
イベントによる通信機構や描画回りはアクションゲームでもRTSでもほぼ共通だけど、
そろそろ共通でない部分に手を出す段階に来たようだ。
とりあえず次はRTSの基礎部分。
ユニットの選択、移動、攻撃あたり。
カリング実装中。右は上から見た図。
ポータルシステムは難しそうなんで、とりあえず視錘台によるカリングを採用。
判定が少しおかしい(視界内のキャラまでカリングしてしまう)のを改善し、
地形ポリゴンを自動的に分割してカリングするところまでやったら、描画関連は一段落する予定。
前期の残りの作業スケジュールを見ると、どう楽観的に見ても無理がありすぎる。
今月来月は長期的な修羅場モードになりそうな悪寒。
2004/5
久々の新ムービーキター!
チーム製作の仲間と、敵キャラをどう実装していこうかと相談。
正直なところゲーム作る上で一番ダルいのはどこかっつったらキャラクタのバリエーションを揃える作業なわけで、
(キャラクタの構想というか妄想を練るのは最も楽しい作業の1つなのだが)
それを見越して、キャラクタ製作用インターフェースとテンプレートとして使えるキャラクタクラスを作り、
後はキャラ製作はできるだけもう一人のプログラマに任せよう、と企んでたんだけど、
諸々の事情によりその企みの実現が危うくなってきた。
そうでなくても、いつまでもキャラクタ製作から逃げるわけにはいかない。
そんなわけで、効率的なキャラクタの製作方法を考える必要が出てきた。
今回話し合ったのは主に行動パターンをどうするかについて。
敵クラス毎に行動を一つ一つ定義してやればいい話ではあるんだけど、
手を抜くためならどんな労力も厭わない俺としてはそんな素直で面倒な方法は避けたい。
ここでふと思いついたのが、行動パターンを抽象化して抽出し、オブジェクトにしておくという方法。
例えば「敵を探して、見つけたら攻撃」という、かなり一般的なキャラクタの行動パターンを考えてみる。
どのように探すか、どのように攻撃するかはそのゲームとそのキャラクタによって全然違うわけだけど、
探す、見つける(条件分岐)、攻撃、などの共通の行動を純粋仮想関数にすることで、
ゲームやキャラクタの実装を知らなくても行動パターンを記述できる。
キャラクタクラスでは、どのように探すか、どのように攻撃するかのみを記述する。
例えば
こんな感じ。
あんまり複雑になると行動と状態が増えすぎて破綻しそうな気がするけど、
そこまで複雑な行動をするキャラを作る気はないので、物は試しで実装中。
頂点単位アニメーション、当たり判定、地形、丸影、一通り実装完了。
ようやくアクションゲームっぽくなってきたような気がする。
現状でGeforce2GTS+PenIII1Gの環境で地形描いて700ポリゴンくらいのキャラ40体出して約45FPS。
カリングもLODも一切やってない状態だから、もう一回り速くできそう。
地形は事前に高さ情報を抽出して2次元の画像にしておき、
キャラのXZ座標からインデックスを得て、同じマス内の4つの点を線形補完して接地させている。
3Dアクションゲーム開発のテクニックとしてよく紹介されている(ような気がする)のはキャラの手前にレイを飛ばす方法だけど、
計算が重そう&高速化のために木構造作るのに手間取りそうなので今回は却下。
卒業制作の企画書とやらにAge of EmpireっぽいRTS作ります的な内容を書き、それが受理された。
期限は1月だけど、前期終了までにはプロトタイプを提出しないといかんらしい。
アクションゲームのこともあるし、8月まで相当忙しくなりそう。
先月からGentooLinuxを入れて遊んでたんだけど、
起動するたびにNTFSドライブを傷つける(Windows起動時に毎回checkdiskが起動する)という症状が出てて、
ついに先週一部のアプリが起動しなくなるなどの致命的な症状が出始めた。
つうわけで、Windowsを再インストールしてGentooの代わりにFedoraCore2を入れてみた。
しかしnvidiaドライバ入れるとXを起動時に固まる問題が発生。
さらに2ch見てるとNTFS傷つける症状が出たという報告が。
Xに関しては、Gentooでもnvidiaドライバを入れた場合、
ここに従ってカーネル
の構築からやり直すまでX起動時固まる症状が出てたんで(GeForce4Ti4600環境下)、FedoraCore2でも同じ手順を踏めば治るのかもしれない…が、
面倒だ。
つうかNTFSドライブを傷つける問題さえなければ当分Gentooがいいんだけど、原因は何なのか。
結局現在はその場しのぎにRedHat9に戻している。
チーム製作のスケジュールが予定より遅れており、
ここ数日は寝食以外のほぼ全ての時間をプログラム書きとデバッグに費やす日が続いている。
遅れの最大の原因は、キャラクタデータをDLL化したこと。
自分でも何故だかよくわからないけど、俺はプログラム本体とキャラクタデータを分離しないと気が済まない性質で、
そのためhlではキャラクタのロジックをLuaで記述するようにしてたけど、
弾一発に至るまでLuaで制御ってのはさすがにきついってこともわかったんで、
今まで以上にパフォーマンスが重要な問題になる今回はDLL化に踏み切った。
踏み切ったはいいんだけど、DLLとSTLが相性が悪いということを知らず、延々不可解なエラーに悩むはめになった。
(この問題に関しては
ここが参考になった)
現在本体-DLL間でSTLのコンテナを直接参照するのは一切避け、
インターフェース(メンバが全部純粋仮想関数のクラス)をきっちり定義して、それの参照をやりとりすることで解決している。
しかしDLL側の制御はデバッガで追えなくていざってとき困る。
やり方知らないだけで何か方法ありそうな気はするけど…。
lua_Number(double)の中に無理矢理型情報仕込んだらLuaでもユーザーデータの型判別が簡単にできるんじゃなかろうか、
というちょっと邪悪なことを思いついて試してみた。
上手くいってるようにみえる。
この手を使ってLua用のベクトル・行列ライブラリを
書き直してみた。
ベクトル・行列ライブラリといえば、boost::uBLASか
tvmetの導入を検討中。
expression templateとやらによる強力な遅滞評価で大幅なパフォーマンス向上を望めるらしい…。
2004/4
重度の無気力周期。やる気が欲しい。
WindowsでいうところのLoadLibrary,GetProcAddress,FreeLibraryのLinux用の相当品がdlopen,dlsym,dlcloseであると知る。
つうわけで、
薄いラッパーを作ってみた。
これは色々使えるかも。
竹内均先生、死去
中学生くらいの時まで将来の目標は物理学者(主な興味の対象は核物理)で、Newtonは愛読していた雑誌だった。
御冥福をお祈りします。
しかし最近、有名人が死にすぎではあるまいか…。
STGにもACTにもRTSにも使い回せる汎用的なキャラクタの設計を、ということで、
StateMachineでEventDrivenなキャラクタのコードを書き書き。
手順をまとめると以下のような感じ。
キャラクタオブジェクトにイベントキューを持たせる。
何かイベントが発生したら(生成された、アップデートされた、ダメージ食らった、死んだ、等)イベントキューにイベントを詰める。
キャラクタの行動はイベントキューに溜まったイベントを処理するという形で行う。
イベントの送信を専門に行うイベントルーターを用意する。
イベントの遅滞送信を実現するため、イベントルーターには送信時間をキーにしたpriority_queueのイベントキューを持たせ、
指定した時間が来た時キューからイベントを引っ張り出して送信する、
これにより、一定時間後自殺する等の行動が簡単に実現可能になる。
遅滞の間に送信先キャラクタが死んでることがあり、イベントの送信先としてキャラクタへのポインタ直接指定は危険なため、
キャラクタオブジェクトにはIDを持たせ、送信先はIDで指定する。
GeForce6シリーズ来月中に発売?
そろそろGLSLやPS2.0が使えるビデオカードが欲しいと思っている。買ってみようか。
GLSLにはまだ正式には対応してないけど、時間の問題だろう、多分。
ファントムブレイブが面白かったから、という理由で今月初めからディスガイアをやってたんだけど、今日ようやくクリア。
ディスガイアもファントムブレイブもほぼ同じようなシステムと聞いていたし、
実際似通ってる点も多いんだけど、方向性はファントムブレイブとはまるで正反対のように見える。
主にファントムブレイブと比べて気になった点を挙げていくと以下の通り。
ターン制。これがファントムブレイブとの決定的な違いだと思う。詳しくは後述。
ファントムブレイブ以上にレベル上げを強いられるゲームバランス。
魔法使い系が異様に強い。魔法が戦士系キャラの必殺技を上回る威力を備え、長射程な上に攻撃範囲も広い。
敵は終盤になるほど固くなり、ザコ一匹倒すにも3人以上で袋叩きにする必要がある、
味方は終盤になるほど(相対的に)脆くなり、防具でHP底上げしないと1~2発で殺されるので、周到に待ち伏せる必要がある。
装備をしっかり揃えれば上二つの苦労は軽減されるんだろうけど、値段が高すぎてまず無理。
アイテム界というランダムダンジョンがあり、奥に進むことでアイテムを強化できるが、超絶めんどくさい。
ジオシンボルとかいう果てしなく鬱陶しいだけの要素が存在する。
前々から思ってるんだけど、
延々と同じマップやランダム生成ダンジョンに潜ってレベル上げすることを強いるタイプのSLGにターン制は向かないように思う。
ターン制のゲームはどうしても一回の戦闘の密度が濃くなり、テンポが悪くなりがちで、
テンポ良く敵を倒し、キャラやアイテムのレベルを上げることに楽しみを見出す(と俺は思ってる)延々レベル上げる系ゲーム
とは相反する性質を持ってるからだ。
結局俺にとってのディスガイアは最後までダメなレベル上げ系ターン制SLGの典型だった。
プレイヤのターンでキャラ選択の優先順位を考えるのがだんだん苦痛になってくるし、
敵のターンで敵が一方的に移動、攻撃してくるのを見守ってる時間もだんだん苦痛になってくるし、
終いには「Player Turn」とか「Enemy Turn」の表示すら鬱陶しくなってくる。
ディスガイアは移動と攻撃フェイズで分かれているので尚更。
さらにジオシンボルという余計な要素が鬱陶しさに拍車をかけている。
ファントムブレイブでタクティクスオウガ式にしたのは英断だったと思う。
そういえばファントムブレイブのとき2chでこのような書き込みを目にした。
「ファントムブレイブが楽しい奴にはディスガイアは合わないし、ディスガイアが楽しい奴にはファントムブレイブは合わない」
そんな大雑把に括れるわけなかろ、と思ってたんだけど、今になってこの言葉が身に染みる。
俺はモロに前者だったようだ。
まだ本編をクリアしただけでエクストラステージには手をつけてないんだけど、
これ以上のレベル上げは苦痛以外の何者でもないので諦めそうな予感。
んでも天使兵は作りたいなぁ。萌え。
ファイアーエムブレム 蒼炎の軌跡今冬発売らしい。
FE紋章の謎は推定プレイ時間500時間以上で、飽きっぽいこの俺が半年程はまった神ゲーであり、
今でも「今までプレイしたゲームの中で一番はまったものは何か」と問われたら
FE紋章の謎と即答するくらい気に入ってるゲームだ。
しかし紋章の謎の続編である聖戦の系譜は、突撃や大盾に代表される理不尽なスキル、
敵の攻撃全てが命中することを前提として考えると確実に誰か死ぬ理不尽な敵配置、
この上なく不要な存在に思われる恋愛システム
等で盛大に俺の期待を裏切ってくれたゲームでもある。
俺にとってFEとは、敵の行動範囲、攻撃範囲、攻撃力を調べ上げ、受けるダメージ、食らわすダメージを綿密に計算し、
敵の攻撃は全て命中するものという想定の元に味方を配置し、
時折起こる攻撃のミスや、時には味方の放つ必殺の一撃すらも不測の事態として処理する、
そんな詰め将棋的なプレイ感がたまらなく楽しいゲームであって、
聖戦の系譜のように指揮官ユニットの支援効果や武器の相性で常時命中率が50%切ったり、
突撃とか言うわけわからんスキルで勝手に戦闘を継続させて勝手に死ぬアホな味方が出たり、
城を守る敵に大盾とか言うわけわからんスキルを3連発とか4連発で出されて
綿密に組んだ攻撃パターンを無かったことにされたりするゲームであってはいかんわけだ。
聖戦の系譜以降はスキルがあるってだけで回避してたんだけど、蒼炎の軌跡ではどうなってるんだろう。
紋章の謎並に面白いならGCごと買ってもお釣りが来まくること間違い無しなんだけど。
サイヴァリア2サントラ、とてもいい感じ。
俺にしては珍しく買って満足だった1枚だ。
Etaが特にお気に入り。
この機会に過去に書いた腐ったHTMLから脱却しよう、つうことで、
w3.orgのチェックにも通るまともなXHTMLに書き直してみた。
全部はめんどくさすぎるので主要な部分だけ。
書き直すに当たってちょっと詰まったことがあって、
<div align="center">によるセンタリングをよく使うんだけど、w3的にはこれはダメらしい。
その代わりに<div style="text-align: center;">とすることで同等の機能を実現できる…はずなんだけど、
Mozillaではこれが上手くいかない。具体的には、テキストはセンタリングされるけど、他の要素がセンタリングされない。
IEでは望む結果になったんだけど…。
しょうがないので現在は要素毎に
margin-left: auto;
margin-right: auto;
を指定して無理矢理センタリングして解決している。
健康診断にて、左右の視力が全然違ってることが発覚。
眼鏡かけた状態で、片方が0.8、もう片方が1.5。
酷い。去年替えた眼鏡が合ってなかったのか。
元々頻繁に頭痛を起こす体質なんだけど、ここ数ヶ月の頭痛の原因の一つがこれであることは間違い無い。
金もったいねーけど、さっさと替えるか…。
視力以外は至って良好との結果。
去年の暮れに血尿出したこともあって心配してたんだけど、一安心。
2004/3
微妙にサイト構成変更。
programコンテンツは暫定。
需要が高そうに見受けられるglKanjiはある程度改良加えて公開する予定。
こちらのサイヴァリア2のムービーをぼけーっと眺めていた。
俺はゲーセンでは数回やって、入力の遅れ、冗長なデモ、大味過ぎる内容
(前作よりレベルアップしやすくなってて無敵になりやすくなっているが、敵の配置や攻撃のいい加減さも増している)
に耐え切れず投げてしまったクチだけど、
こうして見るとこのゲーム、音楽はいいしグラフィックも悪くない。
あんな大味な内容になってしまったのが勿体無く思える。
しかし音楽はホントいいよなぁ…と思ってたら、
サントラ売ってたのか!その場の勢いで注文。
昨日のavxdemo。
色んな環境での結果が知りたくて、知り合いに協力を仰いで調べてみた。
同じような環境でもかなりばらつきがあったけど、成績のいい方で見ていくと、
GeForce256でも50FPS、GeForce4Ti4200あたりで200FPS、Radeon9200あたりで160FP、
Radeon9800XTに至っては300FPSオーバーとかそんな感じ。悪くない結果だ。
…と言いたい所だけど、不可解なのがGeForceFX系。
GeForceFX5200で55FPSだったり、GeForceFX5600で70FPS程度だったり(勿論VSYNCは切ってある)
お前らやる気あんのかよ的な結果に。なんでやねん…。
お気遣い感謝。
帰省してました。帰ってきました。
過去に何度か書いてる通り、実家は宮崎なわけだけど、
夏や冬だとそれほど実感できないけど、この時期に帰ると気候の違いが良くわかる。
昼は東京より暑く、夜は寒い。
おかげで体調崩しまくり。
前回の日記のavxモデル、
GeForce2GTS+PenIII1G環境下で676ポリゴンのモデルを50体出して動かしてみたところ、85FPS出た。
十分実用になってくれそうだ。
実際のゲームではピーク時で画面内に50体くらいキャラ出したいと思ってたんだけど、実現できるかもしれない。
しかし676*50で33800ポリゴンに及ぶわけだけどこの速度。GeForce2GTSってここまで底力あったのか。
サンプルモデルは2chのローポリスレで見かけた
観鈴さんを使用させていただきました。
avxdemo
avertex
頂点数が同じの複数のモデルを読み込んで線形補間してアニメーションをつけるもの。
要するにモーフィング。
全ての頂点を事前に計算して保存しておく紙芝居方式はメモリ使用量が気になるのでこうしてみた。
紙芝居方式も実装は簡単なので、モーフィングに問題があるならそっちも試してみる方向で。
現状法線を出力しないんで見ての通りシェーディングできなくなるんだけど、法線も出力するオプションもつけとくべきか。
実際にこれで作ったモデルを複数出してみるテストはこれから。
チーム製作はアクションゲームで確定。
ミーティングでデザイナさん向けの最低限の仕様を決める。
ザコキャラは800三角ポリゴン以下、自キャラでも1500程度、シェーディング無しで陰もテクスチャに描き込む、など。
キャラクタのアニメーションはMAYAで作ったモデルを連番objで書き出してモーフィングか紙芝居方式で実現する。
上のツールはこのために取り急いで作ったものでもある。
俺は来月中にはプロトタイプを提出するということで、フィールドを歩き回って敵を撃ち殺すくらいはできるものを作ることに。
Fateオールクリア。長かった…。
面白いのは面白かったけど、今ひとつ物足りない感があるのはいまいちキャラに萌えなかったせいか。
というか上級生キャラがいないってのは画竜点睛を欠くってもんではないか。(個人的趣向)
学校のチーム製作とやらでゲームを作ることになる。
メンバーはデザイナ4人、プログラマ2人(含俺)の計6人。期限は8月。
このまま順当に行けばアクションゲームになる予定で、戦国無双とかああいう系統を目指す。(言い出しっぺは俺)
イベント、描画、音はSDL+OpenGL+SDL_mixerで。
ステージデータはLuaで記述、キャラクタはハードコーディング。
俺は全体の設計とシステム部分のプログラムを、
もう一人のプログラマには主にキャラクタのプログラムを担当してもらう、とかそんな感じの脳内予定。
可能な限り今までの技術を使いまわして手を抜きたいところだけど、
アクションゲームで確定したとして、フィールドの管理はしっかりやっておかねばなるまい。
具体的には、可視判定して見えてないオブジェクトは描画しないようにする、
空間分割して効率よく衝突判定する、とかそういうもの。
今まで面倒で避けてた部分でもあるし、一度やっておけばSTGにもRTSにも応用できる基本的なことでもある。
グラディウスV体験会へ行ってきた。
グラフィックは素晴らしく綺麗。美しい。見惚れた。感動。
デモ動画は何回も見てたけど、実際の画面はやっぱ違う。
グラフィックマンセーな俺には最高の第一印象。
TGS版は未プレイだけど、回りの話を聞くに内容はほとんど変わってないぽい?
以下まとめ。全部既出だろうけど気にしない。
パワーアップは従来通り、スピード、ミサイル、ダブル、レーザー、オプション、バリア。
外伝にあったゲージエディットや、SFC版3にあったようなバリアの次(スピードダウンとか)は存在しない。
パワーアップは4つのタイプの中から選ぶ。
で、今回の最大の特徴であるオプション。タイプ毎に全く違う挙動で、具体的には以下のようなもの。
・固定
R1ボタンを押してる間、オプションの自機との位置関係が固定される。デモ動画の最初の方のあれ。
攻撃面では最強と思われる。
・方向変化
R1ボタン押しながら十字キーでオプションの攻撃方向を変えられる。
俺が勝手にグネグネレーザーと呼んでいたのはこれ選んだ時のレーザー。
・上下伸縮
オプションは基本的に自機を中心に「>」の字型に展開する(SFC版3にあったやつと同一)が、
上下の間隔を広げたり狭めたりできる。
使いやすいとは思えないんだけど、今回の体験会で一番多く見かけた気がする。
・回転
お馴染み。R1ボタン押してる間オプションが自機を中心に回転する。
こいつと方向変化の場合レーザーがしなる。
他は2のレーザーような縦軸を自機に合わせる一直線レーザー。
気づいたことを適当に列挙
・タイプ…というよりオプションは固定と方向変化が強すぎて他二つは出番が無さそうな気がしなくもない。
・ショットの最大同時発射数は5発?弾速は早く、ダブルでなければ弾切れを気にする必要はあまりない。
・レーザーは強くなったが、ミサイルがえらく弱体化してるよーな…。
・例によって自機の当たり判定はとても小さい。
・バリア(正確にはフォースフィールド)の当たり判定は自機と同じ?地形で削れない。
・死んだ後はその場復活。死んだらオプション以外の装備は全部失う。
オプションは死んだ時の位置に残っており、画面外に流されていく前に取れば取り戻せる。
画面外に流されていく速度は遅いので、大抵は全部取り戻せる。
・爆発はデモ動画と同様、赤と黒で表現されている。…いまいち美しくない気が。
・過剰な加算合成のせいか、ディスプレイが液晶だったせいか、自機や弾が見えにくくなる状況が多々。
・ボスがアホみたいに爆発しまくる。斑鳩も派手だったがあれの比ではない。
・ステージ間のロードがえらく長い。
体験会は大盛況で1プレイ1時間待ち。何度かやっておきたかったけど結局1回で辞退。
回りの音がでかすぎてBGMは断片的にしか聞き取れなかったのが残念。
ゲーム自体も面白かったし、今から7月が楽しみだ。
帰りに
ベンガルのカレーを食ってきた。
記事での評価が大げさだったせいかちょっと期待はずれだったけど、美味い方ではある。
次秋葉原行く時も寄ってみよう…。
進級確定。
安心した。疲れた。とりあえず泥のように眠ろう…。
wxWidgets布教活動。というか今までのまとめ。
まずは
本家からダウンロードしてライブラリのビルド。ここでは2.5.1前提。
Linuxではconfigure; make一発で問題なくビルド完了。
ただ、デフォルトではダイナミックリンクライブラリになるんで、
スタティックリンクしたい時は--diable-sharedでconfigureする。
だけどスタティックリンクするとバイナリが物凄いサイズになるんで、(最小限でも2MBとか)
可能な限りダイナミックリンクした方がよさそう。
VCの場合、include/wx/msw/setup.hの819行目あたりのwxUSE_GLCANVASを1に変更、
それと各プロジェクトのコード生成オプション-MDを-MTに変更してビルド。それで望む結果になった。
cygwinでは…configure; makeでビルドはできるけど実際に使うときリンクエラーが出る。調査中。
分かりにくいサンプルばっかりだったのが理解に苦しんだ要因だったので、
要点だけ絞った(つもり)のサンプルプログラムを。
VCの場合-MTオプションをつけないとリンクエラーになるので注意する。
ウィンドウを開くだけ
とりあえずOpenGL
コントロールを配置
イベントとIDの関連付けが分かれば問題なく使えると思われる。
GtkとかWinAPIでガリガリやるのに比べるととても楽で嬉しい。
んでも、Windows前提なら
WTLが最適か?
こっちもそのうち試してみよう。
課題、期限まで後少し。つーか絶対終わらん。
できるとこまでやってあとは運を天に任せるしか。
そして来週の土曜は
グラディウスV体験会へ。楽しみだ。
画面内に100体近くに及ぶキャラクタが出てくるようなゲームの場合、
ボーンを使ったデフォームでは行列の算出で相当コストがかかる。
ボーンを使ってないキャラでもパーツが多い場合は一つ一つ階層構造を追って行列を算出しないといけないので同様。
こういう場合アニメーションを攻撃時アニメとか歩行時アニメとかのクリップに分けて、
事前に1フレーム毎にモデルデータとして保存しておき、
経過時間に合わせてモデルを差し替える紙芝居方式でやるほうが適切かもしれない。
当然メモリ使用量が桁違いに増えるなどの問題も出てくるけど。
それを裏付けてる…と断言はできないけど、
AoMではモデルデータ(らしきファイル)の容量が、テクスチャデータ(らしきファイル)と比べて段違いにデカい。
models/models.bar 272MB、 textures/textures.bar 83MB
あんなにローポリなら普通はテクスチャデータの方が数倍大きくなるはずだ。
とりあえず時間と精神に余裕があるときに紙芝居方式アニメをやってみよう。
ボーンによるデフォームもいつかやってみたいなぁとは思うけど、
その「いつか」が1ヶ月先なのか1年先なのか10年先なのかは誰にも分からない。
どちらかというと俺はマイペースな人間なので、あまり周囲の事を気にすることはないんだけど、
昨日の一件でちょっと気になってきた。
今の俺の技術ってどの程度通用するもんなんだろう。
いかに自分がゴミであるかを思い知る。
2004/2
現状RTSを作るとして技術的に問題になりそうなところは
・経路探索アルゴリズム
・直感的なインターフェース
・遅滞まで考慮した通信とゲームの進行処理
あたりだろうか。
上二つはどうにかなりそうな気がするけど、最後のは見当もつかない。
AoE/AoMとか、どうやって進行させてるんだろ?
Doom3も60FPSで内部処理やるらしいから、とりあえず内部ループは60FPS決め打ちで大丈夫か?
…深く考え出すとキリが無いので、詳細な実装について考えるのは当分後回し。
ゲームの基本的な流れはAoE/AoM方式で、
資源を集めて、建物を建てて、進化して、軍事ユニット作って、テクノロジを研究して、攻める。という感じに。
内政が無い、または内政のウェイトが低いRTSもあるけど、ある程度内政のウェイトが高いと
内政の邪魔をして勝つ、などの戦法が使えるのが俺好みなのでこっちを採用。
極端な速攻を無効にするため、各陣営にはゲーム開始時から強力なボスユニットがいて、
そのボスユニットを倒せば勝ち、というルールにする。
AoMで言えば最初からティタンがいてティタンを倒せば勝ち、みたいな感じだ。
そしてFaction。(文明とか文化圏とか国家とか呼ばれるもの)
ここが一番構想を練るのが楽しい部分であろう。
例えば…
・機械化異星人軍団(怒首領蜂/大往生の敵)
単体性能は低いがコストも低い軍事ユニットが揃っており、ひたすら物量で押していく戦法を得意とするFaction。
進化していくと、強力な範囲攻撃を行う固定砲台・神顎や最終鬼畜兵器を建造可能になる。
ボスは緋蜂。全ボス中最凶の攻撃力を誇るが、耐久力は低い。
・鳳来ノ国(斑鳩の鳳来ノ国)
軍事ユニットの飛鉄塊は脆いが攻撃力と機動力が高い傾向があり、
内政荒らしで敵を内側から弱らせていく戦法を得意とするFaction。
進化していくと、大型爆撃機・仏法僧や機動要塞・鶚を建造可能になる。
ボスは産土神黄輝塊。攻撃力は低い方だが、とにかく硬い。
・旧世紀軍団(PanzerDragoonの純血種の面々)
機動力は低いが耐久力の高いユニットが揃っており、
敵の攻撃に耐えながらじわじわと押し返していく戦法を得意とする防戦的なFaction。
進化していくと、最高クラスの攻撃力と機動力を持つドラゴンや、超大型空中戦艦シェルクーフを建造可能になる。
ボスはセストレン・エクスシス。突出した能力はないが、意識融合体による爆撃で広範囲に攻撃してくる。
こんな感じで。
…こうやって妄想してる内が一番楽しいんだろうなぁと思いつつ、妄想終わり。
レポート課題に続いて論文課題まで出される。
来週の頭には発表会も待ち構えている。
この状況、過去最悪の修羅場かもしれない…。
進級製作はhlで、発表会はhlに使っている技術の解説だったりする。
公私混同もいいところだけど、今は形振り構っていられる状況ではない…。
来年度は今年度とは違う内容の研究・製作にしないといけないらしい、ということを聞いて、
来年度はRTSを作ろうかと考え始めている。
やり慣れてるジャンルだし、作ってて楽しそうだ。
プログラムが難しそうってのが問題になりそうな部分か。
hlは学校関係が落ち着き次第再開予定。
再開後はツール類の充実とモデル等各種リソースの作成を主軸に。
なんとしても一つの作品として完成させておきたい。
なんとなく
アンテナを立ててみた。
wxWidgetsの勉強中。
マルチプラットフォームなGUIクラスライブラリはいくつかあるけど、
GPLやLGPLより緩いライセンスで、それなりの知名度と使いやすさを備えているものとなると限られてくる。
(将来を見越してGPLへの感染は避けたいのだ)
で、俺が適当に見て回った中で一番良さそうだったのがこのwxWidgets。
スタティックリンクしてもソース公開の義務は発生しないライセンスだし、
可能な限りGUIの見た目をそのOSネイティブのものに近づけてる点も高評価。
欠点はバイナリのサイズがそれなりに膨れ上がることか。
(VC7.1で最適化オプション弄りまわしてみたものの、どんなに最小限のアプリでも700KB以下にはならなかった)
ちなみにwxWidgetsという名前になったのはつい最近(多分今週中)で、
それ以前はwxWindowsという名前だった。MS Windowsと紛らわしいってんで改名したらしい。
手始めにタイムラインエディタをまともなGUIで書き直し中。
リファレンスを見ながらチュートリアルを見ながらサンプルのソースを見ながらあれやこれやと試行錯誤しつつ。
その結果というか経過が
これ。
wxWidgetsも日本語の資料が少ないので、後日経過でも書こうかと。
期限までに終わらせるのが物理的に不可能なくらい大量のレポート課題が出される。
これが進級を阻む最後の壁だ、気合を入れてかからねば。てか終わるのかよこれ…。
何時の間にか日常的に使う存在になっているLua。
しかしこのLua、日本語のチュートリアルが絶望的に不足していて普及を阻んでるらしい。
なのでその素晴らしさを広めるべく基本的な使い方を適当に紹介してみる。
まずCからLuaの関数を呼ぶ場合
add.lua:
-- 足して結果を返すだけの関数。ちなみにLuaはコメントアウトは"--"で行う。
function add(a, b)
return a+b
end
// C++の場合extern "C"が必須。こうしないとリンクエラーになる。
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <iostream>
int main()
{
lua_State *L = lua_open();
// add.luaファイルを実行。これによりadd関数がグローバルテーブルに作成される
lua_dofile(L, "add.lua");
// グローバルテーブルからadd関数を拾ってスタックに積む
lua_pushstring(L, "add");
lua_gettable(L, LUA_GLOBALSINDEX);
// 第1引数に1を、第2引数に2を設定
lua_pushnumber(L, 1);
lua_pushnumber(L, 2);
// 関数を呼ぶ。lua_callの第2引数は渡す引数の数、第3引数は戻り値の数。
// 関数とその引数はスタックから取り除かれ、戻り値がスタックに残る。
lua_call(L, 2, 1);
// スタックの1番目の要素(つまりこの場合add関数を呼んだ結果)を表示する。
// ちなみにLuaの数値はデフォルトではdouble型
std::cout << lua_tonumber(L, 1) << std::endl;
}
結果:3
次にLuaからCの関数を呼ぶ場合
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
// Luaに登録するCの関数は、intを返し、lua_State*を受け取るものである必要がある。
// 返す値は戻り値の数。この場合数値を1個返す(スタックに積む)ので1。
int lua_add(lua_State *L)
{
lua_pushnumber(L, lua_tonumber(L, 1) + lua_tonumber(L, 2) );
return 1;
}
int main()
{
lua_State *L = lua_open();
// print()関数を使えるようにするために必要
lua_baselibopen(L);
// lua_add関数を登録する。lua内でのこの関数の名前は"add"
lua_register(L, "add", lua_add);
lua_dofile(L, "call_add.lua");
}
call_add.lua:
-- 上記の通り、addはCで登録された関数。
print( add(1, 2) )
結果:3
あと重要だと思われるのがユーザーデータ(任意の型)の操作。
まあユーザーデータってのはただのvoid*で、それをキャストしまくって使うってだけの話なんだけど。
以下、二次元の点(struct Point)をC側で定義し、Lua側から操作してみるテスト。
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <stdexcept>
struct Point
{
Point(float _x=0, float _y=0) : x(_x), y(_y) {}
Point operator+ (const Point& p) const { return Point(x+p.x, y+p.y); }
float x, y;
};
int lua_point_new(lua_State *L)
{
// 引数がある場合はそれで初期化。そうじゃない場合デフォルトのまま。
if(lua_gettop(L)==2)
lua_pushlightuserdata(L, new Point(lua_tonumber(L, 1), lua_tonumber(L, 2)));
else
lua_pushlightuserdata(L, new Point());
return 1;
}
int lua_point_add(lua_State *L)
{
Point *result=0;
// スタックに積まれてるものがPointであるかチェック。
// …と言ってもこれじゃユーザーデータであれば何でも通ってしまうので、
// より厳重にやりたい場合別の方法を考える必要がある。
if(lua_islightuserdata(L, 1) && lua_islightuserdata(L, 2)) {
Point *rhs = static_cast<Point*>(lua_touserdata(L, 1));
Point *lhs = static_cast<Point*>(lua_touserdata(L, 2));
result = new Point(*rhs + *lhs);
}
else {
// エラー処理は例外投げるのが一番妥当かなぁ…。
throw std::runtime_error("どっか使い方間違ってます@lua_add_point()");
}
lua_pushlightuserdata(L, result);
return 1;
}
// 以下面倒なのでエラー処理は省略
int lua_point_get_x(lua_State *L)
{
lua_pushnumber(L, static_cast<Point*>(lua_touserdata(L, 1))->x );
return 1;
}
int lua_point_get_y(lua_State *L)
{
lua_pushnumber(L, static_cast<Point*>(lua_touserdata(L, 1))->y );
return 1;
}
// lua_register()は関数を問答無用でグローバルテーブルに登録しやがるので、
// 任意のテーブルに登録したい場合以下のような操作で行う。
void lua_regist_function(lua_State *L, const char *func_name, int (*func)(lua_State*))
{
lua_pushstring(L, func_name);
lua_pushcfunction(L, func);
lua_settable(L, -3);
}
int main()
{
lua_State *L = lua_open();
lua_baselibopen(L);
// pointという名前のテーブルを用意し、Point操作関連の関数をこれにまとめておく
lua_pushstring(L, "point");
lua_newtable(L);
lua_regist_function(L, "new", lua_point_new);
lua_regist_function(L, "add", lua_point_add);
lua_regist_function(L, "get_x", lua_point_get_x);
lua_regist_function(L, "get_y", lua_point_get_y);
lua_settable(L, LUA_GLOBALSINDEX);
lua_dofile(L, "point.lua");
}
point.lua:
p1 = point.new(1, 2)
p2 = point.new(3, 4)
p3 = point.add(p1, p2)
print( point.get_x(p3), point.get_y(p3) )
結果:4 6
newに対するdeleteの事後処理やってないんでリークし放題だけど、それは話の本筋ではないのでとりあえず気にしない。
こんな感じで任意のデータを取り扱うことも可能であると。
以上のこととLuaのスタックとテーブルの操作を覚えれば何でもできる。かもしれない。
より詳細な情報は
こちらを参照。
授業が終わった日(10日)にファントムブレイブを購入、そして今日ようやくプリニガーXを倒し、事実上制覇。
寝食以外のほぼ全ての時間を費やすほどにはまったゲームは久しぶりだ。
買った動機は面白いらしいという噂だけで、プレイし始めるまでジャンルすら知らなかったんだけど、
一応ジャンルはタクティクスオウガやファイナルファンタジータクティクスと同系統のシミュレーションRPGのようだ。
…なんだけど、ゲーム自体はとても大味な作りなので、あまりシミュレーションRPGらしいゲーム性には期待しない方がいい。
(射程が長い技や魔法がほとんど無く、全体的にキャラの移動力が高めな上、
敵味方関係なく飛び越えられるので、魔法使い系などの後方支援型ユニットの存在意義が薄い。
なので必然的に戦闘は敵味方入り乱れて乱闘という形になる。
というか後になるほど敵も味方も一撃で死ぬようになっていくので支援なんぞどうでもよくなっていく。
一撃で死ぬようになっていくので先手必勝。速度が上がる武器を作る必要性が上がっていく。
キャラの成長は緩やかなのに武器の成長は異様に早いので、後になるほどキャラの性能==武器の性能になっていく。
本編だけではどう考えても敵の成長速度に味方の成長速度が追いつけないので、
延々とランダムダンジョンに潜ってキャラと武器を育成する単調作業を繰り返す必要がある。
大失敗ダンジョンや大失敗合成など、ゲームバランスを破綻させるような卑怯くさい要素がいくつかある。
いや、これがないと隠しボスの連中には勝てそうに無いのでこれはこれでいいのかもしんない。
最後の方は能力値がインフレ状態になって一撃で数十万ダメージ食らわせたり食らったりする。
などなど…)
このゲームの面白みは、戦闘よりもキャラと武器の育成にあるように感じられる。
(あとは異様に派手な技の演出を楽しむところとか)
シミュレーションRPGというよりはアクションRPGに分類した方がいいような気がする。
コンファインとリムーブは面白い要素なので、突き詰めればもっと戦闘が面白くなりそうだけど、
このゲームでこれ以上一回の戦闘の密度を濃くしたらランダムダンジョンに潜るのはかなりダレそうなので、
このくらいがちょうどいいのかもしれない。ちょっと勿体無い気はするけど。
こんな時なのでhlの今後の予定とか妄想とかを書き連ねてみる。
・ゲームとしての方向性とか
とにかく敵を撃って破壊して、派手で爽快なゲームにしたいと考えている。
あまり弾幕は無い…というより、ほぼ全てのキャラクターをLuaで制御する関係上、
あまり大量にキャラを出すわけにはいかず、弾幕を張ることも叶わないわけで、
その分敵キャラを出しまくって破壊してもらう方向で。
自機がワープするのが最大の特徴なので、
ゲームの内容もそれに合わせて高次面に行くほどワープを強要する内容にする。
地形でがんじがらめにして、敵が遠慮なくレーザー撃ちまくってくるとか、
敵が突進してくるとか、地形が迫ってくるとか。
うーん、他にワープを活かす方法は無いもんか…。
・自機
ホーミング+全方位攻撃+ワープは現状維持。
ボムも入れたいところ。
残機制ではなくライフ制で。パワーアップはレベルアップで。
スコア=経験値なので稼ぎは重要な要素になるわけだけど、今のところ考えてるのは、
敵速攻破壊で早回しが出る
誘爆で倍率がかかる
敵の攻撃に自機を掠めることによって掠り点が入る
難度によってスコアの加算方式が変わる
(高難度になるほど敵のスコアが減り、代わりに敵の攻撃は激しくなって掠り点が上がる、とか)
くらい。いいアイディアが浮かび次第追加。
視点に依存しない操作性を実現する。
例えば横から見た状態でも上キー押したら画面上方に移動するようにする。
カメラの移動はタイムラインで固定で、リプレイのときだけ自由に変更可能…と考えているけど、
プレイ中も自由に変更可能にしない?という要望を受けて揺らいでいる現在。
・他
ネットワークを通じた2Play
旧作(歌鶫)にもあったアレ、おまけ要素的に入れたい。
シューティングも友人と共同プレイができたらまた違った楽しさがあると思うんだけど、どうだろう。
まあ1秒に60回通信ともなるとLAN、またはADSLクラス以上の通信速度+物理的に近い者同士じゃないと
まともな速度は出ないけど…。
タイトルとかストーリーとかは考えているけど、
ゲームそのものには影響しない要素なので優先順位は低。
現在Linux環境だとたまーにseg. faultすることが発覚。
WindowsNT系はメモリ回りのエラーに甘いらしいので、そちらでは表面化してないのかもしれない。
ホーミングレーザーの敵をサーチする時の挙動がどうも怪しい。要調査。
そういえば、
東方シリーズは組み込み言語としてRubyを使ってるという噂を約2箇所で見かけたんだけど、ほんまかいな?
RubyってGPLだよなぁ…?
これ以上休むと進級できないらしいっつうか、
今現在でも十分進級が危ういらしいので、やむなく学校に通うことに。
いやそれが当然なんだけども…。
授業のメインはMayaとかPhotoshopとかのソフトのオペレーティングだし、
プログラムの授業はCでソフトウェアレンダラを書いたり
Gtk+OpenGLでツールを作ったりする内容なんだけど、言語自体は最小限しか教えないので、
未だに構造体がどうのポインタがどうのリスト構造がどうのってレベル。
なもんだから学校行っても行かなくてもあまり変わりは無い気がするし
実際有名企業に就職した先輩方はやはり独学で技術を身に付けて行ったらしいし、
むしろ学校は足枷になってるんじゃないかと思えてきて、
それなら俺は一体何のために学校行ってるんだろうっつうかいっそやめた方が身のためか?とか思うけど、
多分他の学校でも状況はあまり変わらんのだろうから、
耐え忍ぶ以外道は無いんだろうかなぁとか悩みながら仕方なく学校に行く日々なわけで。
んでもこの学校に行かなかったらプログラムに目覚めることは無かっただろうから、
きっかけを与えてくれた点に関してはとても感謝している。
入学当初はデザイナを目指してたような気がするんだけど、遥か遠ーい過去のことように思える今現在。
2004/1
てわけで、
即席タイムラインエディタ。
ゲーム本体との連携もつつがなく完了。
しかしこれだけじゃやはり使いにくい。
3Dソフトにあるアニメーション編集機能みたいに、
タイムスライダを動かしてオブジェクトを動かしてキーを打つ、的な機能が欲しい。
けどまあ、今回の目的は果たせた。
VCでSDLを使うときは、自分で-MTオプションつけてビルドすれば
dllの混乱は起きないことを確認。
ついでなのでSDL-1.2.6をVC7.1で-MTオプションでリリースビルドしたものも
公開。
何で公式で配布されてるのはあんな使いにくいんだ。
スクリプトで敵のモーション全てを記述するのは、作業量の面でも実行効率の面でも非効率的。
なので、3Dソフトでよくあるタイムライン方式を取り入れようとしている。
キーフレーム間のアニメーションの補間はいわゆるベジエ曲線と呼ばれる3次曲線で行う。
ベジエ曲線はお馴染み
t-potの
この項目を参考にというか丸写しにしながら実装。
ただ、ベジエ曲線からxを与えてyを解く方法が分からなかったので、
これはあらかじめ曲線をサンプリングして配列に詰めておき、xに最寄の両点を線形補間してyを求めるようにして実装。
なんとも頭悪いアルゴリズムだけど、望む結果になってるから今は気にしない。
ポイントの位置を手書きしていくのはこれまた非効率的なので、モーションエディタを作成することになる。
今は諸々の事情により急いで作らないといけないので、SDLでガリガリと作成中。
時間があるときにWTLかwxWindowsあたりを使ってちゃんとしたGUIソフトにしたいところ。
3Dソフトから直接書き出すことができればそれが一番早いんだけど…。
モーションデータの保存形式はLuaにする予定だ。
この程度のものにXMLを使うのは大げさすぎるし、独自フォーマットをパースするのもめんどくさい。
例えば上の図の赤いラインは以下のような記述。
timeline_begin()
timeline_point(vector2.new(10, 190), vector2.new(10, 190), vector2.new(200, 200))
timeline_point(vector2.new(350, 0), vector2.new(200, 0), vector2.new(350, 0))
timeline_point(vector2.new(490, 100))
timeline_end()
フィルタを実装してみる。
(画面全体に及ぶエフェクトの正式名称がわからんので勝手にフィルタと呼ぶ。ガルーダの覚聖時に背景が歪むやつとか)
OpenGLはの2Dの処理(glDrawPixels()とか)が非常に遅いらしいので、こういうエフェクトも3Dで処理することになる。
具体的にはglTexImage2D()でバックバッファ、もしくはフロントバッファの内容をテクスチャ化し、
それをポリゴンに貼り付けて描く。
テクスチャは2のn乗の大きさじゃないといけないので、640*480の場合は1024*1024のテクスチャにしないといけない。
こんな大規模なコピーを毎フレームやったら相当遅くなりそうに思ったけど、
少なくともGeForce2GTSな環境下ではそこまで極端な速度低下は見られなかったので安心。
つうか現在一番時間食われてるのはダントツで衝突判定の部分らしく。
上は試しにやってみた摘みフィルタ。頂点を一箇所に集めているだけ。
今までオブジェクトの管理は敵リストとか弾リストとか種別ごとにlistコンテナを作ってやっていたのを、
一つのmapコンテナでやるように変更。
オブジェクトにはIDをつけ、それをmapのキーにする。
オブジェクトへのアクセスはこのIDを通じて行う。
この変更に伴い、描画の処理も変更。
今までは種別ごとにまとめて描画するとゆーいい加減な実装だったのだ。
オブジェクトに描画の優先順位のパラメータをつけ、
描画する時はオブジェクトを描画用コンテナに詰めて優先順位でソートし、順番に描いていくようにする。
バックバッファを使うフィルタはいつバッファをテクスチャ化するかが問題になってくるわけだけど、
この変更で制御が容易になった。
WA:F、クリア、リボン返すイベントもクリア。
スーパーグロウアップルに18連ガトリングぶちかましまくって現在Lv90だけど、これでも勝てない隠しボス達。
ルシファアあんなヘボそうな見た目なのになんであんなに強いんじゃー。
つうか属性耐性系スキルでガチガチに固めていかんと無理っすか?
WA:Fな日々。
ようやくラストダンジョン到達。レベル62、プレイ時間60時間超。
あーもう、無駄に時間かかりすぎ。だんだん我慢できなくなってきた。ダレる。
リメイクというより改悪になってるような気がする。というより俺の期待が大きすぎたのだろーか。
もはや隠しダンジョンや隠しボスまで全部攻略する精神的余裕は無さげ。
エルミナにリボン返すイベント見てクリアしたら売っぱらうか…。
俺にはRPGは普通にやってたら30時間くらいで終わるくらいの長さ(と、それ相応の密度)が丁度いいようだ…。
16bit色深度環境下でも本来の速度が出るように修正。
今後やるべきことは、オブジェクトの管理をもちっとスマートに、スクリプトの機能強化、音鳴らす、あたりか。
音鳴らすのにはDirectXのDirectAudioを使おうと考えて始めている。
OpenGL使ってるのにDirectX必要ってなんかマヌケな気もするけど…、Windows以外ではSDL_mixerを使う方向で。
そういえば現在エンディアンを全く考慮していない。
元々WindowsとLinuxで動かすことしか考えてないんだけど、
エンディアン考慮しとけばそれ以外の環境でも動くようになるだろうから一応やっておくべきか。
エンディアンが問題になるのはファイルの読み書きとネットワーク越しにデータ送る時だけ…でいいんだっけ…?
WA:F、復興資金集めとガーデニングばっかりやりながら40Lv到達。
しかしこのゲーム、キャラの動きが直線的というか角張ってるというか、
キーフレーム間の補間を全部線形補間でやってそうな不自然さを感じる。
キャラの動き次第で退屈な戦闘ももっとテンポ良く見せられそうなのに…。
OpenGLを初期化するとき、画面の色深度と違う色深度を与えると極端に遅くなる。
んで現在のhlは問答無用で24bitで初期化するので、16bitの色深度の環境では極端に遅くなってしまうようだ。
そういえばそのうち環境に合わせて初期化するようにしようと思いつつ、ずっとほったらかしにしてた気がしなくも無い。
ウィンドウモードでゲームするために常時16bit色深度な人は多いと思われるので対応しとかないと…。
遂にPS2とワイルドアームズを購入し、延々とプレイ中。
現在フォトスフィアを叩き落したところで、プレイ時間は25時間ほど。
…こんなに時間かかるゲームだったっけ?
敵の出現率えらく高くてENCゲージ一瞬で尽きるし、
その割に戦闘はテンポ悪いし、ロードも遅い(気がする)し、必要以上に時間食われてる感が。
まあやってるうちに慣れてきたからいいものの…。
そうそう、リボンの持ち主の名前はエルミナだった。
爆発が地味で物足りない。
だけど単純に爆風オブジェクトを増やすのは負担が大きい。
んじゃビルボード1枚でレンズフレアを加えてみたらどうか?
というわけで爆発時に光らせてみたら、これが思いのほか綺麗。
綺麗なもんだから必要以上にでかく長く光らせようと変更を加えていくうちに、
爆風に攻撃判定つけて誘爆させてみたらどうだろうなどと考え出したりして、調子に乗って光らせまくった結果が上。
実際に動いてる時は綺麗に見えるんだけど…飽和しすぎ。
今回の成果
WinAPI直叩きの演奏機能が難航中。
単体で鳴らすのは何の問題も無いけど、複数の音を混ぜる(同時に鳴らす)時に必要な処理はかなり複雑らしく。
各音データを細かく切り刻んで空いてるバッファに流し込んでwaveOutWrite()してスレッドを同期して…とか、
そういう流れになるんだろうか?
つうか資料が少ないのが最大の問題。
もうこの辺に深く突っ込むのは後回しにして、今は素直に外部ライブラリ使った方がいい気がしてきた…。
あと10日の雑記の「音はただ鳴らしただでは演奏が終わるまでそこで処理が止まってしまうので」の記述は間違い。
waveOutWrite()してもさっさと次の処理に移動しつつ音は鳴るようだ。
中学高校時代の元クラスメイトで現在東京在住の連中による、
成人式兼同窓会みたいな集まりがあり、半ば飛び入りで参加してきた。
俺の通っていたところは中高一貫で、一学年が40人程度で一クラスというちょっと変わった学校である。
俺は高1で中退してるので、学校でしか会ってなかったヤツとは4年ぶりの対面。
懐かしくてちょっと感動してしまった。
みんな外見はあんま変わってないけど、言動が大人っぽくなっててちょっと焦る。
というか俺がだんだん世間離れしてきている気がしてきた…。
誤ってキーボードに烏龍茶のボトルを倒してしまったらそのキーボードはイカれてしまったようで、
sを打ったらsaになったり、yを打ったらyと出力された後カーソルが左に移動し続けたり、
色々おかしな挙動をするようになってしまった。
急遽代わりのキーボードを購入。今回はテンキー無しの小さめのを。
しかしキーボードって意外とデリケートなのね…。
ロックオンを実装し、ホーミングはロックオンしてからじゃないと撃てないように変更。
ロックオンのアルゴリズムは、
ロックオンサイトを作って、カメラ-ロックオンサイトの二点を通る直線と衝突した敵をロック…するようにしようと思ってたけど、
これ以上操作を複雑にしたくないので、敵リストを自機との距離でソートして自動的に近くの敵からロックオンしていくように。
全方位に方向変更可能なメインウェポン+ホーミングするサブウェポン+ワープという初期から考えてた自機の挙動は
一応実現されたことになるんだが…、グネグネレーザー(仮称)はこのまま使っちまうか?
詳細な仕様を早めに決めなあかんね。
それと、連休中に友人の熱心な要望によりBGMと効果音をつけた。
つうか要望を出してくるほど興味を示してくれる友人は貴重だ。嬉しい。
んでその時はSDL_mixerを使って実現していたのを、現在WinAPI直叩きで実現するように変更中。
msvcrt.dllを使うように自分でコンパイルすれば
dllの混乱は起きないらしいという話を聞いた気がするので
わざわざそんなことする必要もない気がするけど、まあ勉強のため。
しかしSDL_mixer、
ここを参考に使ってみたんだけど、すごい手軽さだ。
ファイルからの読み込みも演奏も、これ以上簡単にしようがないってくらい簡単。素晴らすぃ。
音はただ鳴らしただでは演奏が終わるまでそこで処理が止まってしまうので、
それ用にスレッドを作ってそっちでやらないといけないようだ。
具体的な鳴らし方やスレッドの作り方は、おなじみ
Win32 API入門
を漁りながら実装中。
BGMにはoggを使う予定だ。
実家から帰還。
とっくに明けてますがおめでとうございます。
去年は色々消化不良だったので、今年はもっと進歩がある年にしたいところ。