Game Loop的几种实现方式(转载)

【AHK】打造炒股利器系列——2. 用数组和循环来简化语音报时器 以简化炒股语音播报器为实例,讲解Array、 Loop 、MsgBox等AHK指令。简化思路: 1. 我们用两个数组“times”和“messages”替换了单独的变量。这两个数组按照相同的顺序包含了时间和对应的消息。 2. 我们用一个循环替换了多个if语句。该循环遍历times数组。 3. 在循环中,我们检查当前时间是否与数组中的任何时间相匹配。如果有匹配项,就语音播报出相应的消息并退出循环(因为我们每次只需要说出一条消息)。 4. A_Index 内置变量用于访问两个数组中的当前索引。 阅读详情

转自牛人的博客:http://www.bennychen.cn/

Game Loop的几种实现方式

写这篇博客的目的是为了对game loop(游戏主循环)做一个全面的总结和介绍,包括它的定义,与之相关的专业术语(terminology),以及最重要的,对它的几种实现方式,从代码层次做一些介绍以及优缺点分析。

1.什么是Game Loop

对任何一个游戏开发者来说,game loop都应该不是一个陌生的概念。任何一款游戏都会有一个自己的game loop,它是整个游戏的核心,是游戏的心脏。具体什么是game loop,这是来自于Game Engine Architecture[2]上对于game loop的定义:game loop是对于一个游戏(或者一个游戏引擎)的所有子系统(subsystem)的周期性的更新。一个游戏会包含各种不同的子系统(比如渲染,物理,动画,AI等等),这些不同的子系统负责处理不同的游戏任务,game loop的实现方式就决定了这些子系统的任务执行的组织方式。而这些就决定了整个游戏的基础架构,同时也将决定game在不同的机器上将如何运行,在下面介绍game loop的不同实现方式时会对此有详细介绍。

game loop中所处理的逻辑和操作包罗万象,但一般可抽象为以下这几种模块:

  • 处理输入:这些输入包括,来自于交互设备(键盘,鼠标,游戏控制器等等)的输入,来自于网络的输入;
  • 系统更新(update):(根据输入或者自发的)对各个子系统进行更新,以决定当前的游戏状态;
  • 渲染(render):对整个游戏场景进行渲染。

所以一个最最简单的game loop可以抽象为如下的这些伪代码:

1 while ( game is running )
2 {
3     processInput();
4     update();
5     render();
6 }

2.相关术语

常常和渲染紧密相连的一个参数是FPS(frame per second),它指的是每秒显示设备在屏幕上进行绘制的频率。对于游戏来说,一般50-60的FPS是最优,最低也不要低于16帧[1]。游戏中还有一个容易被忽略的重要参数可以被称为游戏速度(game speed)[3],它指的是游戏状态每秒被更新的次数,容易与FPS混淆。一个通俗的理解和区别它们的方式可以是,FPS是render函数被调用的频率,而game speed则是update函数被调用的频率。

游戏是对实时性(real-time)要求很高的系统,所以在game loop中,time是尤其重要的一个因素。这里需要说的是,游戏中会包含好几种不同的时间,这些时间有着各自的时间线(timeline),并且在游戏中发挥着各自不同的重要作用[2]。

  • 系统的真实时间(real time)。真实时间一般在操作系统被定义为从过去某个固定时间点(比如常见的一个时间点被称之为Epoch, 是1970年1月1日的0:00:00, UTC时间)到当前点总共逝去的时间。
  • 游戏时间(game time)。一般情况下,游戏时间等于系统时间。但在某些特殊情况下,游戏时间可以发挥不同的作用:比如在游戏暂停的时候,需要停止更新游戏时间;在游戏需要以慢速运行时,可以用比真实时间低的频率来更新游戏时间,这在我们需要进行一些游戏调试的时候,尤其有用。下面会介绍到,一个好的game loop结构,可以有助于游戏调试,这对开发人员来说是非常重要的。
  • 局部时间线(local timeline)。不管是一个动画,还是一个音频或者视频片段,都会有一个局部时间线。通过将此局部时间线以不同的方式映射到全局的时间线,可以灵活的控制片段以特定的方式进行播放。[2]
  • 帧时间(frame time)。两次帧循环之间所间隔的时间,具体可看本文章的3.2.1节。

