避免在 2D 游戏引擎中嵌套 for 循环
Avoiding nested for loops in 2D game engine
我正在创建一个 2D 游戏。
有很多objects
,每个都有宽度,高度,X和Y坐标。
每个对象都存储在 class 的 array
中:
- 玩家
- 盟友
- 敌人
- 障碍
- 能量提升
- 敌人射出的子弹
- 玩家和盟友射出的子弹
为了让游戏正常运行,我需要明显地检测两个元素是否占用相同的 space(我们称之为 "collission"),以便
- 玩家可以收集道具
- 没有人可以通过障碍物
- 盟友可以射击敌人
- 敌人可以射击盟友
- 可以启用或禁用误伤
这需要每帧检查一次,每秒60次。
到目前为止我一直在做的是遍历每个 class,然后遍历每个可以与之交互的 class。
例如:
foreach (ally_bullets)
{
foreach (enemies)
{
if ( collision detected between enemy and bullet )
{
remove the bullet and the enemy
}
}
}
这很有意义,也很有效,但随着游戏变得越来越复杂,它会占用大量资源。元素越多,这个嵌套的 for 循环渲染的时间就越长,最终会降低帧率。即使我试图 运行 尽可能少的循环。
解决这个嵌套 for 循环的更好方法是什么?
一个常见的解决方案是使用 Polymorphism, in which you have a base class (in this case Object) which gets inherited by other classes (such as Player, Bullet, Enemy, etc). Instead of each of these having an individual array, you would have a single array (or typically more appropriate, a vector)。现在您只需循环遍历一个数组,让每个对象进行更新,并针对数组中的每个对象检查它们的更新。
此 'vector-wise' 更新通常设置为 Messaging System。现在,只要继承的对象收到一条消息(例如 'hit by bullet'),该对象就会检查它是否关心该消息。如果是,请接受消息,否则忽略它。
这是(在我看来)处理你想要完成的事情的更好方法,我相信这就是你要问的。
如果您仍在为此使用数组,我假设您对编程还是很陌生,我建议您坚持使用现有的。它绝对有效(前提是你知道如何完成你的项目),当你完成这个并开始学习更高级的东西时,你会看到你这样做的缺点和它的好处)。
如果您确实看到出现了一些滞后,很可能是在这种交互性检查成为瓶颈之前很久就由您的绘图方法引起的。
无论你走哪条路,碰撞检测本身和渲染将是你的 cpu 被吃掉的主要区域,前提是你的数组保持在合理的范围内。
编辑:
如果您追求我提到的主题,另一件可以帮助您的事情是 Observer Pattern, also known as the Listener Pattern.
我正在创建一个 2D 游戏。
有很多objects
,每个都有宽度,高度,X和Y坐标。
每个对象都存储在 class 的 array
中:
- 玩家
- 盟友
- 敌人
- 障碍
- 能量提升
- 敌人射出的子弹
- 玩家和盟友射出的子弹
为了让游戏正常运行,我需要明显地检测两个元素是否占用相同的 space(我们称之为 "collission"),以便
- 玩家可以收集道具
- 没有人可以通过障碍物
- 盟友可以射击敌人
- 敌人可以射击盟友
- 可以启用或禁用误伤
这需要每帧检查一次,每秒60次。
到目前为止我一直在做的是遍历每个 class,然后遍历每个可以与之交互的 class。
例如:
foreach (ally_bullets)
{
foreach (enemies)
{
if ( collision detected between enemy and bullet )
{
remove the bullet and the enemy
}
}
}
这很有意义,也很有效,但随着游戏变得越来越复杂,它会占用大量资源。元素越多,这个嵌套的 for 循环渲染的时间就越长,最终会降低帧率。即使我试图 运行 尽可能少的循环。
解决这个嵌套 for 循环的更好方法是什么?
一个常见的解决方案是使用 Polymorphism, in which you have a base class (in this case Object) which gets inherited by other classes (such as Player, Bullet, Enemy, etc). Instead of each of these having an individual array, you would have a single array (or typically more appropriate, a vector)。现在您只需循环遍历一个数组,让每个对象进行更新,并针对数组中的每个对象检查它们的更新。
此 'vector-wise' 更新通常设置为 Messaging System。现在,只要继承的对象收到一条消息(例如 'hit by bullet'),该对象就会检查它是否关心该消息。如果是,请接受消息,否则忽略它。
这是(在我看来)处理你想要完成的事情的更好方法,我相信这就是你要问的。
如果您仍在为此使用数组,我假设您对编程还是很陌生,我建议您坚持使用现有的。它绝对有效(前提是你知道如何完成你的项目),当你完成这个并开始学习更高级的东西时,你会看到你这样做的缺点和它的好处)。
如果您确实看到出现了一些滞后,很可能是在这种交互性检查成为瓶颈之前很久就由您的绘图方法引起的。
无论你走哪条路,碰撞检测本身和渲染将是你的 cpu 被吃掉的主要区域,前提是你的数组保持在合理的范围内。
编辑: 如果您追求我提到的主题,另一件可以帮助您的事情是 Observer Pattern, also known as the Listener Pattern.