Slick2D和JBox2D。 如何绘制

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

如果有人在同一个障碍面前找到了他,我会发布一个HOW TO,而不是正常速度的好解释。 你可以在这里找到它: http : //romeo.akademx.ro/2012/04/06/slick-and-box2d/

这是渲染function:

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(); } 

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

 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绘制了一个完全不同于渲染function的东西。 我有点困惑。

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

您需要跟踪的两件事是:

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

所以,假设你有一个大的,大的世界,2D坐标(x,y)空间为1,000,000 x 1,000,000像素(我在这里使用像素作为度量单位,但这是一个任意的选择,以及世界无所谓,我刚刚选了一个大的)。 然后,假设您有一个指向该世界的“相机”,该相机的视图就是屏幕上显示的内容。 相机为您提供的显示尺寸为1024×768像素。

我们还假设您使用箭头键将该摄像机移动到世界各地。

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

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

当你的精灵“向右”移动时,它们会增加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 | | +===================+ \ / 

使用该设置,假设相机处于(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)。

所以,审查:

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

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

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

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

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

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

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

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

如果你需要更多的例子,我有一个工作的Slick2D技术演示,称为Pedestrians ,它有你可以看到的代码。 有关如何计算应该渲染的世界区域的详细信息,请查看此文件中的render方法,并特别注意startXstartYstopXstopY变量,这些变量用于控制精灵区域。我要去画画。 还应该注意的是,我的精灵(或“行人”)存在于TileMap ,因此它们的大小不是1像素 - 它们具有自己的宽度和高度。 这为如何决定绘制内容增加了一点点复杂性,但它基本上归结为“在相机视图中绘制内容,加上边缘附加一些额外内容”。

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

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