3.Game Loop的实现方式

OK,介绍了这么多跟game loop相关的概念,接下来进入正题,game loop的各种实现方式大盘点。

有一点需要强调的是,game loop在单线程的游戏系统中是一种情况,而在多线程的系统中又是另一个不同的故事。多线程对于系统会引入异常的复杂性,关于这个,可以看我之前的一篇关于游戏引擎多线程的文章:http://www.bennychen.cn/2011/01/关于游戏引擎多线程的一些整理和思考/。相比来讲,单线程要简单很多,这篇文章里以下的一些game loop的实现方式也主要是针对在单线程环境中的。

在单线程环境中,game loop按照实现方式可以分为以下这几种类型:

  • 基于帧的(frame-based)game loop
  • 基于时间的(time-based)game loop
    • 可变频率(variable-step)game loop
    • 固定频率(fixed-step)game loop
3.1 基于帧的(frame-based)game loop

这是一种最简单的game loop,就如上面文章刚开始的伪代码所描述的一样,在这种结构下,游戏只是重复的不间隔的进行processInput,update,render操作。可以看到,这种game loop的实现异常简单,但缺点也是异常明显的。因为它缺少了一个很重要的控制因素——时间,所以在不同配置的机器环境下,游戏将以不同的速度运行。比如说,游戏中的一个物体,在每次的update操作中将它的位移增加5(单位可以是米,英尺,像素,或者其它某种单位,每个游戏都使用一个特定的距离单位):

1 void update()
2 {
3     object.position += 5.0f;
4 }

在一个较快速的机器上,update被执行的次数会更多,所以物体移动的速度就会更快,这就导致了游戏在不同机器运行速度的不一致,这是不能接受的。

优点:简单;
缺点:在不同机器上,游戏的运行速度不一致。

3.2 基于时间的(time-based)game loop

为了让不同机器的游戏运行速度一致,就需要引入时间,这就带来了基于时间的game loop实现方式。这种方式下,又可以分为两种,可变频率(variable step)的和固定频率的(fixed step)。在[5]中,这两种方式则分别被称为可变间隔的(variable interval)和固定间隔的(fixed interval)。

3.2.1 可变频率的game loop
这种方式的实现只需要为update函数引入一个时间参数elapsedTime即可,elapsedTime指的是从上一次loop的执行到当前loop所过去的时间,通常称之为帧时间(frame time),或者time delta。它的单位一般使用毫秒,这是在游戏中进行时间相关操作所使用的标准单位[2],当然其它比如在做profiling时为了计算某个函数的执行时间,则用的是机器周期(machine cycle)这样更精确的时间机制。

这是这种game loop实现的伪代码,也非常简单:

1 lastFrameTime = getCurrentTime();
2 while ( game is running )
3 {
4     processInput();
5  
6     currentFrameTime = getCurrentTime();
7     elapsedTime = currentFrameTime - lastFrameTime;
8     update( elapsedTime );
9     lastFrameTime = currentFrameTime;
10  
11     render();
12 }

这时,再看前面的那个例子,对游戏中的一个物体,在每次的update操作中不是将它的位移绝对增加5,而是要乘以时间这个因子,这样5实际代表的是物体的速度。速度乘以时间,就得到了物体在这段时间内的位移:

1 void update( float elapsedTime )
2 {
3     object.position += 5.0f * elapsedTime;
4 }

这样就解决了在不同配置的机器上运行速度不一致的问题。因为在更快的机器上,update执行的频率高,但frame time的间隔时间较短,所以物体位置更新的频率高,但每次更新的位移幅度小。反之,在较慢的机器上,update函数的执行频率较低,但frame time间隔时间较长,则每次物体将以较大幅度的更新位移。正是因为引入了时间因素,所以在不同配置的机器上,游戏的运行速度将会看起来一致。

不过这种game loop在实现时需要解决一个长时间暂停的问题,所以我们在暂停时,要同时停止更新游戏时间,以免在暂停后恢复时,将得到一个超级大的elapsedTime值。

