《游戏编程模式》学习笔记(九)游戏循环 Sequencing Patterns

定义
一个游戏循环会在游玩时不断运行。 每一次循环,它都会无阻塞地处理玩家的输入,更新游戏的状态,渲染游戏。它追踪时间的消耗并控制游戏的速度。游戏循环需要做到始终以固定的速度运行游戏。

一个游戏循环中通常包含处理输入部分,物理,AI等游戏逻辑部分,以及渲染部分。这一章给出了一些实现游戏循环的方法。

1.固定时间步长,没有同步
用while,尽可能快地运行游戏, 能跑多快跑多块。

while (true)
{processInput();update();render();
}

在这里插入图片描述

优点就是一个简单,没了
缺点是,游戏速度直接会受到硬件处理的速度以及单次循环中的复杂度的影响。在你的外星人上,子弹可能会飞的非常快。在你爷爷的大屁股电脑上,子弹会变得非常慢。

2. 固定时间步长,有同步
就是说在之前的基础上,每次循环后等一会。调用sleep()方法,让这个循环在固定时间段运行。

while (true)
{double start = getCurrentTime();processInput();update();render();sleep(start + MS_PER_FRAME - getCurrentTime());
}

优点,简单,省电,游戏不会运行得太快。
缺点是如果执行方法花了很多时间,游戏仍然会运行的过慢。

3.动态时间步长

用真实的时间做循环,每次循环会计算上一次循环到这一次循环所用的时间间隔,然后在update的时候传入这个时间间隔。这个方法很少见,几乎没有人会用。

double lastTime = getCurrentTime();
while (true)
{double current = getCurrentTime();double elapsed = current - lastTime;processInput();update(elapsed);render();lastTime = current;
}

优点,能适应并且调整,避免游戏运行的过快或者过慢
缺点,这会导致很多东西都不稳定。在物理和网络部分使用动态时间步长会遇见更多的困难。例如有些电脑上一个子弹一秒更新50次位置,另一台电脑上这颗子弹只更新了5次,浮点数的舍入偏差会导致这个子弹不同步。

4.扔掉渲染帧
以固定的时间步长更新游戏,但是在动态时刻渲染。

double previous = getCurrentTime();
double lag = 0.0;
while (true)
{double current = getCurrentTime();double elapsed = current - previous;previous = current;lag += elapsed;processInput();while (lag >= MS_PER_UPDATE){update();lag -= MS_PER_UPDATE;}render();
}

在代码中可以看到,这个循环会计算上一次循环到现在间隔的时间,如果间隔时间过长,就会进入里边的小循环,多次调用update方法以追上现实时间。当最终追上后,才会结束,调用渲染,结束整个大循环。

技巧在于我们将渲染拉出了更新循环。 这释放了一大块CPU时间。 最终结果是游戏以固定时间步长模拟,该时间步长与硬件不相关。 高端硬件玩家会有多次渲染,游戏体验更加平滑,而使用低端硬件的玩家看到的内容会有抖动。

在这里插入图片描述

优点是能适应并调整,避免运行得太快或者太慢。 只要能实时更新,游戏状态就不会落后于真实时间。如果玩家用高端的机器,它会回以更平滑的游戏体验。
缺点是比较复杂,你需要将更新的时间步长调整得尽可能小来适应高端机,同时不至于在低端机上太慢。一种方法是限制小循环的最大次数,来防止低端机上跑得太慢的问题,本质上就是扔掉一些逻辑帧。

有时候会出现这种情况:
在这里插入图片描述

由于渲染是动态的,在每次大循环结束才开始,中间有时候会隔着好多个小循环。所以有时候会出现渲染在两次更新之间的情况,而这个时候,渲染的往往是前一次更新的时候的情况,这会造成困扰,例如玩家看见子弹在左边,下一次渲染的时候应该在中间但还是显示在左边。在下一次渲染的时候就变成了右边,而不是玩家期待的中间。

解决方法就是 给render()方法也传入时间,让其插值预测来达到平滑的目的。
当我们要渲染时,我们将它传入:
render(lag / MS_PER_UPDATE);
假设子弹在屏幕左边20像素的地方,正在以400像素每帧的速度向右移动。 如果在两帧正中渲染,我们会给render()传0.5。 它绘制了半帧之前的图形,在220像素,啊哈,平滑的移动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/90539.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式的使用——模板方法模式+动态代理模式

