なのでまたまた、好きなように改造していきます。結果、コードが汚くなってきたら、また書き直しゃいーんです、的な気楽さでいきましょう。
さて、このあいだ岩を「赤い四角」から適当に「赤い石の写真」に置き換えただけで、雰囲気はえらく変わってしまいました。やっぱ見た目は大事ですねぇ、ということで。
PUBLIC-DOMAIN-PHOTOS.com さんのところで見つけた宇宙の画像を、背景に貼ってみました。
うん、更に宇宙旅行っぽくなりましたかね。コードはベタですが、まずGameViewに以下の変数を宣言しておき、
Bitmap wall;
Rect wall_f, wall_t;
初期化のところに以下のコードを追加して背景画像を準備し、
wall = BitmapFactory.decodeResource(context.getResources(), R.drawable.galaxy);
wall_f = new Rect(0, 0, wall.getWidth(), wall.getHeight());
wall_t = new Rect(0, 0, s.cw, s.ch);
最後にdoDraw()で canvas.drawColor(Color.BLACK); の代わりに以下で背景をクリアするようにします。
canvas.drawBitmap(wall, wall_f, wall_t, null);
もう少しマシな方法もある気はしますが、とりあえず簡単に実現できたのでコレで良しとしましょう。
次はゲーム性の向上を考えてみましょう。このゲームでは岩を避けるのがゲームの根っこですが、岩の出現のしかたが親切ではない気がします。いきなり出てきて、避けられないことがある。
そこで出現直後の一定時間は、自機との当たり判定が無いという仕様はどうでしょうか。更にそれがわかるように、出現時には半透明で、だんだんとはっきり見えてくる感じの表現が良いですね。半透明でなくなった時から当たり判定が発生する、であればプレイヤーに十分な情報を伝えることができます。
これを実現するために、GameBitmapObject を継承した Rock クラスを新しく作成してみましょう。
public class Rock extends GameBitmapObject {
int count;
public Rock(int _w, int _h, Bitmap b) {
super(_w, _h, b);
count = 0;
}
動いた回数を記録する count変数を追加してみました。で、実際に動くmove()関数を上書きして、カウントアップしてあげないといけないですね。
@Override public GameObject move() {
super.move();
count++;
return this;
}
で、最初の2秒ほどは衝突判定はないことにします。よって以下のように上書きしてみました。
@Override public Boolean collision(GameObject o) {
return count < 20 ? false : super.collision(o);
}
あと、衝突判定がない間は、半透明表示でしたよね。なので以下のように上書きしています。
@Override public GameObject draw(Canvas c) {
if (count < 20) {
Paint p = new Paint();
p.setAlpha(count * 10);
c.drawBitmap(bitmap, br, new Rect(cx, cy, cx + cw, cy + ch), p);
} else {
super.draw(c);
}
return this;
}
それぞれ、countの値を条件として参照していて、条件によって動作を乗っ取る仕組みの上書き(Overrode)ですね。条件外のときには素直にsuper呼ぶのがポイントです。
透明度を count * 20 としているのは乱暴に見えますが、半透明の状態とふだんの表示(α値が255)は少しギャップがあったほうが、プレイヤーにわかりやすいと思って、この式にしています。
さて、この新しいクラス Rock を GameActivity に組み込みましょう。岩関係でクラス指定をしている、以下の二箇所を書き換えます。
List<GameBitmapObject> rocks = new ArrayList<GameBitmapObject>();
↓
List<Rock> rocks = new ArrayList<Rock>();
GameBitmapObject o = new GameBitmapObject(s.w(0.01F * s.i(10, 5)), s.h(0.01F * s.i(10, 5)), b);
あ、衝突判定の修正を生かすには、以下も忘れちゃ駄目ですね。
if (ship.collision(rock)) {
次はゲーム性の向上を考えてみましょう。このゲームでは岩を避けるのがゲームの根っこですが、岩の出現のしかたが親切ではない気がします。いきなり出てきて、避けられないことがある。
そこで出現直後の一定時間は、自機との当たり判定が無いという仕様はどうでしょうか。更にそれがわかるように、出現時には半透明で、だんだんとはっきり見えてくる感じの表現が良いですね。半透明でなくなった時から当たり判定が発生する、であればプレイヤーに十分な情報を伝えることができます。
これを実現するために、GameBitmapObject を継承した Rock クラスを新しく作成してみましょう。
public class Rock extends GameBitmapObject {
int count;
public Rock(int _w, int _h, Bitmap b) {
super(_w, _h, b);
count = 0;
}
}
動いた回数を記録する count変数を追加してみました。で、実際に動くmove()関数を上書きして、カウントアップしてあげないといけないですね。
@Override public GameObject move() {
super.move();
count++;
return this;
}
@Override public Boolean collision(GameObject o) {
return count < 20 ? false : super.collision(o);
}
@Override public GameObject draw(Canvas c) {
if (count < 20) {
Paint p = new Paint();
p.setAlpha(count * 10);
c.drawBitmap(bitmap, br, new Rect(cx, cy, cx + cw, cy + ch), p);
} else {
super.draw(c);
}
return this;
}
透明度を count * 20 としているのは乱暴に見えますが、半透明の状態とふだんの表示(α値が255)は少しギャップがあったほうが、プレイヤーにわかりやすいと思って、この式にしています。
さて、この新しいクラス Rock を GameActivity に組み込みましょう。岩関係でクラス指定をしている、以下の二箇所を書き換えます。
List<GameBitmapObject> rocks = new ArrayList<GameBitmapObject>();
↓
List<Rock> rocks = new ArrayList<Rock>();
↓
Rock o = new Rock(s.w(0.01F * s.i(10, 5)), s.h(0.01F * s.i(10, 5)), b);
あ、衝突判定の修正を生かすには、以下も忘れちゃ駄目ですね。
if (ship.collision(rock)) {
0 件のコメント:
コメントを投稿