但随之而来,这种game loop实现方式的缺点也暴露出来了。比如考虑这样一种场景,物体绕着一个弧形的轨迹进行移动。在正常的速率下,物体的运行轨迹几乎是弧形的。如下图,图片来自于[5]。

但是在较慢的机器上,虽然物体的移动位置点能保持同步,因为更新的频率较低,物体的移动轨迹就变得非常离散,以至于不是按照一个弧形在移动,如下图。

其它的效果也有类似的问题,比如说动画,虽然说动画的播放速率是一致的,但是在较慢的机器上,会出现比较严重的掉帧现象,这就是我们俗称的“卡了”。再比如说物理,在一个正常的机器上,一个障碍物能够完美的被避开,但在一个较慢的机器上,这就不好说了。

对于这种game loop,就算是较快的机器上,也是有问题的,虽然好像update被执行的越快越多,游戏运行的就越流畅,用户的体验应该越好才对。但其实不然,两点原因,首先就算在较快的机器上,也可能会遭遇到运算的高峰期,这时由于对比明显,游戏性能的下降会非常明显,游戏用户就很容易察觉到这种性能降级(performance degradation),这并不是好的体验;再一点,对于手机等移动设备上的游戏,update速率执行过快不是好事,这对电池是一种消耗。事实是,游戏只需要一定范围内的update频率就可以达到流畅而令用户接受的效果。

优点:简单且不同机器上的游戏运行速度是一致的;
缺点:在较慢的机器上,物体的更新频率慢会导致各种效果失真(distortion);在较快的机器上,更新太快的话会更容易让用户察觉到性能降级,且对于移动设备,更新太快会降低电池的使用时间。

3.2.2 固定频率的game loop
由此,为了解决上面的问题,就有了这种固定频率的game loop,让游戏的更新速度保持在一个特定的恒定值。比如下面的这段伪代码,让游戏恒定运行在FPS(或者game speed,此时FPS等于game speed)为25的速度下。代码参考自[3]。

1 #define FRAME_RATE 25
2 #define FRAME_TIME ( 1000 / FRAME_RATE )
3  
4 nextFrameTime = getCurrentTime();
5 while ( game is running )
6 {
7     processInput();
8     update( FRAME_TIME );
9     render();
10  
11     nextFrameTime +=  FRAME_TIME;
12     currentFrameTime = getCurrentTime();
13     if ( nextFrameTime >= currentFrameTime )
14     {
15         sleep( nextFrameTime - currentFrameTime );
16     }
17     else
18     {
19         // 我们已经跟不上帧速率了
20     }
21 }

可以看到,如果一次loop执行完的持续时间小于固定帧时间,则直接让主线程sleep即可。但是如果在较慢的机器上(或者是设定的固定帧速率过高),执行完一帧的时间会超过固定帧时间,导致无法达到所目标的帧速率,则只能忍受这种情况了。最差情况下,如果在某一时期内游戏遭遇到了非常巨大的运算压力,则游戏将会变得异常缓慢到无法忍受的地步。

保持固定的更新频率有一个非常重要的优点,因为它带来了游戏执行的确定性(game execution determinism)[1],所以以这种机制所实行的game loop可以被称为确定性的game loop(deterministic game loop)。反之,可变频率的game loop则是非确定性的(non-deterministic),因为它依赖于系统每一帧运行的时间,这在游戏每次运行时是变化不定的,这就导致游戏的行为也是不定的。

确定性机制能够为系统带来一个非常重要的特点——录制和回放功能(record and replay)[2]。所谓录制回放功能,就是能够将玩家在进行游戏的时候的各种操作记录下来,以便在下一次运行时,就能够通过回放将游戏以同样的方式执行。这会成为一个很好的debugging工具,因为通过回放功能,会让一些难以发现的bug得以轻而易举的复现,这是非常珍贵的。甚至我们还可以支持单步调试(single-stepping)功能[2],单步调试指的是当游戏处于暂停状态时,可以通过某个按键,让游戏一次执行一个frame time,这在调试游戏时都是非常有用的。

