Slick2D和JBox2D。如何绘制

时间:2012-04-03 15:56:14

标签: java physics-engine slick2d jbox2d

在问这个之前我做了很多网上搜索。我不能这样做。这对我来说有点难以理解。那么我如何在与世界位置的身体相对应的右侧屏幕位置绘制图像?感谢名单。

如果有其他人在同一个障碍面前发现了他,我发布了一个如何操作,而不是正常速度的好解释。您可以在此处找到它:http://romeo.akademx.ro/2012/04/06/slick-and-box2d/

这是渲染功能:

public void render(GameContainer container, StateBasedGame game, Graphics g)
        throws SlickException {
    g.setBackground(Color.white);

    g.pushTransform();
    g.translate(worldToScreen(body.getPosition()).x, worldToScreen(body.getPosition()).y);
    g.rotate(15, 15, (float) Math.toDegrees(body.getAngle()));
    part.draw();
    g.popTransform();

    g.drawString("Count: " + cont, 5, 40);
    //world.drawDebugData();
}

这些是我用来转换世界屏幕协调的功能:

public Vec2 screenToWorld(Vec2 screenV) {
    return new Vec2((screenV.x - offset.x) / scaleFactor, yFlip
            * (screenV.y - offset.y) / scaleFactor);
}

public Vec2 worldToScreen(Vec2 worldV) {
    return new Vec2(worldV.x * scaleFactor + offset.x, yFlip * worldV.y
            * scaleFactor + offset.y);
}

我也碰巧使用此链接中的SlickDebugDraw:http://slick.javaunlimited.net/viewtopic.php?f=19&t=3610&sid=69614ac53aaf5724b808b75173e8e48e

但他的DebugDraw绘制了一个完全不同于渲染功能的东西。我有点困惑。

1 个答案:

答案 0 :(得分:64)

如果您所做的只是在2D世界中绘制精灵,那么基本上需要跟踪两件事情,以便决定在屏幕上绘制哪些精灵以及在屏幕上的哪个位置画它们。您必须将您的精灵视为存在于世界某个位置,以及您在屏幕上看到的仅仅是一个世界观,并专注于一个区域。

