0

在 2D 游戏中有很多关于弹丸运动的例子。

  • 但是,在 2D 俯视图游戏中实现抛射运动的方程式是什么?例如,我们想踢一个球并增加它的高度(就像明智的足球一样)。

我读到可能有两个精灵,一个用于球,一个用于其阴影,可以产生球越来越高的错觉。

  • 但是,当球击中柱子时,我们如何实现碰撞检测和响应呢?我们是否也必须使用 z 坐标?
4

1 回答 1

4

您面临的问题说明了图形和逻辑之间的重要区别——即用户所看到的情况与该图像所反映的底层虚拟世界之间的区别。

2D 和 3D 世界的维度不必总是匹配。事实上,从根本上说,从 Pong 到 Skyrim,所有图形都是 2D 的。游戏开发者必须就维度做出的唯一决定是:

  • 游戏逻辑是3D的吗?
  • 如果是这样,3D 世界是如何投射到 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 维度。您可能希望将您的对象拆分为GameObjects 和GameObject3Ds,前者有一个xandy后者有一个额外的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 上的其他地方有很多很好的解释。

玩得开心你的游戏:)

于 2013-03-05T08:43:04.443 回答