「パネルγ」に関する日記(6)

<前 次>

不条理な灰色

基本得点とBGM実装。
ただし基本得点には連鎖による倍率掛けはなし。基本得点は基本得点のままです。
DirectMusicを使ってみたのですけれども、ゲームとの同期が取れなくていろいろ手間取りました。
消しBGMがコンボ終了後も鳴り終わらなかったり、コンボが終わった後に無音になったり…
先日言っていたチャンネルの問題は、実際起こり、消しBGMの楽器で次のBGMが鳴らされたりもしたので、チャンネルを完全に分けました。
コンボ精算のときの音をどうやって分けるかというのと、消しBGMの同時消しに反応する部分をどうやって実現するかということを現在研究中です。
ところで、適当にプレイしながら思ったのですが、これ、何も考えずにパネルを出しまくって消しまくっていたら勝手にどんどん最小単位の4つパネルの四角形ができて得点がたまっていくんですよね。しかもかなりのスピードで。
これでは、運を天に任せてひたすらパネルを流していくゲームになりかねません。
そんなゲームバランスのないゲームなんか、自分で作って自分で遊べばいいのです。人様に見せるような代物ではありません!(そういうことで、私のパソコンにはバランスも糞もないくだらないゲームがたくさん埋もれています)
だから、まだ途中ですが、ゲームバランスを考えるためテストしてみました。
4つ消しのみを狙い、ひたすら出して消し、まぐれ当たりを狙ったら10000フレームで1020点。
9つ消しを狙い、適当に出しつつ入れ替えで消していったら、まぐれ当たりも含めて1270点。
かろうじて9つ消しのほうが高得点ですが、あまり割に合いません。
だからといって4つ消しの得点を下げすぎると4つ消しが「ハズレ」になってしまいます。
4つ消しの価値はそれなりに残しつつ、狙うならまぐれ当たりよりももっと大きく、という方向に持っていけるゲームバランス(例えば、4つ消しを連鎖数稼ぎに使い、数がたまったところで大きな塊を作れるようにして更なる高得点を目指すとか)にしたいものです。
ちなみに、灰色パネルというのがたまに出てきまして、これは普通の方法では消えてくれません。
で、特殊なパターンに揃えて消すわけですが、これがまた、完全に消せるパターンだと難易度の割りにやけくそに得点が低く、それなりの得点が入るものは8個消えて1個発生という、実にプレイヤー泣かせの消え方をしてくれます。

ミュージック

MIDIどうすべきか考えていたりするのであります。
リアルタイム性が必須の消しBGMは通常BGMとチャンネル分けるべきかもしれないと思っていたりするのであります。
なぜなら、パラメータ変更に手間取っていたらピアノ化したり前に使っていたりした楽器が勝手に使われたりして困るかもしれないと思っていたりしたからなのであります。
ともかくMIDIを再生できないことにはどうにもならないのでリソースからMIDIを読む処理を作ることにしていた次第であります。
ヘルプのチュートリアルには記述が見当たらなかったのでプラットフォームSDKのヘルプと照らし合わせながら作っていたりするのであります!

ウィンドウ

パネルγでやったことと同じことをPRG±0でも。
ウィンドウをクリップしてウィンドウモードでウィンドウを動かしてもウィンドウの位置に合わせた位置に正しくウィンドウ内に収まるようにウィンドウにウィンドウの内容を表示できるようになりました。
さらに保存してあるデータのタイトル画面を表示できるようにもしてみたかったんだけど面倒だったんで後回し。

パネルγの動作チェックも。
空中で素早くパネルを揃えることにより脅威の空中消しが!
例によって得点は変わりませんが。

コンボまで実装。基本得点と連鎖得点はなし

「パネルγ」のノーマルゲームのコアの部分を作りました。
まず、パネルの生成。
イレカエモードで(といってもまだこれだけなんですが)、何もないところをマウスでごしごしするとパネルがだーっと降ってきます。
で、逆にパネルがあるところを右クリックでがしがしやるとパネルがざーっと消えます。
正直言うとパネルを直接消す機能はいらないと思ったのですが、実際に操作した感覚ではパネル入れ替えは想像以上に神経を使う細かい作業なので、通常時はともかくピンチのときはとっさにパネルを退避できそうにないので、一時しのぎに使えるようにパネルを直接消す方法を用意しました。
で、次がパネル消し。
アルゴリズムは作り始める前から考えていたので一日で作った割にはまあまあ。
得点加算のところの演出までできたので結構満足。
現状のゲーム画面をアップしておきました。

