2010-11-15 55 views
9

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

我希望游戏在每部手机上都以相同的比例显示,如果您在QVGA手机上截取了游戏截图并将屏幕截图重新调整为WVGA大小,它看起来几乎相同WVGA手机上的游戏一样。换句话说,桨的宽度应该总是屏幕宽度的1/32,球的直径应该总是屏幕宽度的1/16。

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

比方说,我有一个高分辨率PNG的桨,球和游戏字体(记分牌,主菜单)。

才能知道的物理分辨率,然后通过scale(float sx, float sy)缩放Canvas,使我的画布(上QVGA和WVGA)具有相同的虚拟分辨率,然后画在每个屏幕上的每个位置完全相同的图元尺寸?

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

回答

4

我只能用抽签的画布功能播放一次然后切换到opengl,但逻辑保持不变(我认为)。

第一个问题,你会想保持一个电话的比例不变。 在我的应用程序中,我在每边添加了一个“黑带”效果。在onSurfaceChanged中的 ,你会想要计算一个比率,这个比例将允许你确定你必须在每一边去掉多少空间来保持你的绘图的一致性。这会给你一个增量X或Y适用于所有的绘制 下面的代码是我改编自OGL版本,所以它可能需要tweeked有点

@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(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); 
} 
} 

这应该解决你所有的问题比跨plateforms 我会建议OpenGL的,因为这将简化保持恒定的方面你的需要,但我想它不是一个选项^^

希望这有助于你足够

2

使用骤降和画桨而是采用PNG格式

+0

如何在drawLine()之类的Canvas方法中使用下拉菜单? – Axarydax 2010-11-15 11:22:09

+0

好吧,让我们忘掉Pong克隆,让我们来谈谈像Pac-man或者SimCity这样的基于瓦片的游戏吧。所以有PNG存储的图块,而Pong可能太简单了。 – Axarydax 2010-11-15 11:26:10