代码与方程:打造游戏世界的数学艺术

如果你正在构建游戏,那么对于视频游戏程序员来说,数学并不是一道可怕的墙——而是一小套你可以不断重复使用的工具。从移动摄像机到生成公平战利品,数学帮助你将“我希望这感觉不错”转化为你的游戏实际上可以做到的事情。

游戏程序员实际使用哪些数学知识?

你不需要掌握大学课程中的所有主题来学习视频游戏程序员所需的数学知识。大多数日常问题只需要一个简短的列表:一点三角学、大量的向量、一些矩阵和基本的概率论。把它当作一个工具箱,而不是教科书。

三角学和算术

它是什么(用平实的话说):三角学有助于处理圆和角度——任何旋转、瞄准或绕某物移动的东西。算术是你每天都在用的数学:加法、减法、限制和混合数字。

它出现在哪里

  • 摄像机绕玩家旋转。
  • 炮塔瞄准或精灵指向鼠标。
  • 动画中平滑自然的上下摆动(正弦/余弦“波”)。
  • 径向菜单、指南针UI、音频声相。

需要学习的小技能

  • 转换度数 ↔ 弧度(许多引擎使用弧度)。
  • atan2(y, x) 给出“这个方向的角度”——非常适合于指向物体。
  • Lerp(线性插值)在两个值之间混合。逆Lerp将原始数字转换为0-1进度条。
  • 限制使数字保持在安全范围内(例如,0到最大生命值)。

额外的舒适技巧

  • 包装角度以避免在跨越0°/360°时出现突变。在lerp之上使用缓动曲线(缓入、缓出),以获得更友好的摄像机缩放和平移效果。
  • 当你想要“跟随但不超调”时,尝试使用临界阻尼平滑方法而不是简单的lerp;它感觉更紧凑,而且需要较少的调整。

线性代数

它是什么:向量和矩阵——“箭头”和“变换盒子”的花哨说法。向量描述位置、方向和速度。矩阵干净地移动和旋转物体。

它出现在哪里

  • 玩家移动、摄像机方向、后坐力、击退。
  • 光照(表面是否面向光源?)。
  • 剔除(这个三角形是否背对?)。
  • 皮肤和动画(骨骼只是变换)。

为什么重要:如果你深入研究一件事,那就应该是向量。掌握它们会使其他一切——物理、摄像机、AI转向——变得清晰。一个很好的日常例子:将操纵杆输入从摄像机空间转换到世界空间,这样操纵杆上的“上”始终朝向摄像机所看的方向。这其实就是“通过摄像机的偏航角旋转一个方向”。

离散数学、统计学和概率论

它是什么:适用于有步骤和选择的系统的逻辑(图、树),加上感觉公平的随机性(概率)。

它出现在哪里

  • 战利品表、暴击几率和伤害范围。
  • 寻路(A*算法适用于节点图)。
  • 行为树和状态机用于AI。
  • “不再有糟糕的连败”系统,使随机数生成器更友善。

小胜利:使用加权选择来获取战利品,但用怜悯计时器限制极端情况,以防止新玩家在开局不利后退出。对于BOSS阶段,当血量达到阈值时切换的简单状态机可以防止混乱的“if/else”代码并易于调试。

image.png

微积分和数值方法

它是什么:“随时间变化”。你不会写证明;你会使用速率和累积的概念。

它出现在哪里

  • 将加速度转换为速度,再将速度转换为位置。
  • 摄像机和平移的平滑阻尼运动。
  • 模拟弹簧、抛射物、绳索。
  • 用快速数值猜测解决“这两件事何时相遇?”的问题。

经验法则:使用稳定的时间步长感知更新(尊重deltaTime),并优先选择简单可靠的积分器而不是复杂的不稳定积分器。半隐式欧拉方法是许多运动的免费升级,RK4是快速子弹或紧绷弹簧的好朋友。
如果在高帧率下某些东西爆炸,那可能是一个时间步长问题——将物理锁定在一个固定的tick上。

掌握向量数学:运动的基础

把向量想象成一支箭:它指向的方向就是方向;它的长度就是数量。

理解二维和三维向量

长度(大小):箭有多长?用它来限制速度或测量距离。

归一化:将任何箭缩小到长度为1。现在它只是一个纯方向。非常适合于“以我选择的速度沿这个方向移动”。

投影:将运动分解成部分。想沿着墙壁滑动吗?去掉垂直于墙壁的速度部分。

友好习惯

  • 在紧密循环中比较平方距离以避免昂贵的平方根运算。
  • 在引擎中绘制调试线(光线)以查看方向并快速发现逻辑错误。
  • 保持单位一致(米,而不是“神秘单位”),以简化跨系统的调优。