理不尽なエラーが多すぎる

学校のActiveBasicで、行単位でデータが格納されたファイルを整理する「LineConstructor」を作っていたのですが、メニューを作成すると謎のエラーが出てコンパイルが通らなくなるという事態が発生。
もちろんエラーの原因を究明しようと思ったのですが、ヘルプにも公式サイトにもエラーの解説はなく、該当するエラーをクリックしても存在しないFドライブのファイルを参照してデバッグも糞もない状態。
一応それらしきファイルを探してきて覗いては見たのですが、エラーの原因となっている部分と関係のありそうなところは確認できず。
VS.NETがだめ、JBuilderもだめ、ActiveBasicもだめとなればもう残りはさっぱりわからないDelphiのみ。
こりゃ学校じゃプログラミングはできそうもありません。

「パネルγ」のマウスクリック感知の部分を作って、タイトルを動かせるようにできました。
まずは終了処理を作成。
ウィンドウを直接閉じると強制終了がかかってデータが破損する可能性があったので正規の終了方法を用意ということで。
これでゲームメインへのシーン移動もできるようになったのでこれからはメインのほうを集中的に作っていこうと思います。

Lunascape2!

Lunascape2入れてみました。
使ってみた印象は、Luna2でできていたことができなくなっていたり、よくわからない機能が説明もなしにたくさん付いていたりで、かなり使いにくいという印象でした。
大部分は慣れで解決するのでしょうけれども、慣れではどうしようもない不具合などはできればつぶしていってほしいものです。
そのいくつかは既に報告があったようで。
まだまだ安定版には程遠いようですなぁ。

「パネルγ」のタイトル画面を作りました。
ゲーム名はまだ表示されませんが、ゲームメニューがずらっと表示されます。
背景とメニューの文字の明度が近いので見づらかったのですが、マウスカーソルを合わせると背景色を明るくして見やすくなるように調整しました。
今回アップしたスクリーンショットではプレス機が表示されていなかったりしますが、実際の今の状況だとプレス機が表示されていますし、パネルの並び方も若干異なり、メニューの位置も変わっています。
まだマウスボタンの押下を検出することができないのでメニューを押すことはできません。

「Bomber丸World」のページを更新しました。
主人公の社会での扱われ方がわかっちゃいます。

あっ、そろそろ更新する時期だなぁ。

マウス

考えてもみればパネルγはマウス操作だったんですよ!
というわけでマウスカーソルのソフト表示に対応。
画像転送の部分も改良。
一部がはみ出すような場所にも表示できるようになりました。
さて、気になるのがBGMに使うDirectMusic。
IDirectMusicPerformance8::PlaySegmentExでi64StartTimeを0にして実行するとできるだけ早く演奏が開始されるらしいけど、この遅延時間が60msを超えると使っている音楽の性質上異常演奏になってしまうのです。
できるだけ早く、だから結果が不定になるのなら、あえて開始時間を設定して開始時間のほうに遅延時間を吸収してしまうとか…

しーーー~~ん…

パネルγ、ハイスコア記録をどうするか思案中。
文字列の表示は結構遅いようなので(おそらくフォントから画像を計算で作成しているため)、また、画像主体のところへWindowsのテキストボックスを表示するのはあまりよくなさそうな気がするので、使える文字を英数字に限定してフォントをビットマップの形で使おうかと思っています。
そういうことなので善は急げということでMSゴシックのフォントで画像を作成。
プログラム的なところでは、シーン管理クラスを作って、タイトルシーン(ただし真っ白な画面が表示されるだけ)を作りました。
このシーン管理クラスの特長は、シーンが増えても管理しやすく、次のシーンへの切り替えのときにパラメータなどを詳細に指定することができることなどですが、短所として、ウィンドウを閉じて終了するとシーンでの処理がその瞬間に強制終了されるため何が起こるかわからないということなどがあります。
タイトルメニューの仕様も考えてみたり。
「ふにゃふにゃ」と同じく、項目を上下に並べ、左右キーでその子項目を動かせるようにしようかと思っています。

