Surfaceview - 以不同的fps以相同的速度移动位图

时间:2015-03-09 19:19:03

标签: java android bitmap

我有很多位图我在一个surfaceview上移动,有时候fps掉落会使位图移动速度变慢或超快随机,我看到有人使用系统时间或类似的东西发布解决方案,但找不到它,所以我想知道是否有人知道即使fps下降我怎么能使速度相同。

编辑:

我想也许我可以使用以下方式计算时间:

int myFPS;
        if(gameLoopThread.startTime!=System.currentTimeMillis())
     myFPS=(int) (1000 / (gameLoopThread.startTime-System.currentTimeMillis())*-1);
        else
            myFPS=25;
        float new2=1;
     new2=25/myFPS;

然后只是多个

currentSpeed.y += speed*new2;

但它没有成功,因为fps显示错误,但我认为这是做到这一点的方法?或者我可能错了..

2 个答案:

答案 0 :(得分:1)

我如何跟踪fps 1000毫秒/ 25 = 40 fps

在while循环开始时,请确保您有时间。

long starttime  = System.currentTimeMillis();

然后在所有内容完成并呈现后,您将再次获得时间。

long endtime  = System.currentTimeMillis();

从结束时间中减去开始时间,然后除以1000乘以-1得到运行状态可以在一秒内循环的次数。

int MyFPS = (int) (1000 / (starttime - endtime) * -1);

如果您的答案是75,那么您将以75fps的速度运行。

你只需要让线程休眠35毫秒就可以达到40fps。 追踪我从未做过的低fps。希望这会有所帮助。

@Override
public void run() {
    while (THREAD) {
        long starttime  = System.currentTimeMillis();
        if (!myHolder.getSurface().isValid())
            continue;
        Update();         <----Running the game.
        Main_Render();    <----Rendering graphics.
        long endtime  = System.currentTimeMillis();
        int MyFPS = (int) (1000 / (starttime - endtime) * -1);
            if (MyFPS >= 25) {
                sleep_length = MyFPS - 25;
                try {
                    Thread.sleep(sleep_length);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }
}

答案 1 :(得分:1)

更新

单线程循环

为了使游戏的速度保持恒定,如果循环迭代花费的时间超过预期,则必须在某些时候跳过渲染。

while(isRunning){

            beginTime = SystemClock.uptimeMillis(); 
            framesSkipped = 0;

            //Update game state
            update();

            render();

            //how long we took to update and render
            loopTime = SystemClock.uptimeMillis() - beginTime;
            //calculate how long to sleep
            sleepTime = loopPeriod - timeDiff; 

                //All work was done on time.
                if (sleepTime > 0) { 
                    try { 
                        Thread.sleep(sleepTime); 
                    } catch (InterruptedException e) {} 
                } 

                //We were too slow. Update without rendering.
                while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) { 
                  update();
                    //make sure we don't keep looping here.
                    sleepTime += loopPeriod; 
                    framesSkipped++; 
                }
            }
        }

此循环优先处理您的逻辑更新,如果我们落后则跳过渲染。好处是,您的游戏角色会不断更新并独立于可能的帧速率下降。

两个帖子:(原始答案)

确保在低FPS下稳定移动的另一种方法是在一个线程中进行渲染,在另一个线程中进行逻辑运算。

游戏逻辑线程的示例:

while(isRunning){

        startTime = SystemClock.uptimeMillis();

        //update game logic, no rendering.
        update();

        //time it took to update the game state.
        loopTime = SystemClock.uptimeMillis() - startTime;

        //pausing here to make sure we update the right amount per second.
        if(loopTime < updatePeriod){
            try {
                Thread.sleep(updatePeriod-updateTime);
            } catch (InterruptedException e) {
                Log.e(TAG,"Interrupted while sleeping");
            }
        }
    }

更新周期是允许单次更新迭代的毫秒数。

updatePeriod = 1000 / ups;

ups =每秒更新。如果您的游戏最高速度为60 fps,请使用60次。

请注意,这两个循环都是非常基本的,并且无需修改,不适合高级应用程序。

另外,使用SystemClock.uptimeMillis();它更可靠。