点积和叉积解释

点积(对齐度量):如果两个方向指向相同的方向,则返回一个大数,否则返回一个小数或负数。
用途:视野检查、光照、选择正确的动画(前进 vs. 侧移)。

叉积(三维“垂直制造者”):给出一个与两个输入都完全90°的方向。
用途:为摄像机构建右/上/前框架、表面法线以及确定“左 vs. 右”。

快速心理模型:点积 = “多少在一起?”叉积 = “什么突出?”
在二维中,一个小技巧——a.x * b.y - a.y * b.x——告诉你b是在a的左边还是右边(非常适合转向和缠绕测试)。

实际应用案例:运动、方向和力

粘性斜坡:将运动分为沿地面和进入地面的部分。保留沿地面的部分;丢弃进入地面的部分以防止抖动。

瞄准锥:敌人是否在我的瞄准锥内?→ 检查dot(aimDir, toEnemyDir)是否高于某个阈值。

稳定的摄像机:使用叉积在摄像机旋转时重建干净的右/上/前集合,避免偏斜。

摩擦和阻力:每帧施加一个小的反向力以稳定运动;使其感知帧率,以便行为在不同机器上保持一致。

矩阵和变换:在三维空间中旋转和移动

矩阵将移动——平移、旋转、缩放——捆绑成一个整洁的对象。堆叠它们以构建最终变换。

游戏编程中的矩阵数学基础

齐次坐标(4×4):额外的分量允许平移与旋转和缩放在一次乘法中结合。

你会看到的空间:局部 → 世界 → 视图 → 裁剪 → 屏幕。错误通常来自于意外混用这些空间。

顺序很重要:缩放 → 旋转 → 平移的行为与平移 → 旋转 → 缩放不同。要保持一致。

照明提示:如果缩放破坏了你的照明,重新规范化法线或使用“法线矩阵”(旋转/缩放的逆转置)。
调试配方:打印一个点,当你将其推入每个空间时。如果它消失了,你就知道哪个乘法出了问题。

平移、旋转和缩放解释

平移:按某个偏移量移动对象。

旋转:围绕一个轴旋转一定角度(偏航/俯仰/滚转)。小心链接以避免奇怪的旋转。

缩放:使它变大或变小。均匀缩放是安全的;非均匀缩放可能会扭曲照明——尽早应用。

层次结构的合理性:子对象继承其父对象的变换。在编辑器中可视化局部轴,以预测装备和附件(武器、摄像机)的行为。

使用四元数避免万向节锁

四元数是一种紧凑、稳定的方式来存储旋转,是视频游戏程序员数学的重要组成部分。

为什么使用它们

  • 平滑插值(slerp):非常适合摄像机混合和角色瞄准。
  • 无万向节锁:组合多个小旋转而不会导致轴崩溃。
  • 简单的“看向”:从一个前向矢量加上一个向上提示构建旋转。

工作规则:不要手动编辑四元数的数字。从人类友好的输入(轴-角、欧拉角)构建它们,并在需要时将它们转换为/从方向矢量。对于第一人称摄像机,将偏航保持在世界向上轴上,将俯仰保持在局部右轴上——简单、稳定且直观。

三角学如何让你的游戏感觉真实

以下是三角学让你的游戏感觉真实的一些方式:

  • 摄像机轨道:使用cos和sin将摄像机放置在玩家周围的圆上;通过输入改变角度。
  • 起伏和呼吸:添加小幅相位偏移的正弦波,以实现逼真的运动,而无需大量动画工作。
  • 抛射物:使用atan2进行瞄准,通过每帧减少垂直速度来模拟重力,并绘制瞄准弧线以便玩家可以预测着陆点。
  • FOV变化:冲刺时稍微扩大FOV(渐入/渐出),以表现速度而不使人晕动。
  • 径向UI:使用(r cos θ, r sin θ)将项目均匀放置在圆上;使用缓动使选择感觉清脆。
  • 廉价的弧线:对于投掷预览,用几个段落近似路径——你不需要完整的物理模拟就能提供良好的反馈。

更智能的游戏系统:数学在AI、随机性和逻辑中的应用

这是“勉强能用”和“感觉公平、稳定且可调试”的游戏之间的区别。