くぁwせdrftgyふじこlp;@:「」

パネルγのページ更新しましたよ。
ルールにパネル発生メカニズムとプレス機の恐怖を。

あんまり遊べなかった…

いろいろできそうに見えて案外面倒な設定が必要だったり結果が結構地味だったりして、画像ほど際立った効果は実感できませんでした。
さりげなく使って陰で雰囲気を盛り上げるような使い方なのかなと思ったりします。

パネルγのタイトルBGMを作りました。
パネルを消したときの音とゲームのメイン音楽との組み合わせです。

画像表示

画像表示ができるようになりましたよ。
画像読み込みがDirectDrawに入ってないのって納得いかない!
でもないもんはないから自前で。というかサンプルからコピー。
VBのDirectDrawにはあるんですけどね。
ウィンドウモードはメインにするつもりはないけどデバッグやウィンドウで使いたい人のために一応対応。
そのためにいろいろ面倒なことがあって。
ウィンドウモードで正しく表示するためにはクリッパーを仕掛ければよいということで、使ってみたら、使ってないときよりはマシだけど、描画位置そのものはディスプレイ画面の左上だからウィンドウ内に正しく表示されない。
他のサンプルではどうしているのかと思えばただ単に正しい位置に描画されるように位置を補正しているだけ。
それに倣ってこっちも補正を加えるようにしました。
これからはもっと開発スピードが上がりそうです。

ぴかーん!

履いていた靴があまりにもボロだったので新しい靴を買いました。
試し履きせずに買ってしまったのですがピッタリだったようで安心しました。

「パネルγ」のプレス機の絵を描きました。
金属光沢がよくわからなかったのですが…まあまあ妥協しておくことにします。
しかし256色パレットを使っているのにまだ16色パレットにある色しか使ってない…色を使うために絵があるわけじゃないけど、気になるところではあります。

忘れてた!今は冬なんだった!!

パネルγの色パレットの設定を作りました。
ウィンドウモードでパレットが指定できないのは多分サーフェスがパレットモードじゃないから。
となれば正式版ではフルスクリーンモードだけにするか…?
それともウィンドウモードではパレットアニメーションを使わないことにするか…?
いっそのこと3Dをもう一度やり直すか…?
実際に使ってみたら良い点悪い点がよくわかりますのー。

12月も終わりというこのころになってやっと「冬の寒さ」がやってきて、思い出したように雪が降り出しました。
昨日までの寒さは秋の肌寒さ。
雪は地面で速やかに融けてしまいましたが。

最近キリ番とかにあまりこだわらなくなってきたのでカウンターの文字の大きさを普通の大きさで統一するようにしました。
以前のように大きさが変わるバージョンがいいという人がいたら戻しますが。

完成予想図

まずはウェイト処理。
フレームスキップはせず、必ず1msは休むという動作にしたので遅れるときは普通に遅れます。
毎フレーム実行したフレーム数と最小待ち時間(1ms未満だと遅い)を記録しているのでそれが重さの指標になりそうです。
あと、スクリーンショットを更新しました。
本当のスクリーンショットではなくこういうふうにできればいいなという完成予想図なんですが。
あ、DrawBaseの派生クラスとしてGDIによる描画を作ってみてもいいかも。

パネルγの実行速度一定化について

さて、処理落ちが起こるとゲームのテンポが変わってしまい、ランキングを開催したいと思っていることもあって、公正さに欠けるのは致命的だと思うので、最も時間のかかると思われる描画処理について考えていました。

1.普通に描画する。
とにかく簡単。
でもマシンの性能によっては普通に処理落ちします。
2.遅れていたらフレームスキップする。
例えば2フレームの時間で描画していたら、ゲーム処理→描画→ゲーム処理→フレームスキップ→ゲーム処理、となって、2フレームの時間が経過した跡に瞬時に2フレーム分の処理が行われ、これはこれで公正さが失われます。
3.描画命令をキューに入れて後でまとめて実行する。
「後で実行」を別スレッドで管理すれば描画でもたついている間にも裏ではゲームが普通のスピードで進んでいるため実質的な公正さは保たれるはずです。
ただし、「キューに入れる」とという作業が余計に加わるので全体的な速度そのものはかえって遅くなりますし、メモリ使用量もキューの分だけ増えます。
とりあえず2は前に試してえらい目にあったので却下ということで、1か3になるのですが、とりあえず今のところは1の方式を実装して、様子を見てから3に切り替えるかどうかを判断しようと思っています。

