- 作品名:
- 「Digitalian War!! づゅる づゅる ぷぅあ」
- 作者名:
- はりまお
- 製作開始日:
- 2006年08月24日
- 制作完了日:
- 2009年07月06日
- 制作環境:
- Pentium 4(2.60GHz) + 1GB RAM
- WindowsXP Home Edition SP3 + Visual Basic 2008 Express Edition
- 動作環境:
- 要 Microsoft .NET Framework 3.5
- 要 ホイール付き2ボタン以上のマウス
今回は、カップラーメンを作って食べて捨てる速さを競うゲームです。必要な作業を“覚えて”“ミスなく”“無駄なく”こなす、完全なる『覚えゲー』です。
特別なインストール作業はありません。お好きなフォルダの中に、このソフトの全ファイルを置いてください。
アンインストールする時は、フォルダごと全てのファイルを削除してください。
レジストリを変更したり、実行ファイルがあるフォルダ以外の場所にファイルを生成したりといったことは、一切行っていません。
"raumen.exe"をダブルクリックすれば起動します。画面(ウィンドウ内のゲーム内容が描かれている部分)をクリックするか、しばらく待っていると、タイトル画面が表示されます。
タイトル画面で左クリックするとゲームが始まり、右クリックで終了することができます。
ゲーム中ESCキーを押せば、タイトルに戻り、タイトル画面でESCキーを押せば、終了することができます。もちろん、ウィンドウ右上の×ボタンでも終了できます。
ゲーム中の操作は、全てマウスで行います。マウスには、左右2つのボタンとホイールが必要です(要するに、Windows用の標準的なマウスであれば問題ありません)。
これから説明する「カップ麺の食し方」は、文章ではとても複雑に見えますが、なるべく現実の動作を連想するような感じにしましたので、分かってしまえば簡単だと思います。
ゲームを始めて最初にやることは、画面の中央にカップ麺を持ってくることです。
テーブルの右端に少し見えているカップ麺を左ボタンを押して掴み、そのまま画面中央へ持ってきてボタンを放せばOkです。
カップを所定位置に置けばポットが下りてきます。
ポットは、胴体部分にある2つの窓で操作します。左側がお湯の量を表す“湯量ゲージ”、右側はお湯を出すための圧力を表す“圧力ゲージ”です。
まず、湯量ゲージにマウスカーソルを合わせ、左右のボタンを交互に押すと、お湯が溜まっていきます。このとき、ボタンを長く押し続けると逆にお湯が減ってしまうので、タイミング良く左右のボタンを切り替えてください。
次に、圧力ゲージにマウスカーソルを合わせてホイールを回し圧力を掛け、お湯を注ぎます。ホイールを↓方向に回せば加圧し、↑方向に回せば減圧します。カップに必要な量が注がれると、湯気が立ち昇ります。必要量の目安は、カップの側面が傾斜から垂直に変わるところです。
ポットのお湯がなくなった場合は、湯量ゲージでまた溜めてください。湯量ゲージの高さ1ドット分で、カップに高さ1ドット分のお湯を注ぐことができます。
お湯を注ぎ終わったら、ポットのハンドルの付け根の円形部分の内側で左ボタンを押して掴み、画面の上へはみ出るまで移動し、ボタンを放して片付けます。
ポットが片付いたら、上から3分間タイマーが降りてきます。3分間と言っても、現実世界の3分ではありません。
文字盤の下にある“振り子”を左ボタンを押して掴み、左右方向のどちらかにあるレールに沿わせて持ち上げます。ボタンを放すと、真下まで振り子が戻り、それに伴って長針も動きます。マウスカーソルが、振り子から外れてしまってもボタンを放したのと同じになります。
振り子が、真下に戻るとレールが回転し、振り子を降る向きが反転します。
この作業を、文字盤中央の数字(短針)“3”分になるまで繰り返してください。
3分経過したら、タイマーを片付けます。文字盤中央の数字が表示されている部分にマウスカーソルを合わせて左ボタンを押し、画面上方にはみ出るようにしてボタンを放してください。
タイマーが片付いたら、口が現れます。
口の周りには、白,緑色,水色の円があります。歯の周りにある小さい白い円と一番外側にある白い円に挟まれた部分を、口ゲージと呼びます。
ここでの基本的な流れは、以下の通りです。
カップラーメンの茶色い部分はスープ(麺の残量)を表し、マウスカーソルをスープの中に入れて左ボタンを押すと麺を掴みます。このとき、深い程多くの麺を掴むことができるようになっています。なるとは、スープから見えていれば、そこで左ボタンを押せば掴めます。(1)
麺は、大変熱くなっていてそのままでは食べられません。そこで、左側に出現する温度計を見ながら適温になるまで麺を上下させて温度を下げます。(2)
そして、麺の上端(お箸で掴んでいるところ)を口の中(上の歯と下の歯の間)にまで持っていき左ボタンを放せば麺をくわえた状態になります。しかし、そのまま放っておくと、麺はずり落ちてカップに戻ってしまいます。なるとの場合は、口の中で放せば食べます。(3)
麺を銜えたら、すかさず口ゲージの中へマウスカーソルを持っていき、時計回りにグルグル廻すと麺をすすることができます。グルグルするときのマウスカーソルが、口ゲージの外周部に近いほど、勢い良く吸い込むことができます。(4)
また、麺をくわえた状態で口の中をクリックすると噛み切ることができます。(5)
このとき注意しなければいけないのが、水色と緑色の円です。
緑の円は、口の中に入っている麺やなるとの量を表しています。これが一杯になっていると、それ以上食べることはできません。そのときは、口の中をクリックして飲み込んでください。(6)
水色の円は、肺の中の空気の量を表しており、吸っていると外へ広がり、吐いていると内側へ縮みます。ラーメンを食べている人も呼吸をしているので、空気を吸っているときに合わせて麺をすする必要があります。肺が一杯になったら、麺をすすることはできませんので噛み切って、口ゲージを反時計回りにグルグルして空気を吐いてください。(7)
(1)〜(7)を臨機応変に組み合わせて、なるべく早く食べ終わることを目指します。
ラーメンを食べ終わったら、カップを捨てなければいけません。
画面には写っていませんが、テーブルの左下にゴミ箱があります。カップを捨てるには、カップの中の何も無い部分にマウスカーソルを持っていき左ボタンを押して掴み、ゴミ箱の上へ移動させてボタンを放します。
カップが、画面下に落ちて、ゲーム終了となり結果発表画面が表示されます。
ちなみに、食べ残しがあっても捨てることができます。その場合は、ペナルティーがありますので、自分で良い頃合だというところで捨ててください。
食べるのに掛かった時間に、各ペナルティーを加算したものを、最終的なタイムとします。
ペナルティーには、大きく分けて“残飯ペナルティー”と“行儀ペナルティー”があります。“残飯ペナルティー”とは、カップを捨てたときに残っていた麺やなるとの量で、“行儀ペナルティー”とは、口の中に残っている量やこぼしたお湯の量で、加算される時間が決められます。
次に挙げる項目のいずれかを犯してしまうと、ゲームオーバーになってしまいます。
特別なことはしていませんが、プログラムが汚くて難解なものになってしまいました。変数の説明等は、プログラム中に記述していますので参考にしてください。
特に、麺を“カップ”←→“空中”←→“口”の各間をお箸や呼吸を介して移動させるところが意外と面倒で、見にくい(醜い)プログラムになっていると思います。
今作が要求するPCのスペックについては、実際に動かして確認してください。ゲーム中右下に表示されるフレームレートが、だいたい30fps前後を示していたら問題ありません。近年のPCでは、ほぼ有り得ないことですが、もし著しく低下するようであれば、そのPCにとって荷が重いということになります。
一応、ゲーム内の各パーツごとにクラス分けして、プログラミングしてみました。
また、それぞれのパーツがゲーム内で使用する画像は、全てプログラム内で描画しています。好みに応じて変更してみるのも良いかもしれません。
記録が更新されている場合、プログラムの終了時に保存します。保存先は、実行ファイルと同じフォルダにファイル名"Save.dat"で作成されます。
中身はテキストファイルで、タイム(TimeSpan)がそのまま記録されています。基本的に何者か分からないファイルが好きではないのと、改変されたからといって重大な被害が発生しそうにもないので、分かり易いテキストファイルとしています。ですが、場合によっては、バイナリファイル化するなどして、改変しにくくなるようにしても良いかもしれません。
記録を消去したい場合は、ファイルを削除してください。中身を不用意に改変すると、読み込み時にエラーとなる場合があります。
また、最速タイムを一件しか記録していませんが、トップ10などランキングを表示するようにしても良いと思います。
タイトル画面でF4キーを押すと、ゲーム中に使用している画像を確認できます。また、F5キーを押すと、各種パラメータを確認できたりメニューが表示されます。元に戻るには、もう一度F4, F5キーを押してください。
今作では、文字列の描画に"PML 2"というものを使用しています。これは、VB6当時にMSX-BASICと比べて文字列操作関連・グラフィック画面操作関連で貧弱だったのを(知らないだけかもしれませんが)改善するべく自作したもので、それをVB2005移行に伴って移植・機能強化したものです。後々、VB2005は文字列の描画機能も大幅に強化されているのを知り、必要ないかと思ったのですが、今更外すのは作業的に面倒なのと、使ってるうちにだんだん慣れてしまって、結局そのまま使い続けてしまいました。(.NETに文字列の正確な描画サイズを簡単に得られる機能や、最終参照座標の維持機能などがあれば、もっと楽できるのですが・・・。)
音は、一切鳴りません。作者に音才がないからです。淋しいので、音を付けると雰囲気が増すと思います。才能のある方は、挑戦してみてください。
VB.NET系(VB2005からしか使ったことが無いので、それ以前は分かりませんが・・・)になってから、フレームレートの制御に苦労させられました。 APIを使っていたVB6では、120fps以上でも余裕だったのに対して、.NETで同等の機能を使って同じ方法でフレームレートの制御プログラムを書くと、どんなに軽い処理でCPUが遊んでいても20fps台が限界で(しかも想定値よりも低いレートになってしまう)、空ループの時間調整処理を加えて何とか60fps台が安定的に出るようになりました。CPUの負荷に関係なくフレームレートが下がってしまうのは、.NET Frameworkで用意されている[System.Environment.TickCount]や[System.Threading.Thread.Sleep]の更新間隔が永いのが原因だと思いますが、やはり自分の技術力が最大の問題なんでしょうね。
VB6からVB.NET系に移行して、大きく変わったのが画像の描画方法だと思います。
VB6では、自動的に画像の再描画(ウィンドウが他のウィンドウに隠れてしまった部分を自動的に書き直してくれる)をしてくれましたが、.NETでは自分でやらなければならなくなりました。
基本的には、[Paint]イベントで何かあるたびに全て描画し直せば済むのですが、ゲームには、“キャラクタなど常に描き換えたい画像”と、“背景など一度描いたらもう描きたくない画像”の2種類が存在します。それらを簡単に両立するため以下の方法を採っています。
まず、FormにPictureBoxを配置し、プログラム側でBitmapクラスとGraphicsクラスをクラスレベルで作成します。Bitmapは、PictureBoxのクライアント領域と同じ大きさで作成します。Graphicsは、Bitmapを使ってインスタンスを作成します。さらに、PictureBoxの[Image]プロパティにBitmapを代入(同一化)して、準備完了です。
後は、最初に一度だけ描けば済む背景などをGraphicsを使ってBitmapに描画し、フレームごとに書き換えたい画像は、[PictureBox.Refresh]を実行して呼び出される[Paint]イベントの[e.Graphics]を利用して描画すればOKです。ここで描いた画像は、次に[Refresh]したら消えてしまうので、消去処理を行う必要はありません。
この方法で、背景は消えず、キャラクタなどだけ描き換えることが可能(スプライト的)になり、ウィンドウの再描画にも対応できます。
と言うことで、ゲームの画像処理として定石であるダブルバッファリング的な処理はしていません。と言うのも、[Paint]イベントが終了するまで描画内容が画面に反映されない仕組みになっているみたいなので、チラつきが発生せず必要性を感じなかったからです。
このネタで創り始めたのは、2004年03月17日に遡るかな。当初は、ラーメンをすする部分だけで、一定時間内に何杯食べられるかを競う内容やった。一応、形になるところまで行ったけど、何か「一人の人間が意味も無く大量の食料を消費する」内容に罪悪感がムクムクと・・・、しかも何か物足りない。で、方針転換。
その間に、OSはWin98→XPへ、開発環境はVB6→VB2005→VB2008と移り変わり、途中で幾度と無く中断したり、一から創り直したり、何かと足したり引いたり、紆余曲折を経ながら5年と数ヶ月という年月を費やして、なんとか区切りを迎えた。いや〜、ホント永かったょ。
いくら超鈍重ヘッポコ人間といっても、構想段階ではここまでの難産は想定外。でも今回は、これまで創ってきたマウス操作系ゲームの集大成的な感じで過去最大級やし、それはそれでなかなか感慨深い。
.NET系に乗り換えて驚いたのは、画像を回転したり拡大したりが簡単にできたり透明色が使えたりなどなど、グラフィックメソッドがものすごくパワーアップしてたこと。こんなに簡単にできるなんて夢みたい。でも、線を引いたり四角形を描画するときの座標指定がいびつになっているんはいただけない。何とかして欲しいもんだ。
特に、線描画系(Draw〜)と塗り潰し系(Fill〜)メソッドで、同じパラメータを与えても描画される形が異なるのは、どうしても納得できない。この問題が、一向に解消されないところを見ると、問題視しているのは自分だけなんやろか?
ところで、デストラクタをちゃんと実行しないと駄目って良く見かけるけど、いつどこで何に対して実行するべきなのか、実行しなければ何がどうなって不具合が起こるのか、いまだによく理解できない・・・。なんだか、すご〜く面倒臭い。Dispose()メソッドとかFinalize()メソッドとかガベージコレクションとか、やろうとしていることは分かるんやけど、小さいプログラムやから、終了時に自動一括解放してくれて良いよって思ってしまう。