この記事で扱っていること
- かちわりメガトンパンチを作る方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
某有名ゲームキャラクターの「スーパーデラックス」版等に収録されていたミニゲームに、かちわりメガトンパンチというゲームがありました。
タイミングよくボタンを押して好スコアを競うというタイミングゲーです。
3種類のタイミングゲームを連続して行うというものになりますが、それぞれが異なる動きをするため、これをLabVIEWで実現する場合には少しずつ異なる処理を実装することになります。
単調な動作とならないように、動きに緩急をつけるため今回は三角関数を多用しています。
どんな結果になるか
本家のゲームは3種類のタイミングゲームを順にこなしていくようになっていますが、今回はそれぞれ別のviとして実装していきます。
どれもフロントパネルの作りとしては共通しており、2Dピクチャと停止ボタン、そして得点を表示するための数値表示器を配置しています。

1stステージは、伸び縮みする赤いバーが一番上に到達したときに止めると高得点がとれるようになっています。
伸び縮みの早さは一定というわけではなく、上下に伸びるにつれ早く、真ん中を通るときが一番遅いような動作としています(ブロックダイアグラムを見ればわかりますが、正弦波の動作を真似ています)。
なお、図では青い矢印がありますが、プログラム動作時にこの青い矢印はありません(他の2つのステージの図も同様です)。

2ndステージは、円2つがある中心の周りをまわっていて、これらの円が重なったときに高得点になります。

3rdステージは、振り子のように動く赤い円が、静止している円に重なったときに高得点になります。

プログラムの構造
どのプログラムもピクチャ上に線や円を描くときの座標の指定を工夫するだけで作れます。
座標は整数値しか受け付けないので、円状の動きを行わせる場合の厳密な位置調整はできないのは仕方ないですが、それは対象の線や円の太さ(ペンサイズ)をある程度大きくすることでごまかしています。
まずは1stステージのプログラムです。
バーの赤い部分が伸び縮みする速さに緩急をつけるため、バーの上座標(top)を正弦波の値にバーの最大の長さ(以下の例では200)をかけています。
なお、これ以外の3つの座標でそれぞれ黒い四角よりも3ずらしているのは、ずらさないと黒い四角と赤い四角が重なり見栄えが良くないためです。
他のプログラムも同様ですが、待機関数の時間を変えることで、変化速度(≒難易度)を変えることができます。

次に2ndステージのプログラムです。
二つの円を、ある位置(今回の場合2Dピクチャの描画領域の中心)から左上、右下に均等にずらし(以下の図では全ての方向に25ずらしています)、そのずれた位置を中心に周るようにしています。
この二つの円が重なる必要があるのでそれぞれの周回半径は「ある位置」からずらした大きさを考慮しています(以下の図では、25√2が周回半径)。
得点の付け方は、もちろん重なったときが一番大きいため、二つの円の距離を基に計算するようにしています(遠くになると点が低くなる)が、二つの円の距離を100から引くという計算(重なったときには距離=0なので100点)だと負の数になりうるので、負の数になる場合には得点は0となるようにしました。

なお、ワイヤがたくさんあってすっきりしない、デバッグが難しい、という場合には、フォーミュラノードも有効です。
どのような計算をしなければいけないかさえわかっていれば、これを数式で書いて、このノードに対する入力、出力を構成するだけなので、ワイヤが多く煩雑となる状態を軽減してくれます。
以下に例を載せていますが、最初に使用する変数のデータ型を書いて、あとは式を書いていくだけです。
基本的な三角関数や円周率π等は使用できるため、式を見て何となくやっていることは分かるかなと思います。

最後に3rdステージのプログラムです。
赤い丸が振り子のように動くようにしています。
この振り子の動きも緩急をつけるため、ターゲットとなる黒い破線丸に近いほど早く動き、端ほどゆっくり動くようになるために正弦波を用いています。

イベント処理で実装する場合
上記はすべてポーリング処理で実装した場合の例です。
ポーリング処理が全て悪いわけではないですが、似たようなことをイベント処理で実装する場合には、ループ速度を待機関数で調整するのではなく、ノーティフィケーション待機のタイムアウトを使用する方法があります。
イベントストラクチャでタイムアウトイベントを使用するという手もありますが、実際上ポーリング処理と変わらなくなってしまうため、イベントに反応している感をだすためにイベントストラクチャをメインのループから分けています。
また、各ゲームはボタンを押せば終了なのでイベントを複数回検出する必要はないため、Whileループに入れずにイベントストラクチャを使用しています。

なお、機能的にはノーティファイアでなくてもキューを使用することで同じことはできます。
ただ、キューのようにデータを溜める必要もない、こういった特定の命令のみを受け取るような動作を他のループ(もしくはイベントストラクチャ)から受け取る場合には、ノーティファイアを使うイメージがあるので今回もノーティファイアでの実装としました。
本記事ではかちわりメガトンパンチを作る方法を紹介しました。
ピクチャを使って図形が表現できれば様々なゲームを作ることができるかと思います。
ただ、座標での指定については多少慣れないと思った動作をしてくれないことがあるため、今回の題材のようなプログラムで慣れるためにも実際に作ってみるのがいいと思います。
ここまで読んでいただきありがとうございました。
コメント