Slick2D和JBox2D.如何绘制

Rom*_*meo 14 java physics-engine jbox2d slick2d

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

如果有人在同一个障碍面前找到了他,我会发布一个HOW TO,而不是正常速度的好解释.你可以在这里找到它: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();
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

jef*_*unt 64

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

您需要跟踪的两件事是:

  1. 每个精灵都需要在世界范围内占有一席之地
  2. 您的"相机"需要跟踪其相对于世界的位置.

所以,假设你有一个大的,大的世界,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)
      |
     \ /
Run Code Online (Sandbox Code Playgroud)

当你的精灵"向右"移动时,它们会增加x坐标.当他们向左移动时,他们减少了他们的x坐标.当向上移动时,它们会减小它们的y坐标(因为y在监视器显示屏上向下增加),当向下移动时,精灵会增加它们的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      |
      |         +===================+
     \ /
Run Code Online (Sandbox Code Playgroud)

使用该设置,假设相机位于(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
      |  +===================+
      |
      |
      |
      |
     \ /
Run Code Online (Sandbox Code Playgroud)

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

为什么?

因为,这是真正的回答你的问题,在那里你在屏幕上画一些东西是精灵的世界位置(500,500),减去相机的位置(200,200),它等于(300,300).

所以,要审查:

使用箭头键(或鼠标或任何其他控制方案)将摄像机的位置移动到世界各地,然后通过获取精灵的位置并减去摄像机的位置来渲染相对于摄像机位置的精灵位置,以及你得到的是精灵应该出现的屏幕坐标.

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

绘制世界上每一个精灵都是非常低效的.您只需绘制摄像机视图内的精灵,否则您将绘制在屏幕上看不到的东西,因此浪费渲染/ CPU/GPU时间.

因此,当您渲染相机的视图时,您需要遍历您的精灵,检查它们是否"在相机上"(即,它们是否在相机的视野内),并且仅绘制如果他们在这个观点内,他们.

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

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

(200, 200)                      (1224, 200)
           +===================+
           |                   |
           |    *              |
           |                   |
           |                   |
           +===================+
(200, 968)                      (1224, 968)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,精灵的位置@(500,500)位于摄像机视图内.

如果你需要更多的例子,我有一个工作的Slick2D技术演示,称为Pedestrians,它有你可以看到的代码.对于我如何计算出应呈现的世界区域的详细信息,看看render里面的方法这个文件,并要特别注意startX,startY,stopX,stopY变量,这对我来说控制的精灵,我要绘制的区域.还应该注意的是,我的精灵(或"行人")存在于a上TileMap,因此它们的大小不是1像素 - 它们具有自己的宽度和高度.这为如何决定绘制内容增加了一点点复杂性,但它基本上归结为"在相机视图中绘制内容,加上边缘附加一点点".

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

我也有各种各样的行人视频在我的YouTube频道上运行(最相关的视频可能是这个,它显示我的基本行人正在渲染,相机移动),所以你可以看到这一切看起来像什么,而不必首先构建项目.

  • 我读过的关于SO的最佳和更具信息性的答案之一.好帖子. (8认同)