【ウディタ講座】長押し判定とドラッグの作り方

なぜ長押しが必要なのか

よくあるダンジョンギミックで「岩を押して運ぶ」というのがありますよね。

思ったことはないですか?

いちいち調べて動かすのは面倒。ぶつかっていくだけで動いてほしいけれど、間違って近づいただけでも動かれると萎えてしまう……

あるいは

マウス操作ゲームを作っているけれど左クリックと右クリックだけではボタンが足りない……

そんな問題は長押し判定を挟むことで解消できるのです。

長押し判定コモン

十字キーの場合とマウス左クリックのサンプルです。

■変数操作: CSelf10[長押しなら1] = 0 + 0
■変数操作: CSelf11[長押しフレーム] = 5 + 0
■回数付きループ [ CSelf11[長押しフレーム] ]回
|■キー入力:CSelf12[キー受付] 4方向 決定(10)
|■条件分岐(変数): 【1】 CSelf12[キー受付] が CSelf0[指定キー] 以外
|-◇分岐: 【1】 [ CSelf12[キー受付] が CSelf0[指定キー] 以外 ]の場合↓
| |■変数操作: CSelf10[長押しなら1] = 0 + 0
| |■イベント処理中断
| |■
|◇分岐終了◇
|■ウェイト:1 フレーム
|■
◇ループここまで◇◇
■変数操作: CSelf10[長押しなら1] = 1 + 0

コモン呼び出し時には、Cself0の指定キーへ、長押しの判定をしたいキーを入れてください。

決定10、キャンセル11、上8、下2、左4、右6です。

キー入力を受け付けたいときに、このコモンを呼び出すことで、コモンから返ってきた値が1なら長押しと判断できます。長押しフレーム=回数ループの反復数を変えることで、長押し扱いとする長さ(フレーム数)も調整可能ですね。

 

では、主人公からぶつかることで押せる岩のイベントを作ってみましょう。

プレイヤー接触で起動するイベントの中身で、次のようなコモンイベントを呼び出します。

■キー入力:CSelf12[テンキー受付] 4方向
■イベントの挿入[名]: CSelf11[長押し?Y=1] = [“長押し?”] <コモンEv 227> / CSelf12[テンキー受付]
■条件分岐(変数): 【1】 CSelf11[長押し?Y=1] が 1 と同じ
-◇分岐: 【1】 [ CSelf11[長押し?Y=1] が 1 と同じ ]の場合↓
|■変数操作+: CSelf10[主人公の向き] = 主人公 の 向き(1~9)
|■条件分岐(変数): 【1】 CSelf10[主人公の向き] が 2 と同じ 【2】 CSelf10[主人公の向き] が 4 と同じ 【3】 CSelf10[主人公の向き] が 6 と同じ
|-◇分岐: 【1】 [ CSelf10[主人公の向き] が 2 と同じ ]の場合↓
| |■動作指定:このイベント / 全歩移動に設定 / 下
| |■
|-◇分岐: 【2】 [ CSelf10[主人公の向き] が 4 と同じ ]の場合↓
| |■動作指定:このイベント / 全歩移動に設定 / 左
| |■
|-◇分岐: 【3】 [ CSelf10[主人公の向き] が 6 と同じ ]の場合↓
| |■動作指定:このイベント / 全歩移動に設定 / 右
| |■
|-◇上記以外
| |■条件分岐(変数): 【1】 CSelf10[主人公の向き] が 8 と同じ
| |-◇分岐: 【1】 [ CSelf10[主人公の向き] が 8 と同じ ]の場合↓
| | |■動作指定:このイベント / 全歩移動に設定 / 上
| | |■
| |◇分岐終了◇
| |■
|◇分岐終了◇
|■
◇分岐終了◇

この岩押しコモンのなかで、さきほどの長押し判定コモンを呼び出しています。

長押しはあくまで誤爆防止ですから、体感できるかどうかの5フレームぐらいでも十分ではないでしょうか。逆に長押し判定が20フレームぐらいあると、相当重たい岩を押しているな、という手応えもでてきます。

長押しはマウス操作ゲームでこそ生きてくる

ステップアップです。

長押し判定の考え方をマウス操作に応用することで、画像のドラッグ移動が実現できます。

