9

为了简单起见,我们假设我正在为 Android 制作一个简单的 Pong 克隆游戏。让我们假设它只能在横向模式下播放。(暂时忽略方形电话)。

我希望游戏在每部手机上的比例相同,如果你在 QVGA 手机上截取游戏截图,并将截图调整为 WVGA 大小,它看起来与游戏几乎相同看WVGA手机。换言之,球拍的宽度应始终为屏幕宽度的 1/32,球的直径应始终为屏幕宽度的 1/16。

绘制应用程序的正确方法是什么?它将在标准 SurfaceView 中运行,该 SurfaceView 将被绘制到Canvas.

假设我有一个用于桨、球和游戏字体(记分牌、主菜单)的高分辨率 PNG。

我是否找出物理分辨率,然后缩放Canvas通孔scale(float sx, float sy)以使我的所有画布(在 QVGA 和 WVGA 上)具有相同的虚拟分辨率,然后在每个屏幕尺寸的每个位置绘制完全相同的图元?

或者我可以在画布中以某种方式使用与密度无关的像素(倾角)吗?

4

3 回答 3

4

我只玩过一次画布功能,然后全部切换到opengl,但逻辑保持不变(我认为)。

第一个问题,您需要保持一部手机与另一部手机的比率不变。在我的应用程序中,我在每一侧添加了“黑带”效果。在 onSurfaceChanged 中,您需要计算一个比率,该比率将允许您确定必须在每一侧移除多少空间以保持绘图的一致外观。这将为您提供一个 delta X 或 Y 以应用于您的所有抽奖 以下代码是我从 ogl 版本改编而来的,因此可能需要稍微调整一下

@Override
   public void onSurfaceChanged(int w, int h){
   float ratioPhysicScreen = nativeScreenResoltionW/nativeScreenResoltionH;
   float ratioWanted = GameView.getWidth()/GameView.getHeight();
   if(ratioWanted>ratioPhysicScreen){
      newHeight = (int) (w*GameView.getHeight()/GameView.getWidth());
      newWidth = w;
      deltaY = (int) ((h-newHeight)/2);
     deltaX = 0;
   }else{
      newWidth = (int) (h/GameView.getHeight()*GameView.getWidth());
      newHeight = h;
      deltaX = (int) ((w-newWidth)/2);
      deltaY = 0;       
}

那么您还希望能够通过知道画布上的大小以及实际大小以及 image.getWidth() (图片的实际大小)和 a 之间的差异来在画布上绘制图片image.getScaledWidth(canvas) 为您提供 dp 中元素的大小,这意味着它将出现在屏幕上的大小)很重要。看看下面的例子。

public class MainMenuView extends PixelRainView{
private Bitmap bmpPlay = null;
private float playLeft = 0;
private float playRight = 0;
private float playBottom = 0;
private float playTop = 0;

public MainMenuView(Context context, AttributeSet attrs) {
    super(context,attrs);
}



@Override
public void unLoadBitmaps() {
    super.unLoadBitmaps();
    if(bmpPlay != null){
        bmpPlay.recycle();
        bmpPlay = null;
    }
}



@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(bmpPlay == null){
        bmpPlay = getBitmapFromRessourceID(R.drawable.play_bt);
        playLeft = (this.getWidth()-bmpPlay.getScaledWidth(canvas))/2; 
        playRight = playLeft + bmpPlay.getScaledWidth(canvas);
        playTop = (this.getHeight()-bmpPlay.getScaledHeight(canvas))/2;
        playBottom = playTop+bmpPlay.getScaledHeight(canvas);
    }
    canvas.drawBitmap(bmpPlay,playLeft, playTop, null);

    }       
}


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
}



@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        float x = event.getX();
        float y = event.getY();
        //test central button
        if(x>playLeft && x<playRight && y<playBottom && y>playTop){
            Log.e("jason", "touched play");
            PixelRainView.changeView(R.layout.composedlayoutgroup);
        }
    return super.onTouchEvent(event);
}
}

这应该可以解决您所有跨平台的比率问题我建议使用 opengl,因为它可以简化您保持恒定方面的需求,但我想这不是一个选择^^

希望这对你有足够的帮助

于 2010-11-19T03:09:39.600 回答
2

使用蘸水和油漆桨而不是使用 PNG

于 2010-11-15T10:22:29.733 回答
-1

我认为只有 3 种标准分辨率可用(ldip、mdip、hdip),并且您应该为每种分辨率都有一个资源文件夹。

http://developer.android.com/guide/practices/screens_support.html

如果您手动缩放 PNG 以适应 3 种可用分辨率中的每一种,手机应以透明方式加载特定资源文件夹

于 2010-11-15T10:40:35.033 回答