This document written: 2014-05-31 .. 2022-01-05

『Android ゲームプログラミング A to Z』フレームワークの実装作業(中編)

ファイル(入出力)

本家(BAG)はインターフェースが FileIO、実装が AndroidFileIOとなっている。

よって、これらを単一の実装クラスにまとめたのが次の Hata 版 FileIO クラスであるが、外部ストレージに対するパーミッションのルールが Android 4.4 以降で変ったこと、BAG 第 2 版では SharedPreferences 用の実装も追加されていることを反映して、やはり BAG 版をそのまま「単一の実装クラスにまとめただけ」とは違っているので、特に翻訳版の BAG の読者は注意して欲しい。


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.preference.PreferenceManager;

public class FileIO {
	private Context context;
	private AssetManager assetManager;
	private String externalStoragePath;

	public FileIO(Context context) {
		this.context = context;
		assetManager = context.getAssets();
		/*
		 * Beginning Android Games 2 では getExternalStorageDirectory() を使用
		 * getExternalFilesDir() はアプリ専用のディレクトリのみ参照できる代わり、
		 * アンインストール時にはディレクトリ毎、自動で削除され、KitKat (API-19) 以降では
		 * WRITE_EXTERNAL_STORAGE パーミッションも不要になる。
		 */
		externalStoragePath =
			context.getExternalFilesDir(null).getAbsolutePath() + File.separator;
	}

	public InputStream readAsset(String filename) throws IOException {
		return assetManager.open(filename);
	}

	public InputStream readFile(String filename) throws FileNotFoundException {
		return new FileInputStream(externalStoragePath + filename);
	}

	public OutputStream writeFile(String filename) throws FileNotFoundException {
		return new FileOutputStream(externalStoragePath + filename);
	}
	
	/*
	 * このメソッドは Beginning Android Games 2 で追加されたようだ。
	 * 確かに設定ファイルのようなものであれば、ファイルの読み書きよりも、
	 * SharedPreferences の方が正にうってつけだ。
	 */	
	public SharedPreferences getPreferences() {
		return PreferenceManager.getDefaultSharedPreferences(context);
	}
}

音(出力)

BAG はインターフェースが Audio、実装が AndroidAudioとなっている。

さらに、Audio の補助クラスとして、効果音(Sound インターフェースとその実装クラスの AndroidSound)・音楽(Music インターフェースとその実装クラスの AndroidMusic)が用意されている。

音に関しては、特にこれといった変更ポイントはなく、そのままインターフェースを省いて、直接、実装クラスにまとめた形となっている。

つまり、implements Audioimplements Soundimplements Music を除去して、AndroidAudio、AndroidSound、AndroidMusic をそのまま(名前を)Audio、Sound、Music クラスに昇格させただけなので、コードの掲載は割愛する。

※注意:Music クラスの implements OnCompletionListener は除去しないこと。

グラフィックス(出力)

BAG はインターフェースが Graphics、実装が AndroidGraphicsとなっている。

これについても音の場合と同様、基本的にはインターフェースを省いて直接実装クラスとしてまとめた形になる。インターフェースからは、


public static enum PixmapFormat {
	ARGB8888, ARGB4444, RGB565
}

はメンバーとして AndroidGames に移植するが、あとはただ AndroidGraphics から implements Graphics を除去し、これ自体(の名前)を Graphics クラスにしてしまう。

また Circle 描画のメソッドの追加は次のようになる:


public void drawCircle(int x, int y, int radius, int color) {
	paint.setColor(color);
	paint.setStyle(Style.FILL);
	canvas.drawCircle(x, y, radius, paint);
}

さらに、Graphics クラスで利用する Pixmap オブジェクトを定義する Pixmap クラスもインターフェース(Pixmap)と実装(AndroidPixmap)に分かれているが、インターフェースを省いて直接実装クラス(Pixmap)としてまとめればよい。


読解『A to Z』