为什么我的android游戏循环中的deltatime随机变得非常大?

时间:2016-02-19 10:42:08

标签: java android android-canvas surfaceview game-loop

我想开始为Android编写一个简单的2D游戏,并决定在cavas上绘制所有内容。但是我的游戏环已经不能正常工作了。任何人都知道为什么我的游戏循环中的deltatime(看下面)会随机变得非常大并导致一个口吃的画布?

@Override
    public void run(){
        while(running){
            if (!holder.getSurface().isValid()){
                continue;
            }
            float deltaTime;
            int sleepTime;

            Canvas c = holder.lockCanvas();
            synchronized (holder) {
                long startTime = System.currentTimeMillis();

                //update
                background.update();
                bomberman.update();

                //draw
                if (background.getX()+background.getiWidth() >= 0 || (background.getX() >= 0 && background.getX() <= getWidth()))
                    c.drawBitmap(background.getBackground(), background.getX(), 0, null);
                if (background.getX()+background.getiWidth()+background.getiWidth() >= 0 || (background.getX()+background.getiWidth() <= getWidth()))
                    c.drawBitmap(background.getBackground(), (background.getX()+background.getBackground().getWidth()), 0, null);
                c.drawBitmap(bomberman.getImage(), bomberman.getX()-(bomberman.getImage().getWidth()/2), bomberman.getY()-(bomberman.getImage().getHeight()/2), null);  

                deltaTime = (System.currentTimeMillis() - startTime);
                sleepTime = (int) (FRAME_PERIOD - deltaTime);

                Paint paint = new Paint();
                paint.setColor(Color.BLACK);
                paint.setStyle(Style.FILL);
                paint.setTextSize(40);
                c.drawText("deltaTime:" + deltaTime, 10, 50, paint);
                c.drawText("sleepTime:" + sleepTime, 10, 100, paint);
            }
            holder.unlockCanvasAndPost(c);

            //faster
            if(sleepTime > 0){
                try{
                    Thread.sleep(sleepTime);
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //slower
            while(sleepTime < 0){
                //update
                background.update();
                bomberman.update();
                sleepTime += FRAME_PERIOD;
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

不要使用System#currentTimeMillis()。在Android上,它使用设备的挂钟&#34;作为它的时间来源。如果网络决定更新时钟,则当前时间将向前或向后跳跃。

由于您只对帧之间的时间差异感兴趣,请改用System#nanoTime()。它使用单调时钟。

FWIW,您可以使用Choreographer(API 16+)来改善游戏循环,以获得实际的显示刷新时间,而不是将显示队列填满。请参阅explanation here