如何正确缩放的游戏在Android [英] How to properly scale a game on Android

查看:174
本文介绍了如何正确缩放的游戏在Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为简单起见,我们假设我在做一个简单的乒乓克隆游戏为Android。让我们假设它只会播放在横向模式。 (忽略方形手机现在)。

for the sake of simplicity let's assume that I'm making a simple Pong clone game for Android. Let's assume that it would only be playable in the landscape mode. (ignore square phones for now).

我想比赛看在相同的比例每部手机上,在某种程度上,如果你把上QVGA的手机游戏的截图,并调整截图WVGA分辨率,它看起来几乎一样将游戏旁观WVGA手机。换句话说,该桨叶的宽度应该总是屏幕宽度的1/32,球的直径应始终是屏幕宽度的1/16。

I'd like the game to look in the same scale on each phone, to the extent that if you took a screenshot of the game on QVGA phone, and resized the screenshot to WVGA size, it would look almost the same as would the game look on WVGA phone. In other words, the paddle's width should always be 1/32 of the screen width, the ball's diameter should always be 1/16 of the screen width.

什么是正确的方法来画的应用程序?这将在标准的SurfaceView,将被绘制到画布运行。

What would be the proper way to paint the application? It would run in standard SurfaceView that would be drawn onto a Canvas.

让我们说,我有一个高分辨率的PNG格式的桨,球和比赛字体(记分牌,主菜单)。

Let's say that I have a high-resolution PNGs for the paddle, ball and for the game font (scoreboard, main menu).

我发现的物理分辨率,然后缩放画布通过规模(浮动SX,浮动SY)让所有我的画布(上QVGA和WVGA)具有相同的虚拟的分辨率,然后得出完全相同的原语对每个屏幕尺寸每个位置?

Do I find out the physical resolution, then scale the Canvas via scale(float sx, float sy) to make all my Canvases (on QVGA and WVGA) have the same virtual resolution, and then draw exactly the same primitives on each position on each screen size?

或者,我可以用密度无关像素(DIP)以某种方式在画布?

Or can I use density-independent pixels (dip) somehow in the Canvas?

推荐答案

我只玩过一次的抽奖画布功能,然后切换所有的OpenGL但逻辑保持不变(我认为)。

I only played once with the draw canvas functions and then switched all to opengl but the logic stays the same (I think).

第一个问题你要保持一个恒定的比例形成一个手机到另一个。 在我的应用程序,我想补充,每边一个黑带的效果。 在onSurfaceChanged,你要计算一个比例,这个比例将允许你确定你有多大的空间,以消除每侧保持一致方面绘图。这会给你一个增量X或Y适用于所有的画 以下code是我从OGL版本调整,因此可能需要tweeked有点

first issue you'll want to keep a ratio constant form one phone to the other. in my app I add a " black band" effect on each side. in onSurfaceChanged, you'll want to calculate a ratio, this ratio will allow you to determine how much space you have to remove on each side to keep a consistent aspect to your drawing. this will give you a delta X or Y to apply to all your draws the following code is something I adapted from the ogl version so it might need to be tweeked a bit

@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的元素,这意味着有多大它就会出现在屏幕上的大小)是很重要的。看下方的例子。

then you'll also want to be able to draw your pictures on the canvas by knowing there size as well on the canvas than there real size and that where the difference in between image.getWidth() (actual size of the picture) and a image.getScaledWidth(canvas) which give you the size of the element in dp which means how big it will appear on the screen) is important. look at the example underneath.

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的,因为它可以简化您的需要保持一个恒定的方面,但我想它不是一个选项^^

This should solve all your ratio problem cross plateforms I would suggest opengl because it will simplify your need for keeping a constant aspect but I guess its not an option ^^

希望这有助于你足够

这篇关于如何正确缩放的游戏在Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