blog

23日間でゼロからAndroidゲームを開発する (6)

第6回:以前からAndroidゲームを開発したいと思っていたのですが、なかなか良いアイデアが浮かびませんでした。このゲームはまた、Androidゲームに大きな名前や複雑なゲーム設定は必要なく、シンプル...

May 4, 2016 · 6 min. read
シェア
float x = Gdx.input.getX() - 240f; 
float y = 400 - Gdx.input.getY(); 

これは正しい方法ではありません。シンプルで適切な方法は、GDX .NET を使って変換することです:

Vector3 touchPos; 
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0); 
camera.unproject(touchPos); 

アンドロイドでの「戻る」ボタンの取り扱い

ほとんどのネット上の例では、戻るボタンを扱うときにKeyDownメソッドをオーバーロードすることが書かれています。残念ながら、この方法ではStageを使う必要がありますが、私はそれをしませんでした。今、私のコードではActorとStageをたくさんコピーしていますが、それは重要なことではありません。次のプロジェクトまでStageは使いません。

幸い、解決策が見つかりました。Gameサブクラスのcreate()関数に以下の関数を追加するだけです:

Gdx.input.setCatchBackKey(true); 

次に、render()メソッドで、「戻る」ボタンが押されたかどうかをチェックします:

if (Gdx.input.isKeyPressed(Keys.BACK)) 
{ 
    Gdx.app.exit(); 
} 

render()は1秒間に何度も呼び出されるので、"戻る "ボタンが離されたかどうかを検出するために、ブール値のフラグ変数が必要になるかもしれません。

if (backReleased && Gdx.input.isKeyPressed(Keys.BACK)) 
{ 
    backReleased = false; 
    Gdx.app.exit(); 
} 
else 
{ 
    backReleased = true; 
} 

ゲームに入り、ショップメニューに行き、メインメニューに戻ることができるようになりました。もちろん、メニューにはオプションが表示されるだけで、実際にはまだ機能していません。

9-patchで動的にサイズ変更されるボタンやコンテナを処理

とにかく、私は46×46の9パッチイメージを描かなければなりませんでした。コンストラクタのTextureRegionを経由して、大きなスキンから9パッチを取得しました。

この処理によって、メインメニューにさまざまなオプションを入れられるようになりましたし、遊び方のヒントを与えるスクロール字幕も追加しました。私はこのコンセプトがとても好きなのですが、これを採用しているゲームはほとんどありません。ヒントを最初にしか表示しないゲームもあります。プレイヤーの気をメインメニューから逸らしたくないのかもしれません。

以下は、強化アイテムを購入するためのショップメニューです:

補強用小道具

小道具の新しいアイデアをいくつか思いつきました。ひとつはエイリアンの動きを一時的に遅くするもの、もうひとつは短時間だけ5倍の点数を取るものです。高得点を取るのが得意なプレイヤーもいるので、これは良くないアイデアかもしれません。

一方、次のリロードまでの発射速度を上げる小道具は大ヒットするかもしれません。

ショップは7つの小道具だけにして、1つのスクリーンに収まるようにしたいですね。でも、アップグレードの可能性についてはまだわからないんです。

最後に、FPSの処理コードはpixmapを解放していないようです。そのため、長時間実行するとRAMが食われてしまいます。

public class ScreenShot implements Runnable 
{ 
    private static int fileCounter = 0; 
    private Pixmap pixmap; 
  
    @Override 
    public void run() 
    { 
        saveScreenshot(); 
    } 
  
    public void prepare() 
    { 
        getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); 
    } 
  
    public void saveScreenshot() 
    { 
        FileHandle file = new FileHandle("/tmp/shot_"+ String.format("%06d",  fileCounter++) + ".png"); 
        PixmapIO.writePNG(file, pixmap); 
        pixmap.dispose(); 
    } 
  
    public void getScreenshot(int x, int y, int w, int h, boolean flipY) 
    { 
        Gdx.gl.glPixelStorei(GL10.GL_PACK_ALIGNMENT, 1); 
        pixmap = new Pixmap(w, h, Pixmap.Format.RGBA8888); 
        Gdx.gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixmap.getPixels()); 
    } 
} 

OK、これで全部です。レンダリングループの各レンダーの最後に追加しました:

ScreenShot worker = new ScreenShot(); 
worker.prepare();           // grab screenshot 
executor.execute(worker);   // delayed save in other thread 

完全性を考慮して、executorはScreenのサブクラスとして追加されています:

private ExecutorService executor; 
... 
executor = Executors.newFixedThreadPool(25); 

ロゴを含む1280×720の静止イメージを作成しました。それをゲームにブレンドして、縦に反転させます。Linuxではこんなコマンドを使います:

for i in shot*png; do echo $i; convert $i -flip -filter Lanczos -resize 372x620 temp1.png; composite temp1.png back.png -geometry +126+56 $i; done
mencoder mf://shot*.png -mf w=1080:h=720:fps=25:type=png -ovc x264 -audiofile music.mp3 -oac copy -o movie.avi -x264encopts bitrate=5000:bframes=2:subq=6:frameref=3:pass=1:nr=0020

Androidでは、丸みを帯びた長方形以外のアイコンが使えるのがいいですね。これはゲームに個性を与えてくれます。最初は、このゲームのために特別なアイコンを作ろうと思ったのですが、エイリアンのピクセルグラフィックが描かれたこの盾がとても気に入りました。どんなサイズでも出力できるようにInkscapeで作りました。ドローンインベーダーの公式アイコンです:

[]

豊富な小道具

/?=0

原爆は用意しましたが、名前はまだ決まっていません。核爆弾、プルトニウム爆弾、スマート爆弾、あるいはまったく違う名前になるかもしれません。ボスは1発や2発なら耐えられますが、3発の爆弾と同じぐらいヤバイです。システム内部では、各ボスの血は20点、爆弾のダメージは8点。レーザーをアップグレードしない限り、通常攻撃は1ポイントのダメージ。

2つ目は、3ウェイルーズ弾。3回撃ってもマガジンを交換しなければなりません。これは非常に強力な小道具で、これがあれば、本当に人を殺し、モンスターやボスの波を一掃する男です。

3つ目はオートリロード。その名の通り、レーザーは自動的に装填されます。ですから、遠慮なく撃って、撃って、また撃ってください。

4つ目はスローダウン。これはエイリアンの動きを遅くするだけで、他は普通に速くなります。最初の20レベルでは、これはかなり役に立ちません。しかし、後半になればなるほど、役に立つことがわかります。

5つ目はポイント2倍。プロップが有効な間、獲得点数を2倍にします。一定の得点に達したときにボーナスを与えるかどうかはまだ思案中ですが、高得点に到達するのはやはりかっこいいものです。

関連記事

23日間でゼロからAndroidゲームを開発

23日間でゼロからAndroidゲームを開発

Read next

Linuxターミナル:memでメモリ使用量を表示する

あなたがシステム管理者であろうと、Linuxのデスクトップバージョンを使っている単なるユーザーであろうと、あるプロセスがあなたのシステムのメモリを使い切っていることに気づいたことがあるでしょう。しかし今は、どのプロセスやユーザーがシステムのメモリをたくさん使っているかを見つけるのに役立つ、気の利いたプログラムを見る価値があります。

May 3, 2016 · 6 min read