Android - 游戏循环中的主动渲染?

Posted

技术标签:

【中文标题】Android - 游戏循环中的主动渲染?【英文标题】:Android - active rendering in game loop? 【发布时间】:2015-06-19 19:11:49 【问题描述】:

android上的游戏循环中渲染的最佳方式是什么? 当我在java中渲染时,我知道如何做到这一点。我创建缓冲区策略,而不是图形,我绘制,而不是处理和翻转缓冲区。有类似的 Andorid 吗? 我查看了视图,但是当我尝试大量绘制时它无法正常工作。我查看了 SurfaceView,但我不明白如何刷新它的绘图。 invalidate 打破循环, postInvalidate 不起作用。我锁定画布并在其上绘图,然后从表面视图解锁并以“创建”方法发布(在循环中锁定画布不起作用,仅出现应用程序中的白屏)。所以我不明白。 在 Android 中进行大量渲染的最有效方式是什么?

【问题讨论】:

【参考方案1】:

在 SurfaceView 中渲染的常用方法是通过其SurfaceHolder。

通常你会通过持有人得到一个Canvas并在上面画画:

 SurfaceHolder surfaceHolder = surfaceView.getHolder();
 Canvas canvas = surfaceHolder.getSurface().lockCanvas();

 //draw in the canvas
 canvas.drawPoint(...);

 surfaceHolder.unlockCanvasAndPost(canvas);

正确的做法是在单独的线程(渲染线程)中循环lockCanvas()unlockCanvasAndPost()(包括)之间的所有代码,并在循环内使用Thread.sleep()控制帧率。

编辑

有很多方法可以控制渲染线程的FPS,这是一个基本的方法,只需将想要的FPS设置为一个常数即可:

public class RenderThread extends Thread 
  private boolean running;
  private final static int MAX_FPS = 30;    
  private final static int FRAME_PERIOD = 1000 / MAX_FPS;   

  @Override
  public void run() 
    long beginTime;
    long timeDiff;
    int sleepTime;

    sleepTime = 0;

    while (running) 
        beginTime = System.currentTimeMillis();

        //RENDER

        // How long did the render take
        timeDiff = System.currentTimeMillis() - beginTime;
        // calculate sleep time
        sleepTime = (int)(FRAME_PERIOD - timeDiff);

        if (sleepTime > 0) 
            try 
                Thread.sleep(sleepTime);    
             catch (InterruptedException e) 
        
     
   

如果你搜索游戏循环,有很多references。

【讨论】:

它有效,但只有当我创建单独的线程以在surfaceview上绘制时。但是这样做我无法计算 fps 和 delta 来使我的动画更流畅。我找不到解决该问题的正确方法。例如,我会很感激。 我已经用一个例子编辑了答案,也许它会有所帮助。

以上是关于Android - 游戏循环中的主动渲染?的主要内容,如果未能解决你的问题,请参考以下文章

PlayN - iOS 上的渲染性能不佳

为啥游戏循环渲染的次数多于更新的次数

Dart 2 中的最佳渲染循环是啥?

如何将 UI 与 C# 中的渲染分开?

使用 ImageIcon 磁贴在 JPanel 上进行主动渲染? #Java

自定义选项卡式页面渲染器 Xamarin Android