【问题标题】:How to properly scale a game on Android如何在 Android 上正确扩展游戏
【发布时间】:2010-11-15 10:19:59
【问题描述】:

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

我希望游戏在每部手机上都以相同的比例显示,如果你在 QVGA 手机上截取游戏截图,并将截图调整为 WVGA 大小,它看起来几乎与游戏会在 WVGA 手机上看吗?也就是说,球拍的宽度应始终为屏幕宽度的 1/32,球的直径应始终为屏幕宽度的 1/16。

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

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

我要找出物理分辨率,然后通过scale(float sx, float sy) 缩放Canvas 以使我所有的画布(在QVGA 和WVGA 上)都具有相同的虚拟 分辨率,然后准确地绘制每个屏幕尺寸上每个位置的相同基元?

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

【问题讨论】:

    标签: android resolution android-canvas


    【解决方案1】:

    我只玩过一次画布功能,然后全部切换到 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(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,因为它可以简化您保持恒定方面的需求,但我想这不是一个选择 ^^

    希望这对你有足够的帮助

    【讨论】:

      【解决方案2】:

      使用蘸水和画桨而不是使用 PNG

      【讨论】:

      • 如何在像 drawLine() 这样的 Canvas 方法中使用 dips?
      • 好吧,让我们忘记 Pong 克隆,让我们谈谈像 Pac-man 或 SimCity 这样的基于瓷砖的游戏。所以有些图块存储在 PNG 中,而 Pong 可能是一个太简单的例子。
      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多