UD动作游戏开发读书笔记--. D游戏所需要的数学知识

UD动作游戏开发读书笔记--. D游戏所需要的数学知识 UD动作游戏开发读书笔记2D游戏所需要的数学知识大家好我是你们的老朋友——一个从“看到数学就头疼”到“用数学做出酷炫游戏”的资深技术博主。今天我们来聊聊《UD动作游戏开发》这本书里最硬核但也最有趣的部分2D游戏所需要的数学知识。别担心我不会一上来就丢一堆公式把你吓跑。咱们从游戏开发的实际场景出发用代码和例子来理解这些数学概念。你会发现数学不是枯燥的符号而是让角色动起来、让攻击打中、让世界变得真实的魔法。## 为什么2D游戏需要数学你可能觉得2D游戏不就是上下左右移动吗顶多再加个碰撞检测小学数学就够了。但如果你真的做过游戏就会知道没有数学你的角色可能永远走不到正确的位置子弹会穿模跳跃会像在月球上走路。2D游戏的核心数学包括-坐标与向量定位角色、计算方向。-三角函数旋转、瞄准、弹道。-线性插值平滑移动、动画过渡。-碰撞检测判断是否击中敌人或遇到障碍。这些概念看似抽象但用代码实现后你会发现它们就是游戏世界的“物理定律”。## 1. 坐标系统与向量让角色动起来在2D游戏中我们通常使用笛卡尔坐标系。原点通常在左上角x轴向右y轴向下或者向上取决于引擎。每个角色都有一个位置(x, y)。向量是游戏开发中的“瑞士军刀”。它表示方向和大小。比如角色从(0, 0)移动到(3, 4)这个位移向量就是(3, 4)它的长度模是5因为3^2 4^2 5^2。### 代码示例1用向量移动角色下面是一个简单的Python示例使用Pygame库模拟2D游戏逻辑来展示向量的基本用法。pythonimport pygameimport math# 初始化Pygamepygame.init()screen pygame.display.set_mode((800, 600))clock pygame.time.Clock()# 角色位置和速度向量player_pos [400, 300] # 初始位置在屏幕中心velocity [0, 0] # 初始速度为0# 游戏主循环running Truewhile running: for event in pygame.event.get(): if event.type pygame.QUIT: running False # 获取按键输入更新速度向量 keys pygame.key.get_pressed() speed 5 vx, vy 0, 0 if keys[pygame.K_LEFT]: vx -speed if keys[pygame.K_RIGHT]: vx speed if keys[pygame.K_UP]: vy -speed if keys[pygame.K_DOWN]: vy speed # 应用速度向量更新位置 player_pos[0] vx player_pos[1] vy # 清屏并绘制角色 screen.fill((0, 0, 0)) pygame.draw.circle(screen, (255, 0, 0), player_pos, 20) pygame.display.flip() clock.tick(60)pygame.quit()解释 -velocity向量控制移动方向和速度。如果同时按上键和右键角色会以45度角斜向移动因为vx和vy同时非零。- 这就是向量的加法位置 旧位置 速度向量。简单吧## 2. 三角函数让角色瞄准和旋转在动作游戏中敌人需要朝向玩家射击子弹需要沿直线飞行这些都需要三角函数。核心公式-cos(θ) 邻边 / 斜边 -sin(θ) 对边 / 斜边 -tan(θ) 对边 / 邻边 在代码中我们常用math.atan2(dy, dx)来计算角度因为它是“安全”的反正切函数能处理所有象限。### 代码示例2让敌人始终面向玩家这个例子展示如何用三角函数让一个“敌人”时刻指向玩家。pythonimport pygameimport mathpygame.init()screen pygame.display.set_mode((800, 600))clock pygame.time.Clock()# 敌人和玩家的位置enemy_pos [100, 100]player_pos [400, 300]# 敌人图片模拟一个箭头enemy_image pygame.Surface((50, 30), pygame.SRCALPHA)pygame.draw.polygon(enemy_image, (0, 255, 0), [(0, 0), (50, 15), (0, 30)])running Truewhile running: for event in pygame.event.get(): if event.type pygame.QUIT: running False # 计算从敌人到玩家的向量 dx player_pos[0] - enemy_pos[0] dy player_pos[1] - enemy_pos[1] # 使用atan2计算角度注意Pygame的y轴向下所以角度需要取反 angle math.atan2(dy, dx) # 返回弧度 # 旋转敌人图片 rotated_enemy pygame.transform.rotate(enemy_image, -math.degrees(angle)) # 获取旋转后的矩形保持中心对齐 rect rotated_enemy.get_rect(centerenemy_pos) # 绘制 screen.fill((0, 0, 0)) screen.blit(rotated_enemy, rect.topleft) pygame.draw.circle(screen, (255, 255, 255), player_pos, 10) # 模拟玩家移动按方向键 keys pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_pos[0] - 3 if keys[pygame.K_RIGHT]: player_pos[0] 3 if keys[pygame.K_UP]: player_pos[1] - 3 if keys[pygame.K_DOWN]: player_pos[1] 3 pygame.display.flip() clock.tick(60)pygame.quit()解释 -math.atan2(dy, dx)返回从敌人指向玩家的弧度角。 -pygame.transform.rotate需要角度度所以我们用math.degrees()转换并取负号因为Pygame的坐标系y轴向下。 - 现在敌人会像“追踪导弹”一样始终面向你这就是三角函数在瞄准系统中的应用。## 3. 线性插值让移动更平滑游戏中经常需要让角色从一个点平滑移动到另一个点比如镜头过渡、敌人追踪。这时候就要用到线性插值Lerp。公式很简单result start (end - start) * t其中t是0到1之间的值代表进度。### 代码示例3用Lerp实现平滑跟随pythonimport pygamepygame.init()screen pygame.display.set_mode((800, 600))clock pygame.time.Clock()# 玩家和跟随方块的初始位置player_pos [400, 300]follower_pos [100, 100]def lerp(a, b, t): 线性插值函数 return a (b - a) * trunning Truewhile running: for event in pygame.event.get(): if event.type pygame.QUIT: running False # 玩家移动按方向键 keys pygame.key.get_pressed() if keys[pygame.K_LEFT]: player_pos[0] - 5 if keys[pygame.K_RIGHT]: player_pos[0] 5 if keys[pygame.K_UP]: player_pos[1] - 5 if keys[pygame.K_DOWN]: player_pos[1] 5 # 用Lerp让跟随方块平滑移动每次只移动10%的距离 follower_pos[0] lerp(follower_pos[0], player_pos[0], 0.1) follower_pos[1] lerp(follower_pos[1], player_pos[1], 0.1) # 绘制 screen.fill((0, 0, 0)) pygame.draw.circle(screen, (0, 255, 0), player_pos, 20) pygame.draw.rect(screen, (255, 0, 0), (follower_pos[0]-15, follower_pos[1]-15, 30, 30)) pygame.display.flip() clock.tick(60)pygame.quit()解释 -lerp函数让红色方块每次只向玩家位置移动10%的距离。 - 随着距离缩短移动速度也会变慢产生一种“弹性跟随”的效果。这在游戏UI动画、镜头跟踪中非常常用。## 4. 碰撞检测判断是否打中敌人2D动作游戏的核心是“碰撞”。最简单的碰撞检测是矩形碰撞AABB和圆形碰撞。- 矩形碰撞检查两个矩形是否重叠。 - 圆形碰撞检查两个圆心的距离是否小于半径之和。### 代码片段圆形碰撞检测pythonimport mathdef circle_collision(c1_pos, c1_radius, c2_pos, c2_radius): 检测两个圆是否碰撞 dx c1_pos[0] - c2_pos[0] dy c1_pos[1] - c2_pos[1] distance math.sqrt(dx**2 dy**2) return distance c1_radius c2_radius# 示例玩家和子弹player (400, 300, 20) # x, y, 半径bullet (450, 320, 5)if circle_collision(player, bullet): print(命中)解释 - 使用勾股定理计算距离然后与半径之和比较。 - 这是游戏中最基础的碰撞检测效率高且易于理解。## 总结看到这里你是不是觉得数学也没那么可怕在2D游戏开发中数学就是一套“工具箱”-向量控制移动、方向。 -三角函数实现瞄准、旋转。 -线性插值平滑过渡、缓动效果。 -碰撞检测判断交互是否发生。这些知识不仅是《UD动作游戏开发》这本书的基础也是任何2D游戏的基石。下次当你看到一个角色流畅地移动、子弹精准地命中目标时别忘了——背后都是数学在“暗中发力”。记住数学不是障碍而是游戏的超级武器。多动手写代码多画图理解你也能成为“数学型”游戏开发者如果你觉得这篇文章对你有帮助欢迎点赞、收藏我们下期再见