相关疑难解决方法(0)

android游戏循环vs渲染线程中的更新

我正在制作一款安卓游戏,目前我还没有达到我想要的性能.我在自己的线程中有一个游戏循环,用于更新对象的位置.渲染线程将遍历这些对象并绘制它们.目前的行为似乎是波涛汹涌/不均匀的运动.我无法解释的是,在我将更新逻辑放入自己的线程之前,我在onDrawFrame方法中,就在gl调用之前.在这种情况下,动画非常流畅,当我尝试通过Thread.sleep来限制我的更新循环时,它只会变得不连贯/不均匀.即使我允许更新线程进行狂暴(无睡眠),动画也是平滑的,只有当涉及Thread.sleep时它才会影响动画的质量.

我已经创建了一个骨架项目来查看是否可以重新创建该问题,下面是渲染器中的更新循环和onDrawFrame方法: Update Loop

    @Override
public void run() 
{
    while(gameOn) 
    {
        long currentRun = SystemClock.uptimeMillis();
        if(lastRun == 0)
        {
            lastRun = currentRun - 16;
        }
        long delta = currentRun - lastRun;
        lastRun = currentRun;

        posY += moveY*delta/20.0;

        GlobalObjects.ypos = posY;

        long rightNow = SystemClock.uptimeMillis();
        if(rightNow - currentRun < 16)
        {
            try {
                Thread.sleep(16 - (rightNow - currentRun));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的onDrawFrame方法:

        @Override
public void onDrawFrame(GL10 gl) {
    gl.glClearColor(1f, 1f, 0, 0); …
Run Code Online (Sandbox Code Playgroud)

android opengl-es game-loop thread-sleep

19
推荐指数
1
解决办法
1万
查看次数

使用OpenGL将游戏逻辑与Android的快节奏游戏分离的最佳方法是什么?

我一直在学习和制作小游戏,最近我决定尝试为Android开发游戏.

对我来说,从本机C++代码跳转到Android Java并不是那么难,但是让我头疼的是如何考虑如何将逻辑与渲染分开.

我一直在这里和其他网站上阅读:

最好不要为它创建另一个线程,因为Android肯定没有处理问题.

意思是代码是这样的:

public void onDrawFrame(GL10 gl) {
    doLogicCalculations();
    clearScreen();
    drawSprites();
}
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否是最好的方法.因为如果我将逻辑放在GLRenderer::onDrawFrame方法中,我不认为我会这样.据我所知,这个方法只是为了绘制,如果我把逻辑放在那里,我可能会减慢帧的速度.更不用说在我的理解中它伤害了POO的概念.

我认为使用线程可能就是这样,这就是我的计划方式:

主要活动:

public void onCreate(Bundle savedInstanceState) {
    //set fullscreen, etc

    GLSurfaceView view = new GLSurfaceView(this);
    //Configure view

    GameManager game = new GameManager();
    game.start(context, view);

    setContentView(view);
}
Run Code Online (Sandbox Code Playgroud)

游戏管理:

OpenGLRenderer renderer;
Boolean running;
public void start(Context context, GLSurfaceView view) {
    this.renderer = new OpenGLRenderer(context);
    view.setRenderer(this.renderer);

    //create Texturelib, create sound system...

    running = true;
    //create a thread to run GameManager::update()
}

public void update(){
    while(running){ …
Run Code Online (Sandbox Code Playgroud)

android opengl-es

14
推荐指数
2
解决办法
6807
查看次数

Android三重缓冲 - 预期的行为?

我正在调查我的应用程序的性能,因为我注意到它在滚动时丢弃了一些帧.我运行systrace(在运行4.3的Nexus 4上),并在输出中注意到一个有趣的部分.

一开始一切都很好.放大左侧部分,我们可以看到绘图从每个vsync开始,完成备用时间,并等到下一个vsync.由于它是三重缓冲的,因此应该将其绘制到一个缓冲区中,该缓冲区将在完成后发布在以下vsync上.

在放大屏幕截图中的第4个vsync上,应用程序执行了一些工作,并且绘制操作没有及时完成下一个vsync.但是,我们不会删除任何帧,因为之前的抽奖正在提前一帧.

在这种情况发生之后,绘制操作不能弥补错过的vsync.相反,每个vsync只启动一个绘制操作,现在它们不再向前绘制一个帧.

放大右侧部分,该应用程序会做更多工作并错过另一个vsync.由于我们没有向前绘制一个帧,所以实际上帧丢失了.在此之后,它会回到前方画一帧.

这是预期的行为吗?我的理解是,如果你错过了一个vsync,三重缓冲允许你恢复,但是这种行为看起来像每两个你错过的vsyncs一次丢帧.


跟进问题

  1. 此屏幕截图的右侧,应用程序实际上渲染缓冲区的速度比显示器消耗它们的速度快.在performTraversals#1(屏幕截图中标记)期间,假设正在显示缓冲区A并且正在渲染缓冲区B. #1在vsync之前完成,并将缓冲区B放入队列中.此时,应用程序是否应该能够立即开始渲染缓冲区C?相反,performTraversals#2直到下一个vsync才开始,浪费了宝贵的时间.

  2. 同样地,我对左侧对waitForever的需求感到有些困惑.假设正在显示缓冲区A,缓冲区B在队列中,并且正在渲染缓冲区C. 当缓冲区C完成渲染时,为什么不立即将它添加到队列中?相反,它会执行waitForever,直到从队列中删除缓冲区B,此时它会添加缓冲区C,这就是为什么无论应用程序渲染缓冲区有多快,队列似乎始终保持大小为1.

performance android systrace

9
推荐指数
1
解决办法
2774
查看次数

Slick2D游戏速度在变化

我使用Swing创建了一个游戏,它有点不可靠,所以我开始使用Slick2D游戏引擎重新制作它,我遇到了问题.

每次调用更新方法时,游戏的背景在屏幕上以一定的像素滚动.这样可以加速和减速,因此背景会非常快速地移动,然后非常慢,并且会保持波动.

我试过*delta(它监视刷新率,我想!)我的值移动背景,但因为这不会给我一个确切的值我可以用来将背景重置到左侧(2背景移动)从右到左.左手一个向右移动-800像素).

造成这种情况的原因是什么?我如何克服它?

谢谢

java performance game-engine slick2d

1
推荐指数
1
解决办法
3711
查看次数