iモード携帯電話用Java(iアプリ) Part 6
だからそこで擬似BG面(略
キャッシュ用のオフスクリーンイメージを持つ自前ImageMapを構築するのですよ。
描画時には4回のdrawImageで循環スクロールも可能。
DirectDrawなんかでよく使われてた手です。
こっちのほうが速くて取り扱いが素直なんで、はっきり言ってImageMapクラスは無用。
こんなクラスを作る。
import com.nttdocomo.ui.Graphics;
import com.nttdocomo.ui.Image;
/*
* ゲームの背景に使用する、16×16ドットのパターンを組み合わせたイメージを保持するクラスです。
* 家庭用ゲーム機においてBG面と呼ばれているものにほぼ相当します。
* マップは20×20パターンで水平・垂直方向に循環していて、
* ドット単位で任意の座標から表示できます。
* パターンには256×128ドットのパターンセットイメージを使用し、
* 左上から順番に、パターン0〜127に割り当てられます。
*/
public class Bg {
private Image cacheImage;
private Graphics cacheGraphics;
int[][] map = new int[20][20];
private Image patternSetImage;
public Bg(Image patternSetImage) {
this.patternSetImage = patternSetImage;
cacheImage = Image.createImage(320, 320);
cacheGraphics = cacheImage.getGraphics();
}
public void put(int x, int y, int pattern) {
x %= 20;
y %= 20;
// 既にキャッシュイメージに同パターンが書き込まれているなら更新しない。
if (map[y][x] != pattern) {
map[y][x] = pattern;
int sx = (pattern & 0xf) << 4;
int sy = (pattern >> 4) << 4;
cacheGraphics.drawImage(patternSetImage, x << 4, y << 4, sx, sy, 16, 16);
}
}
public void draw(Graphics g, int x, int y) {
x %= 320;
y %= 320;
int dx = 320 - x;
int dy = 320 - y;
g.drawImage(cacheImage, 0, 0, x, y, dx, dy);
g.drawImage(cacheImage, dx, 0, 0, y, x, dy);
g.drawImage(cacheImage, 0, dy, x, 0, dx, y);
g.drawImage(cacheImage, dx, dy, 0, 0, x, y);
}
}
これでRPGのマップなどをスムーズスクロールさせた場合、
1フレームあたりのdrawImageの平均呼び出し回数は、ほぼスクロールするドット数+4回。
あ、ちなみに
> ImageクラスのcreateImage()メソッドで作れるイメージの最大サイズは画面サイズ。
とかいうふざけた機種(DとかDとかDとか)ではそのままでは動きません。
ていうか、こんなもん容赦なく切り捨ててやるのがメーカーへの親心だと思います。
まあ、対応してもクラスサイズが約300バイト増えるだけですけどね。