android游戏开发

游戏循环是每个游戏的心跳。 到目前为止,我们仅使用了非常简单的一种(您可以在此处找到),无法控制我们更新游戏状态的速度或速度以及要渲染的帧。

概括地说,最基本的游戏循环是while循环,该循环不断执行一些指令,直到我们发出信号指示完成为止,通常是通过将一个称为running的变量设置为false来完成

boolean running = true;
while (!running)
{updateGameState();displayGameState();
}

上面的代码盲目运行,无需担心时间和资源。 如果您使用的设备较快,则其运行速度将非常快;如果设备较慢,则其运行速度将较慢。

updateGameState()更新游戏中每个对象的状态,而displayGameState()将对象渲染为图像,并显示在屏幕上。

我们在这里应该考虑两件事:FPS和UPS。

FPS每秒 帧数每秒调用displayGameState()的次数。
UPS每秒更新每秒调用updateGameState()的次数。

理想情况下,每秒调用更新渲染方法的次数相同(最好不低于每秒20-25次)。 25 FPS通常在电话上就足够了,因此我们人类不会注意到动画缓慢。

例如,如果我们以25 FPS为目标,则意味着我们必须每40毫秒( 1000/25 = 40毫秒,1000毫秒= 1 秒)调用displayGameState()方法。 我们需要记住,在显示方法之前也要调用updateGameState() ,并且要使我们达到25 FPS,我们必须确保更新– 显示序列恰好在40毫秒内执行。 如果所需时间少于40毫秒,则我们的FPS较高。 如果花费的时间更多,那么我们的游戏运行速度会更慢。

让我们看一些示例,以更好地了解FPS。

下图正好显示了1 FPS。 它需要更新 - 渲染周期恰好执行一秒钟。 这意味着您将看到屏幕上的图像每秒更改一次。

每秒1帧

下图显示了10FPS。 更新渲染周期需要100毫秒。 这意味着图像每十分之一秒发生变化。

10 FPS

但是上述情况意味着更新渲染周期每隔1秒就会执行一次。 这是一个假设,我们无法控制周期执行的实际时间,或者可以吗? 如果我们有200个敌人,而每个敌人都向我们开枪怎么办? 我们需要更新每个敌人的状态及其子弹的状态,并在一次更新中检查是否有碰撞。 当我们只有两个敌人时,情况就不同了。 时间显然会有所不同。 渲染方法也是如此。 显然,渲染200个发射机器人比仅渲染2个要花费更多的时间。

那是什么情况呢? 我们可以有一个更新-渲染周期,它可以在不到100毫秒(1/10秒)的时间内完成,可以在完全100毫秒内完成,也可以在更长的时间内完成。 在功能强大的硬件上,它会比功能较弱的硬件上更快。 让我们看一下图。

该周期在所需的时间范围之前完成,因此在运行下一个周期之前,我们有少量的空闲时间。

有时间的框架

下图显示了一个落后的周期。 这意味着完成更新渲染周期所花费的时间大于所需的时间。 如果花费12毫秒,则意味着我们落后2毫秒(仍考虑10FPS)。 这可能会加剧,并且每个周期我们都会失去时间,游戏将缓慢运行。

过期帧

第一种情况是所需的。 这使我们有一些空闲时间在开始下一个周期之前做某事。 我们不需要做任何事情,所以我们只是告诉游戏循环在剩余时间段内进入睡眠状态,并在下一个周期到期时醒来。 如果我们不这样做,游戏将比预期的运行得更快。 通过引入睡眠时间,我们获得了恒定的帧速率

当循环落后时,第二种情况(我跳过了理想情况,因为它几乎从未发生过),需要使用不同的方法。

为了在游戏中达到恒定的速度,我们需要在需要时更新对象的状态。 想象一下,机器人以恒定的速度接近您。 您知道它是否在一秒钟内通过了屏幕的一半,因此还需要一秒钟才能到达屏幕的另一侧。 为了准确地计算位置,我们需要知道自上一个位置以来的时间增量以及机器人的当前速度,或者我们以恒定的间隔更新机器人的位置(状态)。 我将选择第二个,因为在游戏更新中使用三角洲可能会很棘手。 为了达到恒定的游戏速度,我们将不得不跳过显示帧。 游戏速度不是FPS!

检查下图。 在这种情况下, 更新渲染周期花费的时间比所需时间长,因此我们必须赶上。 为此,我们将跳过此帧的渲染并进行另一次更新,以免影响游戏速度。 我们将在下一帧进行正常循环,甚至需要一些时间来让CPU休息。

可变FPS的恒定游戏速度