バックバッファ

プライマリサーフェスを作ってました。
フルスクリーンとウィンドウモードで扱いが違うから少し厄介です。
もしかしたらパネルγ、かわいい女の子は別として、何か別のキャラクターが出てくるかもしれません。
今のところはまだ可能性の段階ですが。

さらにBGM

変更。
空のクラス→クラスそのものを作らない。
そうでもしないと純粋仮想クラスのメンバとやらがまずいんじゃないかなと思って。
で、例のDirectDraw、早速実装してみました。
さて、ウィンドウモードとフルスクリーンモードでは画面の反映の仕方が違うそうだけど、どうなるか。
なんとなくBGMのパターンを増やしてみたり。
神秘的かもしれないイメージで作ってみたけど、だけど神秘のカケラもないこのゲーム、どうなることやら。
低い点数のときは暗い曲調なのです。

しかもMazeCube

練習用としてはMazeCubeを作ることにしました。
MazeSquareの3D版っぽい位置付けだけどこっちは完成したら一般公開します。
とはいえルールすら決まってなくて、完成するかどうかすら怪しいものですが…
ギヤバネくんが歩き回るゲームになるような気がしないでもない。
DirectX AppWizard使用。

で、めでたく本番用になったパネルγ、DirectDrawを使えるようにするため、Direct3DとDirectDrawを切り替えやすいようにしていました。
Direct3D使用時はDirectDrawクラスが空のクラスになり、DirectDraw使用時にはDirect3Dが空のクラスになって使わないことになります。
どちらでも同じ感覚で使えるように基底クラスとしてCDrawBaseを作って、その派生クラスとしてCDirectDrawとCDirect3Dを作っています。

そしてDirectX7

「パネルγ」、DirectX8を使うということで何も考えずDirectXGraphicsを使っていたのですが、今更言うまでもなくこのゲームはバリバリの2Dゲーム。
Direct3Dが得意とする回転拡大縮小やらアルファブレンディングやら、ましてや頂点シェーダやらピクセルシェーダなんかとはまったく無縁のシロモノ。
アルファブレンディングだけはパネルが消えるエフェクトに使えそうですが、使うのはどちらかというとひたすら矩形転送というDirectDrawが大得意とする分野がメインなのでそっち使ったほうがよさそうな気がします。
ついでに言うと、効果音はMEを使う可能性があるので、DirectXAudioのDirectSoundとDirectMusicとの統合があんまり意味を成さず、DirextX6.1のDirectMusicで充分そうな気もして、そうなるとグラフィック7、サウンド6.1となり、DirectX8を使う意義がなくなったよう感じます。
さて、問題はコンパイルが通るかどうか…

ミラクル!

パネルγのページを更新しました。
一番基本的なルールが説明されています。
一応プロトタイプにスクリーンショット機能をつけて撮った写真を加工したものを使っています。
パネルの柄をもっとパネルっぽく平面らしく作ってみたのですがどうもしっくりこなかったので元の柄に戻しました。
一番最初はガラス玉みたいなので、プレスに押されるとひびが入るというのにしようかと思っていたのですが今の画力では描けそうになかったので諦めました。
今まで明かした要素の中で、連鎖・コンボ・同時消し・アクティブコンボ(連鎖)などがあったのですが、今回紹介しますのは、これぞミラクル!空中連鎖でございます。
必要最低条件として、先に22個以上の同時消しをしなければならない秘術で、得点は普通の連鎖となんら変わりません。
ただ単に連鎖のタイミングでパネルが落ちていたらそうなることがあるというだけで、狙ってやるほどの価値はありません。
さて、ウィンドウモードでのプレイではマウスの移動位置を制限する必要があるのですが、ウィンドウモードといえばタスクの切り替えができなければならないということで、そのときにはポーズをかけるのだけれども、どんなタイミングでもポーズをかけていいというわけではないので、その辺の兼ね合いをどうするかが問題となりそうです。

あ、トゥーンレンダリングも更新。

<前 次>