这种game loop还是有一个问题,它紧耦合了update和render的执行频率,update的频率(即game speed)保持在25基本能满足游戏运行的流畅需求,但让render的更新频率(即FPS)也保持在25,对于配置好的机器实在是有些浪费,我们可以让渲染的更快,以获得更好的画面效果。

优点:在不同机器上游戏效果一致,同时为游戏带来确定性。
缺点:一个更好的机器并不能带来更好的游戏画面,扩展性(scalability)差。

3.2.3 获得最大FPS的固定频率的game loop
解决上一个game loop缺点的办法就是解耦update和render,让它们以各自不同的频率运行。这就带来了这个固定频率的game loop的变种,称之为“获得最大FPS的固定频率的game loop”(Constant Game Speed with Maximum FPS)[3]。

同时这种方法还处理另一个问题,当update处理时间过久时,这种game loop会暂时不进行render而再次update。换言之,当update执行时间长于所期望的帧时间时,游戏会丢弃绘制帧并调用额外多次update函数,以让游戏从一个慢速(slowdown)状态中追赶上并恢复过来[4]。

这是该game loop的代码:

1 #define MAXIMUM_FRAME_RATE 45;
2 #define MINIMUM_FRAME_RATE = 15;
3 #define UPDATE_INTERVAL ( 1000 / MAXIMUM_FRAME_RATE )
4 #define MAX_CYCLES_PER_FRAME ( MAXIMUM_FRAME_RATE / MINIMUM_FRAME_RATE )
5  
6 nextFrameTime = getCurrentTime();
7 while ( game is running )
8 {
9     loops = 0;
10     while( getCurrentTime() > nextFrameTime
11           && loops < MAX_CYCLES_PER_FRAME )
12     {
13         update( UPDATE_INTERVAL );
14         nextFrameTime += UPDATE_INTERVAL;
15         loops++;
16     }
17  
18     render();
19 }

从上面的代码中看出,当出现update处理时间过久时,game loop并不是一直重复执行update而不渲染,update频率被控制在15-45之间,所以在一次while循环中,最多只会执行3次update(MAX_CYCLES_PER_FRAME=MAXIMUM_FRAME_RATE / MINIMUM_FRAME_RATE=45/15)。

当然FPS也不总是可以为任意值,有时为了解决显示设备上的一种叫做tearing[2](屏幕的上半部分显示的是上一帧的画面,而下半部分是当前帧的画面)的问题,需要将FPS设置为显示设备刷新频率的倍数。在手机等这种移动设备上,同样为了省电,也需要将FPS固定在一个恒定值。但不管怎样,update和render仍然是以各自不同的频率运行。最近在读的一本关于iOS游戏开发的书上[6]的game loop,作者使用的就是这种game loop,它的game speed被设置在15-45,而FPS则采用的是iOS上默认的60(iOS上使用CADisplayLink的frameInterval属性来设置绘制帧率,frameInterval默认是1,表示显示1秒钟会被刷新60次)。

优点:拥有固定频率的game loop的优点,同时解耦update和render,并且当帧速率降低时,可以通过丢弃绘制帧来保持游戏的速度;
缺点:在高配置的机器上依然有些浪费资源。

3.3 其它方式

game loop还可以有更多的变化,比如在[1]中提到,对于游戏中的不同子系统,update的频率也是不一致的。比如,为了获得很好的动画效果,需要一个较高的频率来更新动画,而对于AI系统,用同等高频率的速度来更新就是浪费计算资源了。所以这篇文章提出了一种更好的update机制,将update分隔为两部分,一部分以最快的速度运行,而另一部分以某种预设的固定频率运行。

在[3]中提出,为了获得一种更平滑的画面效果,可以对frame-time进行插值(interpolate),并且为update函数提供预测函数(prediction function)。

4.总结

一个看似简单的game loop,也可以有这么多的变数。这篇文章主要基于时间因素列出了4种实现方式:第1种是基于帧的game loop,一般而言要避免采用这种方式,而应该选用后面3种基于时间的game loop。基于时间的可变频率的game loop是一种常见的实现方式,不过为了获得稳定的画面效果和游戏运行的确定性,可以使用固定频率的game loop。最后还可以将update和render解耦以各自频率运行,以获得最优的组织结构运行游戏。