上面的场景有很多变体。 您可以想象游戏更新需要一个以上的全帧。 在这种情况下,我们无法采取任何措施来保持游戏速度恒定,并且游戏运行速度会变慢。 我们可能必须跳过多个渲染以保持速度恒定,但是我们必须确保设置允许跳过的最大帧数,因为它可能需要花费很多更新才能赶上,并且如果我们跳过15帧,则意味着我们从游戏中损失了很多东西,这将是无法玩的。

MainThread.javarun()如下所示:

// desired fps
private final static int    MAX_FPS = 50;
// maximum number of frames to be skipped
private final static int    MAX_FRAME_SKIPS = 5;
// the frame period
private final static int    FRAME_PERIOD = 1000 / MAX_FPS; @Override
public void run() {Canvas canvas;Log.d(TAG, "Starting game loop");long beginTime;     // the time when the cycle begunlong timeDiff;      // the time it took for the cycle to executeint sleepTime;      // ms to sleep (<0 if we're behind)int framesSkipped;   // number of frames being skipped sleepTime = 0;while (running) {canvas = null;// try locking the canvas for exclusive pixel editing// in the surfacetry {canvas = this.surfaceHolder.lockCanvas();synchronized (surfaceHolder) {beginTime = System.currentTimeMillis();framesSkipped = 0; // resetting the frames skipped// update game statethis.gamePanel.update();// render state to the screen// draws the canvas on the panelthis.gamePanel.render(canvas);// calculate how long did the cycle taketimeDiff = System.currentTimeMillis() - beginTime;// calculate sleep timesleepTime = (int)(FRAME_PERIOD - timeDiff);if (sleepTime > 0) {// if sleepTime > 0 we're OKtry {// send the thread to sleep for a short period// very useful for battery savingThread.sleep(sleepTime);} catch (InterruptedException e) {}}while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {// we need to catch up// update without renderingthis.gamePanel.update();// add frame period to check if in next framesleepTime += FRAME_PERIOD;framesSkipped++;}}} finally {// in case of an exception the surface is not left in// an inconsistent stateif (canvas != null) {surfaceHolder.unlockCanvasAndPost(canvas);}} // end finally}
}

请仔细检查以上代码,因为它实现了图表背后的逻辑。 您可以在可下载的项目中找到完整的代码。

我喜欢另一种方法。 它是恒定的游戏速度,每秒最大帧数。 它使用插值法绘制状态,并且在下一次游戏更新之前还有剩余渲染时间的情况下,它会在快速硬件上发生。 这可以增强游戏的视觉效果,因为它可以使动画更加流畅,但是由于我们使用移动设备,因此给CPU休息可以节省大量电池。

有在游戏圈的真棒文章在这里 。 我个人理解游戏循环阅读本文,因此我强烈推荐它。 我能找到的最好的。

请注意,我还修改了Speed.java类中的默认值。 速度以单位/秒为单位。 因为我们将所需的FPS设置为50,这意味着速度将在每次更新时增加50 * speed.value。 若要具有40像素/秒的速度,则需要将每个刻度的速度增量设置为2(40 /(1000/50)= 2)。 换句话说,您需要机器人在每次游戏更新时(如果您每秒更新50个游戏)前进2个像素,以覆盖每秒40个像素。

在此处下载代码并使用它。

检查它,您将获得具有恒定帧速率的恒定游戏速度。

参考: “ 反对谷物 ”博客中我们JCG合作伙伴Tamas Jano的《 游戏循环 》。

不要忘记查看我们的新Android游戏 ArkDroid (以下屏幕截图) 。 您的反馈将大有帮助!
相关文章:
  • Android游戏开发教程简介
  • Android游戏开发–游戏创意
  • Android游戏开发–创建项目
  • Android游戏开发–基本游戏架构
  • Android游戏开发–基本游戏循环
  • Android游戏开发–使用Android显示图像
  • Android游戏开发–在屏幕上移动图像
  • Android游戏开发–测量FPS
  • Android游戏开发–雪碧动画
  • Android游戏开发–粒子爆炸
  • Android游戏开发–设计游戏实体–策略模式
  • Android游戏开发–使用位图字体
  • Android游戏开发–从Canvas切换到OpenGL ES
  • Android游戏开发–使用OpenGL ES显示图形元素(原语)
  • Android游戏开发– OpenGL纹理映射
  • Android游戏开发–设计游戏实体–状态模式
  • Android游戏文章系列

翻译自: https://www.javacodegeeks.com/2011/07/android-game-development-game-loop.html

android游戏开发

