在游戏编程中全局变量不好吗?

2024-01-13

我知道我对全局变量的本能反应是“糟糕!”但在我在大学学习的两门游戏开发课程中,全局变量被广泛使用,现在在我使用的 DirectX 9 游戏编程教程 (www.directxtutorial.com) 中,我被告知全局变量在游戏编程中是可以的。 ..?该网站还建议在进行游戏编程时尽可能仅使用结构,以帮助保持简单。

我对这个问题真的很困惑,我一直在尝试做的所有研究都非常令人困惑。我意识到使用全局变量时存在问题(线程问题,它们使代码更难维护,它们的状态很难跟踪等),而且不使用全局变量也会带来成本,我必须通过一个looooot经常出现的信息可能会令人困惑,而且我想象会浪费时间,尽管我猜指针会加快进程(这是我第一次用 C++ 编写游戏。)无论如何,我意识到可能没有“正确”或因为两种方式都在这里“错误”答案work,但我希望我的代码尽可能正确,因此任何输入都会很好,非常感谢!


游戏和全局变量的问题在于游戏(现在)是在引擎级别进行线程化的。使用引擎的游戏开发人员使用引擎的抽象,而不是直接编程并发(IIRC)。在许多高级语言(例如 C++)中,线程共享状态很复杂。当许多并发进程共享公共资源时,它们必须确保不会互相侵犯。

为了解决这个问题,你可以使用并发控制比如互斥锁和各种锁。这实际上使得代码的异步关键部分以同步方式访问共享状态以进行写入。并发控制的话题太多,无法在这里详细解释。

可以说,如果线程使用全局变量运行,那么调试会变得非常困难,因为并发错误是一场噩梦(想一想,“哪个线程写了这个?谁持有那个锁?”).

There 是例外游戏编程 API,如 OpenGL 和 DX。如果您的共享数据/全局变量是指向 DX 或 OpenGL 图形上下文的指针,那么通常会映射到 GPU 操作,而 GPU 操作不会遭受同样的麻烦。

请小心。保留代表“玩家”或“僵尸”或其他内容的对象,并在线程之间共享它们可能很棘手。相反,生成“玩家”线程和“僵尸组”线程,并基于消息传递在它们之间具有强大的并发抽象,而不是跨线程/关键部分边界访问这些对象的状态。

说了这么多,我确实同意“对全球化说不”下面提出了一点。

有关线程和共享状态的复杂性的更多信息,请参阅:

1 POSIX Threads API - 我知道它是 POSIX,但提供了一个转换为其他 API 的好主意 https://computing.llnl.gov/tutorials/pthreads/
2 维基百科有关并发控制机制的精彩文章 http://en.wikipedia.org/wiki/Category:Concurrency_control
3 哲学家就餐问题(以及许多其他问题) http://en.wikipedia.org/wiki/Dining_philosophers_problem
4 有关线程的 ThreadMentor 教程和文章 http://www.cs.mtu.edu/~shene/NSF-3/e-Book/
5 另一篇英特尔文章,但更多的是营销内容。 http://software.intel.com/en-us/articles/multithreaded-game-programming-and-hyper-threading-technology/
6 关于构建多线程游戏引擎的 ACM 文章 http://portal.acm.org/citation.cfm?id=1231894.1231896

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在游戏编程中全局变量不好吗? 的相关文章

  • 用 C++ 进行服装建模 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在编写一些软件 最终会绘制一个人体框架 可以配置各种参数 并且计划是在假人身上放置某种衣服 我研究
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • 如何使用 watin 中的 FileUploadDialogHandler 访问文件上传对话框

    我正在使用 IE8 和 watin 并尝试通过我的网页测试上传文件 我不能简单地使用 set 方法设置上传文件 例如 ie FileUpload Find ById someId Set C Desktop image jpg 因为上传文本
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 使用 GROUP 和 SUM 的 LINQ 查询

    请帮助我了解如何使用带有 GROUP 和 SUM 的 LINQ 进行查询 Query the database IEnumerable
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub

