iモード携帯電話用Java(iアプリ) Part 6

このエントリーをはてなブックマークに追加
258デフォルトの名無しさん
だからそこで擬似BG面(略

キャッシュ用のオフスクリーンイメージを持つ自前ImageMapを構築するのですよ。
描画時には4回のdrawImageで循環スクロールも可能。
DirectDrawなんかでよく使われてた手です。

こっちのほうが速くて取り扱いが素直なんで、はっきり言ってImageMapクラスは無用。
259258:04/09/14 11:10:04
こんなクラスを作る。

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();
    }
    
260258:04/09/14 11:11:39
    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);
        }
    }
    
261258:04/09/14 11:12:02
    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回。
262258:04/09/14 11:17:43
あ、ちなみに

> ImageクラスのcreateImage()メソッドで作れるイメージの最大サイズは画面サイズ。

とかいうふざけた機種(DとかDとかDとか)ではそのままでは動きません。
ていうか、こんなもん容赦なく切り捨ててやるのがメーカーへの親心だと思います。

まあ、対応してもクラスサイズが約300バイト増えるだけですけどね。