android游戏开发_Android游戏开发–游戏循环相关推荐

  1. android 左移动画_Android研究院之游戏开发Tween动画的实现(十九)

    今天和大伙讨论一下Android开发中的Tween动画的实现.首先它和上一章我们讨论的Frame动画同属于系统提供的绘制动画的方法.Tween动画主要的功能是在绘制动画前设置动画绘制的轨迹,包括时间, ...

  2. android cmake 打印_Android NDK 开发:CMake 使用

    1. 前言 当在做 Android NDK 开发时,如果不熟悉用 CMake 来构建,读不懂 CMakeLists.txt 的配置脚本,很容易就会踩坑,遇到编译失败,一个很小的配置问题都会浪费很多时间 ...

  3. android pcm频谱_Android音频开发(7):音乐可视化-FFT频谱图

    Android 音频开发 目录 一.演示 image 二.实现 实现流程: 使用MediaPlayer播放传入的音乐,并拿到mediaPlayerId 使用Visualizer类拿到拿到MediaPl ...

  4. android camera移动方向_Android Camera开发系列:调整Camera预览方向

    有时候我们想根据自己的需要调整下Camera的预览方向,那么是调用哪个API可以达到我们的目的呢? 我们看下下图拍的几张小可爱的照片,分别是正常方向.旋转180度.90度拍的照片. ​ 正常方向 旋转 ...

  5. android爆炸粒子_Android游戏开发–粒子爆炸

    android爆炸粒子 有没有想过爆炸是如何产生的? 让我们绕个弯路,尝试实现基本的粒子爆炸. 爆炸不过是一堆散布在屏幕上的,源自单个点的粒子(无论是像素,小形状还是图像). 为了方便起见,并非总是如 ...

  6. android开发--推箱子小游戏(二)

    一.前言 迎来第二章的更新啦:使用ListView实现关卡的选择. 本章的内容有点小复杂,毕竟涉及使用了安卓开发中最难用也是最常用的控件之一:ListView 本章可以说是复杂但是单一吧.主要是想大家 ...

  7. android教育游戏设计方案,基于Android平台的儿童教育游戏的设计与开发

    摘要: 在通讯技术和信息技术的不断发展时代,智能手机(平板电脑)等移动终端的普及和功能的不断强大,基于移动终端的移动学习的理念渐渐深入人心且被广大的学习者所青睐,逐渐成为一种新的学习方式.学习者在面对 ...

  8. Android 3D 魔方游戏的设计与开发

    Android 3D 魔方游戏的设计与开发 5.1 Feature 定义 魔方是一个有趣的益智游戏,相信很多人都玩过.本次毕业设计,欲完成的主要的功能如下: (1) 开始游戏:开始一个新的游戏 (2) ...

  9. Android开发入门——推箱子游戏开发实战(十二)

    绘制游戏局面 本文是推箱子游戏程序开发的第七步.系列文章前五篇描述准备工作,故本文编号是(十二).本文讲解如何绘制游戏局面. 本文目标 本文讲解如何绘制游戏局面.游戏局面的示例如图1,图2所示.这两幅 ...

最新文章

  1. ***:***之路的必备技能
  2. ViewPage+Fragment的使用例子
  3. Eclipse中 怎么让包分层级显示
  4. 《Unit Testing》1.4. 成功的测试套件拥有哪些属性?
  5. 576. 出界的路径数
  6. 苏州大学实验报告模板C语言,苏州大学实验报告-实验flash在线编程实验
  7. java processrequest_java-如何在camera2 API中使用reprocessCaptureRequest
  8. SQL 2008 表死锁的解决
  9. DynamicFusion: Reconstruction and Tracking of Non-rigid scenes in real-time
  10. AAAI2021年,录用了165篇图神经网络相关论文,图网络究竟在研究什么?
  11. tensorflow数据预处理
  12. python 将txt文件转换为excel_Python学习笔记-Txt文件转Excel文件
  13. JDK动态代理简单实现
  14. Java集合高频面试题(最新版)
  15. 关于Matlab插值的问题,这些应该够用了吧
  16. ## 关于时下新兴的日常图片视频摄像防抖技术的简单介绍与讨论
  17. 【YOLOX 论文+源码解读】YOLOX: Exceeding YOLO Series in 2021
  18. idea连接linux中mysql[08S01]错误
  19. JVM 启动参数规则:-、-X、-XX、-D表示什么意思?
  20. pygame 初体验-碰壁小球

热门文章

  1. 昆山市计算机培训机构哪里有,昆山靠谱的办公软件培训班在哪儿
  2. 2020年中国超声行业现状与竞争格局分析,目前小型化超声市场份额还较小「图」
  3. QT开发之config文件读写
  4. cumulative
  5. STL案例-员工分组
  6. 短信拦截木马背后的黑色产业
  7. win10IE浏览器打不开怎么办
  8. SpringSecurity前后端分离(包含token和验证码登录)
  9. oracle logfile sync,发布版本2019_联众智慧内部oracle培训oracle培训相关emr_logfilesync_issue...
  10. Oracle数据库三种备份方式介绍