如何在Android上正确扩展游戏

时间:2010-11-15 10:19:59

标签: android resolution android-canvas

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

我希望游戏能够在每部手机上以相同的比例观看,如果您在QVGA手机上截取游戏截图,并将屏幕截图重新调整为WVGA尺寸,它看起来几乎与这款游戏会在WVGA手机上显示吗?换句话说,桨的宽度应始终为屏幕宽度的1/32,球的直径应始终为屏幕宽度的1/16。

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

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

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

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

3 个答案:

答案 0 :(得分: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()之间的差异(图片的实际尺寸) )和一个image.getScaledWidth(画布),它给你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,因为它会简化你对保持恒定方面的需要,但我想它不是一个选项^^

希望这对你有所帮助

答案 1 :(得分:2)

使用蘸料并涂抹桨而不是使用PNG

答案 2 :(得分:-1)

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

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

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