战利品和RNG背后的数学
  • 期望值:大致传达一个宝箱平均值多少钱。
  • 加权选择:“普通”与“稀有”只是加权彩票。
  • 怜悯计时器/PRD:每次未命中后略微增加几率,以防止玩家遭受残酷的连败——长期几率相同,感觉更友好。
  • 播种随机性:为关卡使用种子,以便速通者可以重现运行,也便于报告bug。
  • 洗牌袋:预先填充一个袋子,包含结果(例如,节奏音符),然后不放回地抽取以避免聚集。
  • 面向玩家的信任:如果你使用坏运气保护,请告诉玩家它的存在。透明的系统无论输赢都感觉更公平。
在游戏中使用概率
  • 命中几率:像“可能/不可能”这样的桶比生硬的73%更好。或者使用伪随机以避免“90%三次未命中”引发的愤怒时刻。
  • 递减回报公式p = stat / (stat + k)防止堆叠失控并且容易调整。
  • 自然生成:带限制的随机延迟感觉比固定计时器更不可预测,但永远不会让玩家挨饿。
  • 调试异常连败:记录种子和输入;你可以重放一场奇怪的战斗并确切地看到为什么会发生这种情况。
  • 蓝噪声放置:均匀放置收集品或敌人,而不显得网格化——玩家会认为它们是“手工放置的”。
使用离散数学进行AI和寻路
  • 图统治:瓷砖、路点、导航网格——考虑带有移动成本的节点和边。
  • 一句话概括A**:已花费的成本 + 对目标的“猜测”。如果猜测从未高估,你将得到完美的路径;如果允许稍微高估,你将得到更快的“足够好”的路径。
  • 行为树(BT):比一个巨大的状态机更容易扩展和调试。
  • 影响地图:在网格中存储“热量”(危险、盟友、目标);AI在没有全局脑力的情况下朝着冷/温暖的地方移动。
  • 人群:混合远距离A*和近距离避障(RVO)。撒点随机性以防止NPC队伍相互碰撞。
  • LOS和平滑:A*之后,使用视线检查修剪不必要的转弯,使路径看起来像人类而不是“阶梯状”。

如何有效地练习和学习游戏开发数学

你会记住你构建的东西。将每个想法与一个可以实时调整的小型可视化项目联系起来。

推荐书籍、课程和教程
  • 《3D数学基础:图形与游戏开发》(Dunn & Parberry):清晰、实用、引擎友好。
  • 《3D游戏编程与计算机图形学中的数学》(Lengyel):更深入的内容——投影、蒙皮、高级变换。
  • 《游戏AI》(Millington & Funge):寻路、转向、决策与代码模式。
  • 《自然代码》(Shiffman):具有接近性的向量、力、随机性。
  • 短视频:3Blue1Brown 用于直觉;Khan Academy 用于快速复习。
  • 引擎文档和示例:Unity 数学/作业;Unreal 数学库——学习你的引擎已经优化的惯用法。
动手项目以建立真正的技能

保持它们小巧、可视化且有趣:

  • 向量游乐场:WASD加速;限制最大速度;沿墙壁滑动(投影)。将速度和法线绘制成线条。
  • 轨道摄像机:鼠标围绕目标偏航/俯仰;限制俯仰;添加碰撞反弹。尝试欧拉和四元数版本。
  • 战利品模拟器:加权表 + 怜悯计时器。运行10,000次试验并绘制结果以查看系统的感觉。
  • A玩具:点击放置障碍物并观看路径更新。交换启发式以查看速度与最优之间的权衡。
  • 鸟群(集群):三条简单规则——分离、对齐、凝聚——教你很多关于涌现行为的知识。
  • 弹簧实验室:比较基本欧拉、半隐式欧拉和RK4在一个弹跳弹簧上的效果。感受稳定性差异。
  • 平台游戏打磨:添加Coyote Time和跳跃缓冲——小数学,大感觉。
  • 曲线编辑器迷你版:构建一个小型工具来绘制缓动曲线并在运行时采样它们;它将提升你游戏中所有的过渡。

image.png

使用游戏引擎强化数学概念

你的引擎是一个免费的教室:

  • Draw gizmos:线条、光线和线框立即将看不见的数学变成你可以立即看到和理解的东西。
  • Trace spaces:在局部、世界和视图空间中打印或显示一个向量,以了解变换是如何堆叠的。
  • Respect time:按deltaTime缩放。考虑使用固定的物理tick,以使结果不受帧率影响。
  • Profiles and logs::数学错误通常表现为“性能不佳”。分析器揭示了由意外数学模式引起的紧密循环和分配。
  • Floating-point reality:大世界需要原点偏移以保持数字精度。使用一致的单位(米),并清理输入以避免NaN。
  • Guardrails:添加断言“此向量必须归一化”,在输入时限制角度,并集中数学辅助函数,使每个系统共享相同的安操作。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