シーンを描画している SurfaceView キャンバスがあります。キャンバスは、1024x768 の論理シーン サイズ (実際の画面は 800x480) に対応し、ズーム/スクロール ナビゲーションをサポートするように変換されます。側面に黒いストライプを入れたくなかったので (4:3 から 16:9 に適合)、比率の違いをカバーするために側面を「引き延ばした」別の背景ビットマップを使用しています。プロットのもう 1 つのひねりは、電話とテーブルの両方をサポートする必要があることです。タブレットの場合は高品質 (サイズ) の画像を読み込み、携帯電話の場合はディスクから読み込むときに背景のビットマップを縮小しています。以下は、私が望むことを実行するコードです (おそらく最善の方法ではありません)。特に、バックグラウンド計算をマトリックスにキャッシュして、後で使用できると感じています。canvas.drawBitmap(Bitmap, Matrix, Paint);
(また、キャンバスをこれらのオフセットで変換しても、 drawBitmap(Bitmap, left, top, Paint) の同等の位置を取得できませんでした。その理由も知りたいです)。
これは描画ルーチンです:
public void draw(Canvas canvas) {
canvas.save();
float midX = width/2;
float midY = height/2;
// zoom out to fit logical view, and translate for future
// sprite drawing with logical coordinates
// x,y and zoom are calculated in on init and updated in touch events
canvas.translate(x, y);
canvas.scale(zoom, zoom, midX, midY);
// background part
if(back != null && !back.isRecycled()) {
// todo: these can probably be pre-calculated for optimization
// todo: but so far I couldn't get it right..
if(bgMatrix != null) { // this is where I'm thinking of using the cached matrix
canvas.drawBitmap(back, bgMatrix, paint);
}
else {
float offsetW = (width-back.getWidth())/2;
float offsetH = (height-back.getHeight())/2;
canvas.save();
// bgScaleFactor is calculated upon setting the bg bitmap
// it says by how much we need to scale the image to fill the canvas
// taking into account the image (possible) downscale
canvas.scale(bgScaleFactor, bgScaleFactor, midX, midY);
// this doesn't work: canvas.postTranslate(offsetW, offsetH) and use 0,0 for next draw
canvas.drawBitmap(back, offsetW, offsetH, paint);
// todo: here I would like to save a matrix which represents
// how the back bitmap was drawn onto the canvas
// so that next time these calculations can be avoided
// this fails: bgMatrix = canvas.getMatrix();
canvas.restore();
}
// draw scene shapes on transformed canvas
if(shapes != null){
shapes.onDraw(canvas);
}
canvas.restore();
}