Android游戏滚动背景

时间:2011-02-04 17:57:59

标签: android background drawing 2d

我只想弄清楚在Android设备上运行scolling背景的最佳方法。到目前为止我的方法......它非常滞后。我使用线程,我认为这不是Android平台的最佳选择

@Override
    public void run() {
        // Game Loop
        while(runningThread){
            //Scroll background down
            bgY += 1;

            try {
                this.postInvalidate();
                t.sleep(10);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

其中onDraw函数中的postinvalidate只是向下推送背景图像

canvas.drawBitmap(backgroundImage, bgX, bgY, null);

提前致谢


更新

我发现了问题所在。事实上,我的播放器更新与背景滚动相同的速率(使其看起来波涛汹涌)。从上到下。这是因为两者都被绘制在同一个函数中。我不太确定如何解决这个问题,并且对任何帮助都会感激不尽。即使玩家移动与地图滚动分开处理

另外,我如何控制调用onDraw(画布)的速度?

提前致谢。

但是,我已经为具有相同问题的任何人修补了不同的运行循环。这部分来自Google上的jetboy示例。

以下是我在surfaceview中的内部课程

class MapThread extends Thread{
    private Map map;
    private SurfaceHolder holder;
    private boolean run = false;

    public MapThread(Map map, SurfaceHolder holder){
        this.holder = holder;
        this.map = map;
        setRunning(true);
    }

    public void setRunning(boolean run){
        this.run = run;
    }

    @Override
    public void run(){
        while(run){
            try{
                Canvas c = null;

                 try {
                       c = holder.lockCanvas(null);
                       synchronized (holder) {
                            map.onDraw(c);
                     }
                 } finally {

                     if (c != null) {
                         holder.unlockCanvasAndPost(c);
                     }
                 }
        }
    }
}

https://gamedev.stackexchange.com/questions/8127/android-game-scrolling-background

3 个答案:

答案 0 :(得分:3)

在屏幕上使用SurfaceView实施图。它允许您更多地控制绘制内容和何时绘制。

  

SurfaceView是View的一个特殊子类,它在View层次结构中提供专用的绘图表面。目的是将此绘图表面提供给应用程序的辅助线程,以便应用程序不需要等到系统的View层次结构准备好绘制。

基本设计是在一个while循环中连续绘制一个surfaceview。然后添加一个if语句,如果计时器线程告诉您绘制时间,则其条件为true。比方说,每30ms绘制一次位图。这将为您提供大约33 fps。

现在您可能还有另一个计时器线程,它告诉您何时更新bgX或bgY值。比如说每隔60ms就会设置一个布尔值updateFlag = true;然后在你的主线程中,你有一个if语句检查这个标志,将它设置为false,并更新你的bgX和bgY值。通过精确控制计时器和bgX / bgY增量,您应该能够生成平滑的动画。

查看Google提供的LunarLander源代码是个好主意。

答案 1 :(得分:0)

要记住的一件事是睡眠非常不准确。要解决这个问题,你可以准确地记录睡眠过程中经过的时间,并相应地更新你移动的东西。

您的代码不清楚,但您需要确保所有UI更新都在UI线程中发生。

您需要在UI线程之外进行计时,否则UI将永远不会更新。还有其他的计时方法,比如使用Handler可以稍微清洁一点,但我认为它们的开销可能对你要做的事情有点多。我认为一个简单的线程具有最少的开销。

答案 2 :(得分:0)

我在SpaceQuestAlpha游戏的第二级使用此方法。这使得一个无缝的卷轴。

我使用下面两行来设置原始位置。

              moony=0;
              moon2y=-(heighty); 

然后这些行增加背景图像的两个版本。一个从0开始,一个从负屏幕高度开始。每当其中一个图像低于屏幕底部时,它就会向上移动两倍高度以将其移回原位。我正在使用表面视图,没有延迟问题。

              moony+=5;
              moon2y+=5;


                 if(moon2y>=heighty) {moon2y=moon2y-(heighty*2);}
                     canvas.drawBitmap(lavabackground, 0, moon2y, null); 
                 if(moony>=heighty){moony=moony-(heighty*2);}
                     canvas.drawBitmap(lavabackground, 0, moony, null);