もともと、変数操作+の「マウス左クリック状態」は1=長押し、2=新規クリックというふうになっています。この変数頼りだと長押しの有効タイミングのコントロールはちょっと不自由しますが、ドラッグ処理では気にしないで大丈夫。

仮に番号100のピクチャがドラッグできるよう、こんな並列コモンを作ってみました。

■変数操作+: CSelf10[長押し判定] = マウス左クリック状態
■条件分岐(変数): 【1】 CSelf10[長押し判定] が 0 以外
-◇分岐: 【1】 [ CSelf10[長押し判定] が 0 以外 ]の場合↓
|■変数操作+: CSelf13[重なってる?Y=1] = ピクチャ:100 の マウス重なってる?(1=YES)
|■条件分岐(変数): 【1】 CSelf13[重なってる?Y=1] が 1 と同じ
|-◇分岐: 【1】 [ CSelf13[重なってる?Y=1] が 1 と同じ ]の場合↓
| |■変数操作: CSelf11[最新X] = Sys71:マウスX位置 + 0
| |■変数操作: CSelf12[最新Y] = Sys72:マウスY位置 + 0
| |■ピクチャ移動:100 X:CSelf11[最新X] Y:CSelf12[最新Y] / 0(0)フレーム / パターン 同値 / 透 同値 / 表示形式:同値 / 角 同値 / 拡 同値 / カラー 同値
| |■
|◇分岐終了◇
|■
◇分岐終了◇

動かしたいピクチャは、あらかじめ別のイベントで表示しておいてください。

ドラッグは「左クリックをし続けている間だけの動作」ですから、「左クリックが押されていて」かつ「カーソルが問題のピクチャと重なっているとき」にピクチャをカーソルの場所に動かしています。

ピクチャの「位置」は「中央」にしておくと、いちばん見栄えのいい動きをします。

あんまり速く動かすとすっぽ抜けたりしますが……

ドラッグ機能の強化

ドラッグ移動を使うほど凝ったゲームなら、上のサンプルだけでは物足りないでしょう。

アイディア次第でいろいろ豪華にできますので、少し例を。

ドラッグ画像の移動前シャドウをおく

同じ画像を黒っぽい半透明状態で描画しましょう。
初期位置がわかりやすくなりますし、ふだんのパソコンの挙動と近いなので直感的ですね。

シャドウのピクチャの番号は、元ピクチャの番号より小さくしましょう。

ウディタは、番号の大きい画像の方が上側に重ねて表示される仕様です。

マウスカーソルを変える

たとえば、ドラッグ中はカーソルが掴む手のかたちになると、わかりやすくておもしろいですね。

カーソルの変え方はこちらを参考に

【ウディタ講座】マウスカーソルを自作化する

ドラッグ中はカーソルが画面外へ出ないようにする

上のリンクのなかでも触れていますが、システム変数のマウス位置の仕様にはちょっと注意点があります。

上のコモンでドラッグ対象の画像を画面外へ持っていこうとしても、画像は画面ハジに引っかかってカーソルだけが飛び出ていきます。画像が画面外へ出ないほうが良いはずですが、ちょっと操作感がよくないですね。

■条件分岐(変数): 【1】 Sys71:マウスX位置 が 0 以下 【2】 Sys71:マウスX位置 が 320 以上
-◇分岐: 【1】 [ Sys71:マウスX位置 が 0 以下 ]の場合↓
|■変数操作: Sys71:マウスX位置 = 1 + 0
|■
-◇分岐: 【2】 [ Sys71:マウスX位置 が 320 以上 ]の場合↓
|■変数操作: Sys71:マウスX位置 = 319 + 0
|■
-◇上記以外
|■条件分岐(変数): 【1】 Sys72:マウスY位置 が 0 以下 【2】 Sys72:マウスY位置 が 240 以上
|-◇分岐: 【1】 [ Sys72:マウスY位置 が 0 以下 ]の場合↓
| |■変数操作: Sys72:マウスY位置 = 1 + 0
| |■
|-◇分岐: 【2】 [ Sys72:マウスY位置 が 240 以上 ]の場合↓
| |■変数操作: Sys72:マウスY位置 = 239 + 0
| |■
|◇分岐終了◇
|■
◇分岐終了◇

ドラッグ中のみ、こういう処理が働くようにすると、画像が止まるのと同じ個所でカーソルもそれ以上すすまない、という操作感になります。