Androidアプリを作ってみる #22 -Surfaceview その5-

Android Surfaceviewでボールを動かす

やっと動かすとこまで…

前回、やっとの事でSurfaceviewを使用してボールというか円を表示するところまできたのでした。今回はそのボールというか円を動かしてみたいと思います。

Android 表示

ここまではきたのね

にゃんこ
まだそこ!?

前回の記事

Androidアプリを作ってみる #21 -Surfaceview その4-

2017.03.20

ちなみに前回までのGameSurfaceview.javaはこんな感じでした。

ボールの位置を覚えておく変数を宣言

ここにボールというか円の位置を制御するための変数を宣言します。書くのは

の下です。

こんな風に宣言します。

メリ
ボールというか円って言いたいのね。

privateとは、このクラス内だけで使用するという意味です。ここをpublicとしてしまうと他のクラスからも変数をいじれてしまうのであんまりよくないです。ま、今のコードならpublicにしても何ら問題はありませんが(他のクラスを使ってないから)。

floatintは、その変数が格納することができる値の範囲を表します。以下の表の通りなのですが細かく覚える必要はないです。簡単にいうとfloatは小数点を扱える、intは整数と言ったとこでしょうか。

Javaのデータ型
データ型
boolean true or false
char 16ビットUnicode文字 ¥u0000~¥uFFFF
byte 8ビット整数 -128~127
short 16ビット整数 -32768~32767
int 32ビット整数 -2147483648~2147483647
long 64ビット整数 -9223372036854775808~9223372036854775807
float 32ビット単精度浮動小数点数
double 64ビット倍精度浮動小数点数
メリ
え、そんな説明!?

まずは画面の大きさを保存

ボールというか円を動かすと言っても、ただ闇雲に動かしてもいつかは画面の外に出ていってしまって表示が消えてしまいます。画面を超えてしまうからと言ってAndroidが自動で跳ね返してくれるわけではありません。なのでこういうところは自分で書いていくしかないんですね。世の中そんなに甘くはないです。

にゃんこ
当たり前だろ

さっき宣言したdisplayWidthdisplayHeightにそれぞれ画面の幅と高さを保存しておきます。これ、調べてみるとSurfaceviewが更新されるときに実行されるコールバック処理「surfaceChanged()」に渡される引数に画面の幅と高さがあるというのですが…。このsurfaceChangedメソッドはAndroidStudioの自動挿入機能で書いたものだけど、引数がなんかおかしいですね…。

ii1i2って意味わからん。

Android Developersで調べてみるとこうなってました。

surfaceChanged(SurfaceHolder holder, int format, int width, int height)

これならわかりやすいじゃん!! 何でこうなったんだろ…。ま、いいです。そこは上記のように書き換えましょ。

変数、引数名(ここのは仮引数)は共に自由です。

この引数に渡されてくるwidthheightに画面のというかSurfaceviewの幅、高さが入ってます。それをさっき宣言した変数displayWidthdisplayHeightに保存します。引数をそのまま使えばいいじゃないかという風に思うかもしれませんが、この引数はローカル変数というメソッドの実行が終了すると消えてしまう変数なのです。で、displayWidthdisplayHeightはメソッドの外に宣言しているのでグローバル変数と呼ばれるものになってメソッドが実行されているとかいないとか関係なしに保持しておくことが可能です。だからsurfaceChanged()メソッドが終了する前に値をコピーしておきます。

=としていますが、これは左辺、右辺がイコールという意味ではなく右辺値を左辺の変数にコピーするという意味になります。プログラミングの世界では=はそういう使い方をします。

ボールを動かす処理を入れる

いよいよボールを動かす処理を書いていきます。これはループ処理をしているpublic void run()に書いていくことになります。while文の中をこのように書き換える。

この中の二つのifの部分で画面の幅と高さを超えているかどうかを判定しています。横方向のX座標が左隅の0を下回らないか、もしくは右隅のdisplayWidth(画面幅)を超えないかを見てます。この「もしくは」を表しているのが「||」です。「or」条件ってことですね。二つの条件のどちらかが成立するならifのすぐ下({}の中)を実行します。それでいくとY座標も同じことですね。

ここでX、Y座標が画面の幅、高さを超えているならマイナスの値にして逆方向にしてます。このボールの方向と進む速さ(初期値に10が入っている)を決めているdxdyをボールの表示位置に加算する形で代入します。

ここで「ballY += dx」とは、「ballX = ballX + dx」と同じ意味です。後者で書いても問題はありません。また、「*=」についてですが、まず「*」は数学の掛ける(x)です。その後に「=」が続いているのでさっきと同じ意味で、「dx *= -1」とあれば「dx = dx * -1」と同じってことですね。

スポンサーリンク



ボールが動くか試す

さあ、いよいよアプリ実行…でも

Android StudioのRunを押して実際にちゃんと動くのか試して見ます。

あ、あれ!? 背景がいきなり白になった上に残像が…。これはこれでかっこいいけど意図したものではありません。どうやら一回表示したボールは消しておかないといけないみたいですね。ボールの動きに関しては問題ないようですけど(円の中心が画面の端にくると逆に進む)。

ってことで、ボールの移動を表示する前にCanvasをクリアすればいいみたい。

んで、実行。

よし!!できました。なんか知らんが背景も黒に戻ったな(何でだろ!?…)。ま、そこはいいか…。ってことでやっとアニメーション的な動きができました。

前回の記事

Androidアプリを作ってみる #21 -Surfaceview その4-

2017.03.20



コメントを残す

メールアドレスが公開されることはありません。