我有一个正在绘制场景的 SurfaceView 画布。画布被转换以适应 1024x768 的逻辑场景大小(而实际屏幕为 800x480),并且还支持缩放/滚动导航。因为我不想在侧面出现黑色条纹(适合 4:3 到 16:9),所以我使用了不同的背景位图,它具有“拉伸”的侧面来覆盖比率差异。情节的另一个转折是我需要同时支持电话和桌子。对于平板电脑,我正在加载更高质量(尺寸)的图像,对于手机,我在从磁盘加载时缩小背景位图。下面是执行我想要的代码(尽管可能不是最好的方法),特别是,我感觉背景计算可以缓存到矩阵中以供以后使用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();
}