OK,这里就是我有史以来最长的一篇博客的结尾。

5.参考

[1]LUIS VALENTE, Real Time Game Loop Models for Single-Player Computer Games
[2]Jason Gregory, Game Engine Architecture
[3]http://www.koonsolo.com/news/dewitters-gameloop/
[4]http://msdn.microsoft.com/en-us/library/bb203873.aspx
[5]http://sacredsoftware.net/tutorials/Animation/TimeBasedAnimation.xhtml
[6]Michael Daley, Learning iOS Game Programming - A Hands-On Guide to Building Your First iPhone Game

THIS ENTRY WAS POSTED IN  GAME PROGRAMMING AND TAGGED  GAME,  LOOP. BOOKMARK THE  PERMALINK.
gameloop游戏运行核心 silvelight beta2游戏开发研究,gameloop游戏运行核心 立即下载

相关推荐

利用gameloop开发简单第一个小游戏

silverlight beta2 游戏开发

游戏主循环(Game Loop)的详细解析

译自:https://dewitters.com/dewitters-gameloop/ 1. 引言   游戏主循环是每个游戏的心跳,输送着整个游戏需要的养分。不幸的是没有任何一篇好的文章来指导一个菜鸟游戏程序员如何为自己的程序供养。不过不用担心,因为你刚好不小心看到了这篇,也是唯一一篇给予这个话题足够重视的文章。   由于我身为游戏程序员,我见过许许多多的手机小游戏的代码。这些代码给我展示...

Zzz的专栏 1万+

Java-Game-Loop-Fun:java中的简单游戏循环,有一些绘图和简单的AI代码

Java-Game-Loop-Fun java中的简单游戏循环,有一些绘图和简单的AI代码。

大话游戏循环Game Loop——Python&C++

简单直接,带你开玩游戏循环Game Loop!

YF云飞的博客 5万+

字节跳动扣子AI应用开发平台之实战

推出背景:扣子平台由字节跳动推出,旨在让非开发者也能快速创建、调试和优化聊天机器人。上线时间:扣子平台于2024年2月1日正式上线。功能定位:扣子是一个AI聊天机器人和应用程序编辑开发平台,可以理解为字节跳动版的GPTs。

恩爸编程 5898

win11重装系统简易教程-小白也可以上手!

本文介绍一下win11系统重装的各个步骤,也作为记录供自己后面查看。附上我之前参考的一位知乎大神写的重装win10系统文章的地址本文用到的工具全部是,不需要下载第三方镜像文件(不是说这个不好,只是第三方的软件或镜像文件网上非常多,琳琅满目,小白需要筛选甄别,直接用官方的就比较省心,大神请自便~)

Sddqa的博客 1万+

游戏编程设计模式——Game Loop

意图将游戏时间的进度从玩家输入和处理器速度中分离出来。动机如果让我选一个本书最不能少的模式,那就是这个。游戏循环是游戏编程模式中最精髓的一个例子。几乎所有的游戏都会有它,再也没有第二个应用如此广泛的。但是在游戏之外有很少用到。要看它是如何起作用的,让我们把记忆拉回到过去。在哪个编程跟洗碗工一样的青葱岁月。你需要把一堆代码塞进机器,按下按钮,等待,然后出结果。这就是批次模式的编程——一旦工作完成,程序就停止运行了。你今天仍然能够看到,虽然谢天谢地我们不要在卡片上写代码了。Shell脚本,命令行程序,甚至是那些

wubaohu1314的博客 1366

【正点原子STM32连载】第六十章 串口IAP实战:从Bootloader到APP的无缝升级

本文以正点原子STM32F103开发板为例,详细讲解了串口IAP(在应用编程)技术的实现原理与实战步骤。内容涵盖Bootloader与APP的分工、FLASH空间规划、核心代码解析以及Ymodem协议的应用,旨在帮助开发者掌握通过串口为嵌入式设备实现远程固件升级的关键技术,提升产品维护与迭代效率。

weixin_29161719的博客 445

为什么鸿蒙游戏不能用传统 Game Loop?