一、需求介绍 现有自己写的的一套审批流程逻辑,由于代码重构,需要把以前的很多业务加上审批的功能,再执行完审批与原有业务之后,生成一个任务,然后再统一处理一个任务(本来是通过数据库作业去处理的&#x…

上海炒股开户哪个证券公司好?找谁能开低佣金的账户?

在上海炒股开户选择哪家券商都可以,但是要拿到低佣金的账户就有点难度了。上海,简称“沪,是国务院批复确定的中国国际经济、金融、贸易、航运、科技创新中心!正是如此,上海地区的券商公司也是非常之多的,这…

论文阅读 FCOS: Fully Convolutional One-Stage Object Detection

文章目录 FCOS: Fully Convolutional One-Stage Object DetectionAbstract1. Introduction2. Related Work3. Our Approach3.1. Fully Convolutional One-Stage Object Detector3.2. Multi-level Prediction with FPN for FCOS3.3. Center-ness for FCOS 4. Experiments4.1. Ab…

【网络设备】交换机的概念、工作原理、功能以及以太网帧格式

个人主页:insist--个人主页​​​​​​ 本文专栏:网络基础——带你走进网络世界 本专栏会持续更新网络基础知识,希望大家多多支持,让我们一起探索这个神奇而广阔的网络世界。 目录 一、认识交换机 二、交换机的主要功能 1、数…

Maven入门教程(一):安装Maven环境

视频教程:Maven保姆级教程 Maven入门教程(一):安装Maven环境 Maven入门教程(二):idea/Eclipse使用Maven Maven入门教程(三):Maven语法 Maven入门教程(四):Nexus私服 Maven入门教程(五):自定义脚手架 Maven项…

二三维电子沙盘数字沙盘虚拟现实开发教程第14课

二三维电子沙盘数字沙盘开发教程第14课 很久没有写了,主要前段时间在针对怎么显示高精度的 倾斜数据而努力,现在终于实现了效果不错。以前的版本显示倾斜数据控制不太好。 对了。目前系统暂只支持smart3d生成的kml格式的数据,由专有的录入程…

AI:05 - 基于深度学习的道路交通信号灯的检测与识别

随着人工智能的快速发展,基于深度学习的视觉算法在道路交通领域中起到了重要作用。本文将探讨如何利用深度学习技术实现道路交通信号灯的检测与识别,通过多处代码实例展示技术深度。 道路交通信号灯是指示交通参与者行驶和停止的重要信号。准确地检测和识别交通信号灯对于智…

C语言每日一练------(Day3)

本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今天练习题的关键字: 尼科彻斯定理 等差数列 💓博主csdn个人主页&#xff1a…

Grounded Language-Image Pre-training论文笔记

Title:Grounded Language-Image Pre-training Code 文章目录 1. 背景2. 方法(1)Unified Formulation传统目标检测grounding目标检测 (2)Language-Aware Deep Fusion(3)Pre-training with Scala…

什么是Python爬虫分布式架构,可能遇到哪些问题,如何解决

目录 什么是Python爬虫分布式架构 1. 调度中心(Scheduler): 2. 爬虫节点(Crawler Node): 3. 数据存储(Data Storage): 4. 反爬虫处理(Anti-Scraping&…

详解 SpringMVC 中获取请求参数

文章目录 1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、[RequestParam ](/RequestParam )4、[RequestHeader ](/RequestHeader )5、[CookieValue ](/CookieValue )6、通过POJO获取请求参数7、解决获取请求参数的乱码问题总结 在Spring MVC中,获取请…

ESP32-CAM模块Arduino环境搭建测试

ESP32-CAM模块Arduino环境搭建测试 一.ESP32OV2640摄像头模块CameraWebServer视频查看 二.测试ESP32-CAM(后续称cam模块)代码是否上传执行成功测试 const int led0 12; const int led1 13;void setup() {// put your setup code here, to run once:pinMode(led0, OUTPUT);pin…