什么是“游戏逻辑代码”?


50

我正在使用C#/ XNA,并且已经被告知很多次不要将更新代码与绘图代码混合使用-我敢肯定我没有!但是,谁能描述“逻辑代码”到底是什么?

如此处所示:http : //blogs.msdn.com/b/shawnhar/archive/2007/07/25/understanding-gametime.aspx

[...]确保将所有游戏逻辑放入Update方法中(不在Draw中),并且所有内容都将以稳定的恒定速度运行。

我问这个问题是因为我的游戏速度相对于FPS有所波动。缓慢的FPS等于缓慢移动的物体,反之亦然。是的,我包括了预期的position += speed * (float)gt.ElapsedGameTime.TotalSeconds;代码。

这可能是一个新手的大问题,但是我只想明确定义它。


我想你的意思是position = speed * ...TotalSeconds。注意=不是+=。如果是+=您键入的内容,那么您的位置几乎会立即从屏幕上飞出。
DrZ214 '16

我有看起来像'位置+ =方向*速度* ... TotalSeconds'的代码,并且效果很好。我可能输入了错误的内容,但是位置=速度会在每次更新时为其分配内容。您的方式可能有效,但是我的代码像这样工作。(请注意方向已标准化)
家伙

我以为gt.ElapsedGameTime.TotalSeconds是从启动程序(游戏)开始经过的秒数。如果将速度乘以该速度,则在播放5秒钟后,速度将提高5倍(特殊情况下,速度设置为0)。不知道还有什么可以使那不真实,但我对此很感兴趣。
DrZ214 '16

1
啊哈,这是自上次更新以来。gamedev.stackexchange.com/questions/67968/...
Shyy盖伊

2
令人着迷的我永远都不会猜到。从来没有在几秒钟之内需要这种东西,因为我个人使用了自己的变量iii,即我手动递增每个更新,因为我不想在几秒钟之内,而是需要步进或帧。我可以看到,您的方式虽然是对事物进行软编码的有效方式。
DrZ214 '16

Answers:


102

它会改变游戏世界的状态吗?这是逻辑代码。

它显示游戏世界的状态吗?它是渲染代码。


我会浏览一下我的代码以确保100%正确。很好的解释,谢谢。
害羞的家伙

38
它可以处理输入吗?它的控制器代码。将控制与逻辑分开,以便可以将相同的逻辑用于不同类型的控件。例如FPSInputController + CharacterMotor与AIInputController + CharacterMotor与NetworkInputController(例如,多玩家实例中的其他玩家)+ CharacterMotor。马达(逻辑代码)并不关心它如何获得指令,只是提供了它们(这种去耦使得可以轻松地从玩家过渡到AI机器人(想想Left 4 Dead和闲置玩家)再返回,除其他事项外)。
Draco18s

10
Draco提出了一个很好的观点。您可以在代码中放入许多不同的部分。我认为Nils的划分是逻辑和渲染之间的原型划分,但是您还会看到许多其他层。将它们分成几层的真正原因是每一层都包含相似的操作,这些操作需要具有相似要求的相似样式的代码。例如,在许多游戏中,您可以花2或3帧来完成游戏逻辑,但是如果您不渲染每个帧,用户的眼睛就会很快注意到。
Cort Ammon

当它们开始成为压力源时,保持它们与众不同将有助于您管理需求。
Cort Ammon

6
请记住,如果您对它过多地添加MVC,可能会减慢爬网的速度,因此请始终在可维护性和优化之间寻求平衡。但是不要过早优化,除非您完全确定自己在做什么。请记住,您始终可以重构。而且...呃,做很多游戏,从错误中学习。
Maurycy

24

在以下情况下,您的分隔是正确的:

  • 连续多次调用Draw()而不散发对Update()的调用将永远不会导致调用之间的任何可见变化。
  • 连续多次调用Update()而不插入对Draw()的调用,就像在关闭屏幕的情况下玩游戏:一切都进行得很完美且始终如一,您看不到它。

5
Draw()随着时间的流逝,正确书写可能会绘制不同的图片。例如,动画小精灵的帧可能会继续变化。同样,如果渲染代码使用通用技巧并添加velocity * time since last update / period of update到对象的可见位置(而其实际位置保持不变),则对象可能会继续在视觉上向前移动。
HolyBlackCat

2
iff意思是“如果只有”?
BalinKingOfMoria '16

3
@HolyBlackCat:这是有争议的。如果我想暂停图形怎么办?如果动画的帧影响游戏(与击打盒相对应的攻击动画等)会怎样?视觉插值仍然暗示着“时间”(如游戏的三角时间)已经过去了,但是如果时间过去了,而您又没有Update时间,那么还有什么不同步的呢?缺少播放器输入,未处理网络事件等?应从单个时钟驱动游戏,并从该时钟派生用于游戏逻辑或物理的固定“滴答”,并且派生图形状态也应由同一时钟驱动。
肖恩·米德迪奇

@SeanMiddleditch我同意,几乎总是可以用Draw()这种方式编写,因此当连续调用多次时,它总是绘制相同的图片。如果可能,应该这样做。但是在某些情况下,您不知道将以什么频率Draw()呼叫。例如,如果您想为新的120hz显示器提供全面支持(实际为120 FPS),然后打开垂直同步。What if I want to pause graphics?然后,您将0而不是实际的增量时间传递给Draw()
HolyBlackCat

2
@HolyBlackCat:我得到的所有内容都不会排除使用120hz渲染的麻烦。我绝对不建议使用固定的提款率。那只是业余。应该有一个全局游戏时钟,该时钟的增量是根据渲染帧来度量的,该渲染帧馈入固定速率游戏逻辑滴答的累加值。全局时钟驱动图形,包括插值。您可以通过将时钟刻度设置为来暂停图形0。您可以使用分层时钟,例如,当字符插值停止时,UI仍然可以运行并动画,这非常非常容易。
肖恩·米德迪奇

7

这里的重点是分离不是模型的模型事物。

博弈逻辑是模型,如

这些都是不同的,相关的软件体系结构模式。但是无论如何,模型都是真实的逻辑和真实的状态。

在制作业务软件时,有时将其称为业务逻辑,并对某些业务策略进行编码。例如,如果您正在为银行编码,计算信用卡账单,那么如果某人在不到30天的时间内清还债务,则无需他人支付利息的功能就是业务逻辑的一部分,它存在于模型。例如,它不存在于显示层之一上。例如,用于打印帐单的代码不会根据其操作来编辑文本。这个示例也许突出说明了为什么您可能希望以这种方式组织代码。

游戏逻辑也是如此。

想象一下,您的游戏有时已移植到另一个控制台。可以想象一下与您当前目标确实有所不同的事物。例如,如果您要用游戏手柄/控制器来瞄准目标,请想象您的游戏已移植到触摸屏平板电脑上。游戏逻辑是代码的一部分,移植时不会更改。

如果您的游戏类似于军事战略游戏,请想象它已被转换为世界上最复杂的棋盘游戏。游戏逻辑是代码部分,直接与规则手册中的行相对应。(不是规则书中的所有行,不是有关移动棋子的行,而是某些行。)

游戏逻辑是永远不变的事物,无论形式如何。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.