您需要跟踪的两件事是:

  1. 每个精灵都需要在世界范围内拥有自己的位置
  2. 您的相机"需要跟踪其相对于世界的位置。
  3. 所以,让我们说你有一个大的世界,2D坐标(x,y)空间为1,000,000 x 1,000,000像素(我在这里使用像素作为度量单位,但是这是一个随心所欲的选择,而世界的大小并不重要,我只选择了一个大的选择。那么,让我们说你有一个"相机"它指向那个世界,并且该摄像机的视图是屏幕上显示的内容。相机为您提供的显示尺寸为1024x768像素。

    我们也说你用箭头键将相机移到世界各地。

    因此,您的世界坐标空间会映射到您的屏幕:

    (0, 0)        +x
          +------------------>
          |
       +y |
          |      *  <= example sprite in your world @ coordinates (x=200, y=200)
          |
         \ /
    

    当你的精灵移动&#34;对&#34;他们增加x坐标。当他们移动&#34;离开&#34;他们减少了x坐标。移动&#34; up&#34;他们减少他们的y坐标(因为y向下增加,在监视器显示上),以及当移动&#34; down&#34;精灵增加他们的y坐标。

    现在,再一次,您在屏幕上看到的只是相机对世界的看法。因此,让我们设置相机的左上角位于(x=500, y=500)。这看起来像是:

    (0, 0)        +x
          +---------------------------------->
          |
       +y |
          |      *  <= example sprite in your world @ coordinates (x=200, y=200)
          |
          |
          |         +===================+
          |         |     the area      |
          |         |  that the camera  |
          |         |    "sees" and     |
          |         |   shows on your   |
          |         |       screen      |
          |         +===================+
         \ /
    

    通过这种设置,让我们说相机处于(500,500)(也就是说,相机的左上角视图,如本例中所示,位于世界坐标(500,500)。由于相机显示的区域大小为1024x768,因此相反的右下角为(500 + 1024,500 + 768)= (x=1524, y=1268)

    请注意,我们这个世界中的精灵在相机的视图区域内。这意味着,当我们在屏幕上渲染相机的视图时,我们不会看到精灵。

    相反,如果相机移动到(200,200),那么相机的视图区域将覆盖从左上角@(200,200)到右下角@(1224,968)的世界坐标,看起来像这样:

    (0, 0)        +x
          +---------------------------------->
          |   
       +y |  +===================+
          |  |                   |
          |  |   * <= sprite     |
          |  |                   |
          |  |                   | <= camera's view of the world
          |  +===================+
          |
          |
          |
          |
         \ /
    

    当相机处于此位置时,精灵可见。如果精灵是@(500,500),并且摄像机处于(200,200),那么当我们在屏幕上绘制精灵时,精灵将出现在坐标300处的在屏幕上 ,300。

    为什么?

    因为,这确实是你问题的答案,在哪里你在屏幕上绘制的东西是精灵的世界位置(500, 500),减去相机的位置(200,200),等于(300,300)。

    所以,回顾一下:

    使用箭头键(或鼠标或任何其他所需的控制方案)移动相机在世界各地的位置,并通过精灵&#渲染相对于相机位置的精灵位置39; s位置和减去相机的位置,你得到的是精灵应该出现的屏幕坐标

    但还有一件事......

    在世界上绘制每一个精灵真的效率很低。您只需要绘制相机视图中的精灵,否则您将绘制在屏幕上看不到的内容,从而浪费渲染/ CPU / GPU时间。 / p>

    因此,当您渲染相机的视图时,您需要遍历您的精灵,检查它们是否是相机&#34; (也就是说,它们是否在相机的视野范围内),并且仅在它们位于此视图中时才绘制它们。

    为了做到这一点,你必须采用相机的尺寸(在我们的例子中为1024x768),并检查精灵的位置是否在矩形的内部。相机的视图 - 相机左上角的位置,加上相机的宽度和高度。

    因此,如果我们的相机向我们显示尺寸为1024x768像素的视图,并且它的左上角位于(200,200),则视图矩形为:

    (200, 200)                      (1224, 200)
               +===================+
               |                   |
               |    *              |
               |                   |
               |                   |
               +===================+
    (200, 968)                      (1224, 968)
    

    精灵的位置@(500,500)位于相机的视野范围内,在这种情况下。

    如果您需要更多示例,我有一个名为Pedestrians的Slick2D技术演示,其中包含您可以查看的代码。有关如何计算应呈现的世界区域的详细信息,请查看this file中的render方法,并特别注意startXstartYstopXstopY个变量,我可以控制我要绘制的精灵区域。还应该注意的是,我的精灵(或者#34;行人&#34;)存在于TileMap上,因此它们的大小不是1像素 - 它们具有自己的宽度和高度。这为如何决定绘制内容增加了一点点复杂性,但它基本上归结为,&#34;在相机的视图中绘制内容,以及边缘附加一些额外内容。 #34;

    在您自己的计算机上克隆Pedeestrians存储库,通过向项目添加与任何其他Slick2D项目相同的依赖项来使其工作,并播放/修改呈现代码,直到您了解正在进行的操作。只有通过练习和学习,你才能获得有关其工作方式的所有细节。好消息是,一旦你弄清楚如何使用这个基本的2D世界与相机方法进行渲染,你就会非常了解如何为所有2D应用渲染图形,因为这些概念可以转换为所有语言。

    我还有my YouTube channel上运行的行人的各种视频(最相关的视频可能是this one,它显示我的基本行人正在渲染,相机移动),所以你可以看到这一切看起来都是如此,而不必先建立项目。