本文深入探讨了鸿蒙(HarmonyOS)游戏开发与传统游戏开发的核心差异。文章指出,传统基于帧循环(Game Loop)的架构在鸿蒙中会导致性能问题、状态不一致和多端同步困难,原因在于鸿蒙的ArkUI采用声明式编程和响应式设计,其本质是"状态驱动"而非"帧驱动"。 作者通过对比分析,提出鸿蒙游戏开发的正确模式应该是"System驱动"架构:由事件触发状态变化,再由系统自动处理渲染更新。这种范式转变要求开发者放弃传统的主动更新思维,转而采用基于状态变

qq_36863796的博客 1万+

【Matlab算法】MATLAB实现的语音信号降噪算法(附MATLAB完整代码)

语音信号降噪是语音处理领域中的一个关键问题。在实际应用中,语音信号常常被各种环境噪声污染,这不仅影响了语音的质量,还可能导致后续处理(如语音识别)的性能下降。因此,开发有效的降噪算法对于提高语音通信质量、改善语音识别系统性能等具有重要意义。 本文将介绍并实现两种经典的语音信号降噪算法:谱减法和维纳滤波。这两种方法都是基于频域处理的技术,具有实现简单、计算效率高的特点。通过MATLAB实现这些算法,我们可以直观地比较它们的性能和降噪效果。

Albert_Lsk的博客 1329

【嵌入式DIY实例-Arduino篇】-脉搏传感器监测脉搏率 (BPM)及可视化

在本文中,我们将使用 Arduino 和脉搏传感器来测量心率 (BPM)。 在文章中,我们将向展示如何使用脉搏传感器测量您的心率(每分钟心跳次数),并在电脑上位机通过Processing来实现心率数据可视化。同时使用LCD16×2 显示屏显示脉搏率 BPM。 该传感器易于使用和操作。 只需将手指放在传感器顶部,它就会测量心跳变化。

视觉与物联智能 834

游戏循环(Game Loop) Unity的游戏循环

协程允许在多帧之间分步执行代码,适合异步操作(如等待、加载、动画等)。通过启动,使用控制执行流程。Unity Job System是官方提供的多线程任务系统。允许开发者编写高性能并行代码,充分利用多核CPU。结合Burst编译器,生成高效本地代码。Unity游戏循环严格分阶段执行,保证输入、逻辑、物理、动画和渲染协同工作。脚本生命周期函数配合游戏循环,提供丰富的扩展点。FixedUpdate用于物理,Update用于逻辑,LateUpdate用于后处理。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 640

Newton & Nvidia 开源 GPU 加速机器人仿真器入门教程(一)

Newton 是一个 GPU 加速、可扩展和可微分的物理仿真引擎,专为机器人、研究和高级仿真工作流而设计。Newton 基于 NVIDIA Warp 并集成了 MuJoCo Warp,为用户和开发人员提供了高性能仿真、现代 Python API 和灵活的架构。

机器人控制与仿真应用 1482

Ch02: Game Class and Loop

《SDL Game Development》中有这样一个游戏的流程图 这个game loop 在游戏开发里面用到的往往是下面一种 《Game Programming Patterns》 http://gameprogrammingpatterns.com/game-loop.html ...

chuling9661的博客 255

