2010-11-15 57 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