在 2D 游戏中有很多关于弹丸运动的例子。
- 但是,在 2D 俯视图游戏中实现抛射运动的方程式是什么?例如,我们想踢一个球并增加它的高度(就像明智的足球一样)。
我读到可能有两个精灵,一个用于球,一个用于其阴影,可以产生球越来越高的错觉。
- 但是,当球击中柱子时,我们如何实现碰撞检测和响应呢?我们是否也必须使用 z 坐标?
在 2D 游戏中有很多关于弹丸运动的例子。
我读到可能有两个精灵,一个用于球,一个用于其阴影,可以产生球越来越高的错觉。
您面临的问题说明了图形和逻辑之间的重要区别——即用户所看到的情况与该图像所反映的底层虚拟世界之间的区别。
2D 和 3D 世界的维度不必总是匹配。事实上,从根本上说,从 Pong 到 Skyrim,所有图形都是 2D 的。游戏开发者必须就维度做出的唯一决定是:
就您而言,第一个问题的答案似乎是肯定的,考虑到球可以在空中踢。这意味着您现在在成熟的“3D”图形领域工作,这种图形可能永远存在。您现在所说的“2D 自上而下”游戏可能是指“无深度的 3D 自上而下游戏”。这是使用正交或等距投影来完成的,如果您好奇,可以用谷歌搜索。
阴影效果是完成这种投影的一个很好的选择,因为非常简单的提示可以在玩家对空间的视觉感知中发挥很大作用。请记住,这不是幻觉,就像光环中的 3D 图形是幻觉一样。屏幕是平的,我们的视网膜是平的,图形也应该是平的。这并没有使世界,无论是虚拟的还是物理的,都不再是 3D 的。
对于第二个问题,您可能不会完全自上而下地进行投影。如果你是,阴影总是会被球遮住,你只能看到足球运动员的头顶。我猜你可能在谈论 45 度角的向下投影,它看起来更自然,并且从一开始就在游戏中使用。口袋妖怪就是一个典型的例子。这一切都在行动:
class SoccerBall extends GameObject3D {
voic draw() {
translate(x, y / 2); // the camera is at an angle, so we foreshorten in the y direction
drawShadow();
translate(0, z / 2);
drawBall();
// cleanup the changes we made to the graphics state
translate(-x, -y / 2 - z / 2);
}
}
现在,回到你最初的问题,这主要是关于游戏逻辑的。通过将高度引入球的位置,您无疑引入了 z 维度。对于您的情况,可能很少使用此 z 维度。您可能希望将您的对象拆分为GameObject
s 和GameObject3D
s,前者有一个x
andy
后者有一个额外的z
(或者可能是 a height
,这可能会提供更多信息)。
弹丸运动非常简单。只需根据需要增加和减少高度
class SoccerBall extends GameObject3D {
float vel_x;
float vel_y;
float vel_z;
// most of the soccer ball class...
void kick(angle direction, angle inclination, float force) {
// calculate based on direction
vel_x = force * cos(direction);
vel_y = force * sin(direction);
// take into account inclination
vel_z = force * sin(inclination);
vel_x *= cos(inclination);
vel_y *= cos(inclination);
}
void movement_update(float delta_time) {
// this function assumes our location
// units are in meters
// and our velocity units
// are in meters/second
// apply gravity
vel_z -= 9.8 * delta_time; // EDIT: switched from += to -=. += could be useful if you're playing soccer with a balloon for a ball!
// move
x += vel_x * delta_time;
y += vel_y * delta_time;
z += vel_z * delta_time;
}
}
对于碰撞检测,如果你只关心与地面的碰撞,你可以做一个简单的if (z < 0) {z = 0; vel_z = 0}
检查。对于更复杂的情况,基于网格的系统始终是碰撞检测的好选择,因为计算对象的网格正方形很便宜(floor(x), floor(y)
),然后您只需要检查正方形中的其他对象。这在 3D 中和在 2D 中一样容易,并且在 Internet 上的其他地方有很多很好的解释。
玩得开心你的游戏:)