华为MetaERP Oracle EBS OM(订单管理)模块详解作为ERP财务解决方案架构师,理解OM模块的业务全景和数据模型至关重要。OM是EBS分销链路的核心引擎,贯穿“订单到收款“(Orde

Oracle EBS OM模块是管理销售订单全生命周期的核心模块,涵盖客户管理、订单执行、发运开票、定价及信用控制等功能。其标准流程包括订单录入、预订、发放、发运确认和自动开票等环节,核心数据表涉及订单、客户、发运和定价等业务对象。OM模块与库存、应收、发运等模块深度集成,架构师需重点设计订单类型、信用控制策略和自动开票接口等关键环节,确保业务流程高效流转。

金牌架构师 361

OpenHarmony之Histreamer引擎深度解析:pipeline_core架构如何全面取代GStreamer,一统音视频播放与录制

Histreamer是OpenHarmony多媒体框架的核心媒体引擎,采用架构设计。一个轻量级的媒体引擎组件,提供播放、录制等场景的媒体数据流水线处理。1.播放场景分为如下几个节点:数据源读取、解封装、解码、输出;2.录制场景分为如下几个节点:数据源读取、编码、封装、输出。该引擎从OH5.0开始取代了原有的媒体引擎gstreamer(部分文档还保留较老架构的讲解),提供统一的音视频播放、录制、元数据解析等能力。

m0_67505153的博客 333

游戏主循环(Game Loop)详解

每一个复杂的应用程序的核心都是一个循环(Loop) - 贯穿于一个应用程序生活周期的是一部分代码不断的重复执行时间.这个循环(Loop),可以就说是主循环。主循环的主要作用是:协调程序的行为(事件)和建里应用程序的中枢。 游戏主循环(Game Loop):游戏(Game)的开发也不例外,也是有主循环(Game Loop)的,游戏主循环(Game Loop)是每个游戏中最重要的一部分。游戏都...

weixin_30522095的博客 456

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

[Teaching] [Silverlight] 30秒快速建立遊戲迴圈 (Game Loop)

如果你想拿Silverlight開發遊戲,不管是在PC上採用Silverlight 3、4,或是Windows phone 7上採用Silverlight for windows phone,都離不開先建立一個遊戲迴圈 (Game Loop)。 一般開發應用程式,通常都是採用事件驅動,當有任何按鈕被按下,或是資料被更新時,觸發相對應的程式,開始進行處理。 而遊戲的開發,則採用了時間驅動,在固定...

weixin_30950887的博客 93

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

[转载]在J2me游戏使用“精灵”-Sprite(图)

在J2me游戏使用“精灵”-Sprite(图)Sprite,精灵,顾名思义,专用来代表游戏中的动画角色,比如飞机,坦克等等。在MIDP1.0中,我们必须自己写专门的类来实现Sprite,幸运的是,MIDP2.0为Sprite提供...

congji3817的博客 231

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

某考试T1 game

题目背景 无 题目描述 Alice 和 Bob 在一个圆环上玩游戏。圆环上有 n 个位置,按照顺时针顺序 依次标号为 1 到 n。Alice 和 Bob 分别有一个数字集合,集合中都是在 [1, n−1] 内的正整数。游戏开始时会有一个棋子摆在圆环上的某个位置,然后两人轮流 行动。轮到某个人的回合时,他可以从他的集合中选出某个数 x,然后把棋子 沿顺时针方向移动 x 个位置。如果某个人把棋子...

weixin_30719711的博客 91

传奇音乐设置

将Game over2.wav改为Log-in-long2.wav这个是登录界面的音乐将main_theme.wav改为sellect-loop2.wav这个是角色选择界面的音乐最好先将Log-in-long2.wavsellect-loop2.wav这两个文件改成别的名字,以免更改的时候说有文件重名 WAV文件夹里面还有一首32.21MB的文件 叫Field2.wav...

weixin_30650039的博客 468

使用 Jbulider 开发 J2ME 移动游戏程序

作者使用JBuilder2005,里面自带WTK2.1,自己下载2.2版本,2.2那个默认的模拟器看着实在爽。另外,Jbuilder X下的WTK也是2.0的版本。Jbuilder 9的WTK是1.04。首先开启Jbuilder。建立一个Project: 然后填写名字和路径。继续: 然后选择JDK路径,本身已有WTK2.1,你可以选择。...

weixin_33696822的博客 93

解决ios下的微信打开的页面背景音乐无法自动播放(转载)

20160314更新 后面的项目发现,还有两个坑,需要注意下: ·本文的解决方案的核心是利用了 微信/易信 在ready的时候会有个 WeixinJSBridgeReady/YixinJSBridgeReady事件,通过监听这个事件来触发的。那有个坑就是 如果微信已经ready了,但还没执行到你监听这个ready事件的代码,那么你的监听是没用的,所以监听的js一定要放在head前面(放在css...

weixin_33759269的博客 247
上一篇: C++虚函数表解析(转)
下一篇: 费马大定理
明斯基
博客等级 码龄18年 24粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值