随机推荐

  • 如何在 Python 中提取字符串中的列表?

    我使用 Pandas 导入了 CSV 并用字符串条目读入了一列 检查本系列 专栏 的条目 我发现它们实际上应该是列表 例如 df A pd Series entry11 entry21 entry22 entry31 entry32 我想从
  • Windows批处理文件中的一个数字既大于又小于另一个

    我的批处理文件中有以下代码 if bakfilesize geq freespacet echo baksize is larger if bakfilesize leq freespacet echo baksize is smaller
  • 如何在服务生成器类中添加http拦截器

    我创建了一个单独的服务生成器类 如本指南所示https futurestud io tutorials retrofit 2 manage request headers in okhttp interceptor https future
  • 如何将 CSRF 令牌设置为不同的上下文路径

    我们基于 Angular 的 Web 应用程序与在不同域和上下文路径上运行的企业门户集成 我正在使用基于 Spring Security 的 CSRF 令牌来验证传入请求 该应用程序在本地完美运行 但当我将其与门户集成时 所有 post 调
  • pg_dump 串行数据类型问题

    有人可以向我解释一下为什么使用以下脚本创建 PostgreSQL 表 CREATE TABLE users id serial NOT NULL name character varying 150 NOT NULL surname cha
  • 开发 API - 如何确保其安全? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我将读取和写入方法放在数据库中 并通过 URL 公开它们 我使用 CodeIgniter 框架并使用 URL 段将参数传递给这些方法
  • 将文件复制到 FTP 并以今天的日期存档

    我需要创建一个执行以下操作的脚本 将文件夹中的所有文件复制到 FTP 站点 如果复制成功 则将文件移至存档 存档应该是一个新创建的文件夹 具有今天的日期 这样我们就知道它们何时被传输 我试图蚕食其他脚本来让某些东西发挥作用 但我没有取得任何
  • docker ubuntu /bin/sh: 1: locale-gen: 未找到

    我将下面的区域设置代码放入我的 dockerfile 中 FROM node 4 onbuild Set the locale RUN locale gen en US UTF 8 ENV LANG en US UTF 8 ENV LANG
  • 如何在返回 SELF 的函数的 pl/sql 对象类型中链接调用

    我想让一个 oracle 对象返回自身并能够链接这些调用 我怎么做 我尝试返回相同的类型 但它不起作用 我还尝试添加一个由函数调用的过程 但它也不起作用 总是抱怨修改宽度成员的值 看起来函数不会产生副作用 它们是按照更数学的函数原理建模的吗
  • 使用QUdpSocket发送数据报

    我正在尝试使用 QUdpSocket 发送数据报 以下是我正在使用的代码 udpSocket new QUdpSocket this QByteArray datagram Message udpSocket gt writeDatagra
  • 将数据拟合到所有可能的分布并返回最佳拟合[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个样本数据 我想获得最佳拟合分布 我有几个链接建议我可以从以下位置导入发行版scipy stats 但是我事先并不知道数据的类型 我
  • Hibernate/MySQL并发问题

    我得到一个极其奇怪的结果使用 Hibernate 4 1 9 Final 和 MySQL 14 14 Distrib 5 5 29 InnoDB 表 当我使用一个线程将某些内容持久保存到数据库并尝试使用另一个线程获取它时 Hibernate
  • FromStr 特征不暴露生命周期的原因是什么?

    Rust FromStr 特征是这样定义的 pub trait FromStr type Err fn from str s str gt Result
  • 如何在 App Inventor 中打开网页

    我有一个网络查看器 它是主要应用程序 网络查看器下方是一个按钮 我想在单击按钮时在用户的网络浏览器中打开一个网页 如何在 App Inventor 中执行此操作 Action android intent action VIEW DataU
  • R 中未使用的参数

    是否可以让软件忽略模块运行时定义了未使用的参数这一事实 例如我有一个模块multiply a b 它返回的乘积a and b 如果我像这样调用模块 我会收到错误 multiply a 20 b 30 c 10 返回错误似乎有点不必要 因为所
  • Mockito 无法模拟/间谍,因为: - 最后一课

    我是 viewmodel 中的一个简单函数 getCreditReport 我试图在其中进行 API 调用存储库层 我想在 viewmodel 中测试 getCreditReport 以检查是否调用了 thge 存储库 但出现以下错误 or
  • 将 docker-compose 与 CI 结合使用 - 如何处理退出代码和守护进程链接容器?

    现在 我们的 Jenkins 代理为每个 Rails 项目生成一个 docker compose yml 然后运行 docker compose up docker compose yml 有一个主 web 容器 其中包含 rbenv 和所
  • 我无法成功将 UINavigationBar 的 barTintColor 设置为clearColor

    在 iOS 7 中 UINavigationBar 有一个奇怪的地方 如果你尝试设置它barTintColor财产给 UIColor clearColor 或任何 alpha 0 的颜色 它完全忽略该值 例如 如果你写 navigation
  • True 返回 1

    false 效果很好 但是当我返回 true 时 我得到 true1 为什么 num 3 function number num for i 2 i lt num i if num i 0 echo false return false e
  • 在游戏编程中全局变量不好吗?

    我知道我对全局变量的本能反应是 糟糕 但在我在大学学习的两门游戏开发课程中 全局变量被广泛使用 现在在我使用的 DirectX 9 游戏编程教程 www directxtutorial com 中 我被告知全局变量在游戏编程中是可以的 该网