妹とバーチャルパッド
「お兄ちゃん! 今日はバーチャルパッドを作りますよ!」
今日はどうやらパッドを作るらしい。
スマホにパッドはついていないはずだが……
「なあ、バーチャルパッドって何だ?」
「要は画面上に表示されるパッドですね。これができれば自由に操作ができるようになりますよ!」
「おお、すごいな。でも難しいんじゃないか?」
「そうでもないのでゆっくりやって行きましょう、まずはパッド用の円を表示しましょう、これが方向キーの代わりになります、まずはこれを書いてください」
-------
@Override
public boolean onTouchEvent(MotionEvent event) {}
-------
「ブーリアンって何だ?」
わからんとこは沢山あったがこれは全くわからない。
「真偽地、if()の()の中で条件判定をするのに使うような値です。例えば100>10なら真ですね」
「タッチされているかどうかを返すのか?」
「いえ今回は@Overrideといって親クラスのメソッドの上書きなので内部実装は自由です」
「さっきのrun(){}みたいなもんか?」
「そうですねではまずタッチされている座標を取得しましょう。いつものように{}内に書いてください」
--------
int tx = (int) event.getX();
int ty = (int) event.getY();
return true;
-------
「末尾のreturn true;は無視してください、とにかく何か返さないとコンパイルエラーになるので書いてるだけであたいは使いませんから」
「コンパイル? ああ、もしかして実行するときの処理のことか」
「そうですね、だいたい合ってます。上2行はだいたい何をやってるかわかりませんか?」
「もしかしてタッチ位置のxとy座標を取得してる?」
「そうです! お兄ちゃんも慣れてきましたね!」
俺もここ数日で基礎を叩き込まれたので何となくは分かってしまう。
「では新しい制御構文を紹介します、switchです」
--------
switch (event.getAction()) {}
--------
制御構文って言ってたな……分岐だろうか?
「これはgetAction()の値で分岐するのか?」
「その通り、getActionはタッチパネルが押されたり離されたりしたときの情報を取得するんです」
--------
case MotionEvent.ACTION_DOWN :
case MotionEvent.ACTION_MOVE :
--------
「さて、早速ですが裏技を使ってもらいます」
「裏技?」
「上の2行ですけど、caseの後に押されたときと指が動いたときにこの2行以下の文が実行されます」
裏技要素無さそうだな……
「お行儀のいいプログラムはcase 条件:の後には次の条件を書く前にbreak;があるべきなんです。このケースだとDOWNでもMOVEでも同じ動きをしますね」
「でもそれのどこが裏技なんだ?」
裏技要素がない気がするんだが……
「本来であれば条件分岐なので
case 1: break;
case 2:break;
と書くべきなんです。break;を忘れると1か2かのどちらかの場合しか実行されないはずがどっちを入力されても1の場合も2の場合も実行されちゃいます」
じゃあここでは意図的にbreak;を書いてないってことか。
「DOWNは押されたときで、MOVEは指が動いたときか?」
「そうですね、こうしておけばこれでタッチされっぱなしでも問題なく動きます」
なるほど、タッチされっぱなしの時も反応してくれるってことか」
「ではまずはonDraw内に
p.setColor(Color.BLUE);
canvas.drawCircle(150, height-150, 100, p);
を書いてください」
名前からするに円を描くのだろうか?
「これはx座標150、y座標height-150に半径100の円をpで指定された設定で描きます、じゃあ実行してみましょうか」
スマホをつないで実行する。
画面下部に青い丸が表示された。
「なあ、これを何に使うんだ?」
「これがパッドです。十字キーはちょっと面倒なので円で代用しました」
この円を押した方向に動くということか。
「さて直接値を埋め込むのはあまり良くないので変数にしておきましょう。まずはクラス宣言の下に
private float padx,pady;
と書いてください」
「名前からするにパッドの中心座標か?」
「そうですねではこの後にrun(){}の中に
--------
padx = 150;
pady = height - 150;
--------
だいたい何をやってるかはわかりますよね。
ではdrawCircleの引数を変えましょう。お兄ちゃんやってみてください」
いきなりこっちに振られてテンパる俺、……こうかな?
canvas.drawCircle(padx, pady, 100, p);
「どうだ?」
「うん、いい感じですよこれであってます」
すると由紀が嫌そうな顔で言った。
「さて、今回の山場を作るわけですが……ぶっちゃけめんどくさいんですよね判定って……
まあ愚痴ってたってしょうがないので書きましょうcaseの下に書いてください」
------
if (tx >= padx - (100 - 30) && tx <= padx + (100 - 30) && ty >= pady - 100 && ty <= pady) {
y += 10;
}
------
「ちょっと待って長すぎない!?」
「そんな身構えないでください、大丈夫、これは下方向への移動だけど他の方向もコピペでちょっと変えるだけですから」
1行の長さにめまいがしそうになるものの、意味はわからないがそのまま入力する。
「上のコードだと丸の中心から下の方を押したときに反応します。で、今のを後3回コピペしてください
--------
if (tx >= padx - 70 && tx <= padx + 70 && ty >= pady - 100 && ty <= pady) {
y -= 10;
}
if (tx >= padx + 20 && tx <= padx + 100 && ty >= pady - 30 && ty <= pady + 30) {
x += 10;
}
if (tx <= padx - 20 && tx <= padx + 100 && ty >= pady -30 && ty <= pady + 30) {
x -= 10;
}
}
--------
「あ、クラス宣言の下にprivate int x;をつけてくださいね」
「ではdrawRectの変更ですが、ここまできたお兄ちゃんならわかりますよね」
「こうか?」
canvas.drawRect(x, y, x+50, y + 60, p);
「あってますよ! 流石ですねお兄ちゃん!」
「じゃあそろそろ実行していいか」
動くのか気になる、どんな風に動くのだろう?
「その前にrun()のなかのy++;を削除しておいてくださいね、ないほうがわかりやすいので。
「ああ、操作以外で動いたら不便だもんな」
「そうですね、じゃあケーブルを挿して、いいですよ」
「んじゃ、実行っと」
差し出される妹のスマホには……四角と丸が映っていた。
「これだけか?」
やっぱりこれだけだとちょっと寂しい。
「画面下の丸をグリグリ触ってみてください」
言われた通り丸をタッチしてみると……動いた! 四角が動いた!
「ね、楽しいでしょう!」
「ああ、何だかすごいな画面の操作ができるのか……」
「ゲームは画面描画の繰り返しですからここら辺までできればあとはアイデアしだいですね」
「これでキャラクターが動くんだよな!」
「もうちょっと調整したほうがいいんですけど……いっぺんに全部やるのも何ですし今日はここまでにしましょうか」
こうして俺たちは解散した、俺は満足感を覚えながら床についた。
スマホゲームにバーチャルパッドを付けるのには賛否あるようですが、
個人的にはありだと思ってます。