【问题标题】:Chase player with camera in AndEngine and limit world's bounds在 AndEngine 中用相机追逐玩家并限制世界的界限
【发布时间】:2013-07-05 20:09:08
【问题描述】:

使用 Android 版 AndEngine,我想让我的场景看起来像这样:

红色框是必须限制在给定大小的世界,例如2000px*450px

蓝色框是Camera,也有限制(像往常一样),例如750px*450px

对于整个场景,我的背景图像正好是450px 高。所以我的Camera 可以缩放到任何合适的大小,但背景必须完全适合高度。 Camera 的宽度可能是可变的。

玩家(圆圈)必须始终位于中心(水平方向),但不得离开世界边界。

为此,我尝试添加两种尺寸:

  • 相机尺寸(CAMERA_WIDTHCAMERA_HEIGHT
  • 世界大小(WORLD_WIDTHWORLD_HEIGHT

这个功能是为世界添加边界,以便物理引擎防止玩家离开这些边界:

private void createWorldBoundaries() {
    Body body;
    final Rectangle wall_top = new Rectangle(0, WORLD_HEIGHT-5, WORLD_WIDTH, 10, mVertexManager);
    final Rectangle wall_bottom = new Rectangle(0, 5, WORLD_WIDTH, 10, mVertexManager);
    final Rectangle wall_left = new Rectangle(5, 0, 10, WORLD_HEIGHT, mVertexManager);
    final Rectangle wall_right = new Rectangle(WORLD_WIDTH-5, 0, 10, WORLD_HEIGHT, mVertexManager);
    body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_top, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
    wall_top.setUserData(body);
    body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_bottom, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
    wall_bottom.setUserData(body);
    body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_left, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
    wall_left.setUserData(body);
    body = PhysicsFactory.createBoxBody(mPhysicsWorld, wall_right, BodyType.StaticBody, new PhysicsFactory.createFixtureDef(0.0f, 0.5f, 0.5f));
    wall_right.setUserData(body);
    attachChild(wall_top);
    attachChild(wall_bottom);
    attachChild(wall_left);
    attachChild(wall_right);
}

不幸的是,这不起作用。(见编辑)

将相机设置为追逐玩家对我来说有错误的结果:玩家确实一直停留在屏幕中心,但我希望玩家只水平停留在中心,而不是垂直。

我做错了什么,我可以改变什么?基本问题是:如何使世界比相机视图更宽,而高度等于相机视图。结果应该是您可以水平地穿过您的世界(移动相机),并且您始终可以看到完整的高度。

编辑:

当您定义Rectangle 的中心而不是左上角的坐标时,您必须这样做,看起来:

final Rectangle wall_top = new Rectangle(WORLD_WIDTH/2, WORLD_HEIGHT-1, WORLD_WIDTH, 2, mVertexManager);
final Rectangle wall_bottom = new Rectangle(WORLD_WIDTH/2, FIELD_BASELINE_Y+1, WORLD_WIDTH, 2, mVertexManager);
final Rectangle wall_left = new Rectangle(1, WORLD_HEIGHT/2, 2, WORLD_HEIGHT, mVertexManager);
final Rectangle wall_right = new Rectangle(WORLD_WIDTH-1, WORLD_HEIGHT/2, 2, WORLD_HEIGHT, mVertexManager);

但是,我在几个教程中找到了其他解决方案。这些作者是否在编写教程之前没有测试他们的代码,或者行为是否从 GLES1 更改为 GLES2 或任何最新版本?

【问题讨论】:

  • 长问题,长答案如下。答案应该很简单:使用SmoothCamera 而不是Camera,并设置绑定(使用setBounds())以满足您的世界维度。您可以设置相机移动速度(使用setMaxVelocity())以使其比被追逐实体的速度更快,因此被追逐实体将保持在中心,除非被追逐实体靠近边界。也可以暂时禁用绑定(使用setBoundsEnabled(false)),看看绑定是如何影响追击功能的。
  • 感谢您的评论!尽管此评论较短,但它并没有为下面的答案添加任何内容,是吗?相反,如果您打算让它比被追逐的实体更快,为什么还要使用SmoothCamera?在这种情况下,它将等于BoundCamera,不是吗?
  • @MarcoW。你是对的,只要你不使用最大速度作为真正的限制,你会得到一个ZoomCamera,直到你不想使用缩放,你会得到一个BoundCamera。 SmoothCamera 只是在 onUpdate 中添加了一些额外的计算来计算当前速度并将其限制为最大速度。变焦相机也会进行一些额外的计算以将变焦限制为最大和最小变焦系数
  • @MarcoW。如果我正确理解了您的问题(如果我没有正确理解,您真的可以忽略我上面的评论),您需要在相机上设置缩放系数,因为您说“相机的宽度可能是可变的”,这就是我建议的原因使用平滑相机。 (边界+缩放+移动速度控制)
  • 啊,现在我明白你指的是什么了,为此,你的答案是完全正确的。但我的意思是不同的:如果您的设备比例与应用程序中的设置不匹配,AndEngine 通常会在左右(或顶部/底部)添加白/黑条。但我希望我的Camera 只展示更多的世界(水平),从而用内容填充栏。你看,我的应用程序只有高度是固定的,但是如果设备的左右两侧有一些未使用的空间,它可能只是扩大了Camera的视图。

标签: android opengl-es 2d andengine


【解决方案1】:

我认为你关于世界边界的问题是自我回答的,不是吗?

物理世界边界

如需进一步研究,您可以从 Play 商店下载 nicolas 的 AndEngine 示例应用程序并在此处查找不同的示例(GLES_2,尚未查找 AnchorCenter):https://github.com/nicolasgramlich/AndEngineExamples/tree/GLES2/src/org/andengine/examples

取自 PhysicsExample,如果边界设置为相机边界,矩形的代码应如下所示。在您的情况下,您可以根据需要扩展宽度(3 倍 CAMERA_WIDTH?)

    final Rectangle ground = new Rectangle(0, CAMERA_HEIGHT - 2, WORLD_WIDTH, 2, vertexBufferObjectManager);
    final Rectangle roof = new Rectangle(0, 0, WORLD_WIDTH, 2, vertexBufferObjectManager);
    final Rectangle left = new Rectangle(0, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
    final Rectangle right = new Rectangle(WORLD_WIDTH - 2, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);

相机跟随播放器 为了让相机跟随你的玩家,你可以查找BoundCameraExample的代码https://github.com/nicolasgramlich/AndEngineExamples/blob/GLES2/src/org/andengine/examples/BoundCameraExample.java

对你来说有趣的部分应该是底部的 addFace 方法

private void addFace(final float pX, final float pY) {
    final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
final AnimatedSprite face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion, this.getVertexBufferObjectManager()).animate(100);
final Body body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
this.mScene.attachChild(face);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));

this.mBoundChaseCamera.setChaseEntity(face);
}

此方法为“你的玩家”(在本例中为盒装的脸)创建一个物理体 + 精灵,并将精灵设置为相机跟随的追逐实体。由于相机有边界,它不能超过并且您的相机将具有您的 PhysicWorld 边界的高度,您可以使用它让您的相机在 x 方向上跟随玩家,而不是在 y 方向上。

如果您(我不知道为什么)不想使用这些边界,您可以覆盖 Sprite 的 onUpdate 方法并仅在 x 方向上重新定位您的相机,而不是 xy 坐标

face.registerUpdateHandler(new IUpdateHandler() {
   @Override
   public void onUpdate(final float pSecondsElapsed) {
      float[] coord = face.getSceneCenterCoordinates();
      this.mBoundChaseCamera.setCenter(sceneCenterCoordinates[0], CAMERA_Y_POSITION);
   }
}

CAMERA_Y_POSITION 是一个带有 y 位置的静态最终字段。

我希望这能回答您的问题。 :-)

edit:哎呀,我忘了说,如何实现相机绑定,我将编辑上面的世界宽度:

    this.mBoundChaseCamera.setBounds(0, 0,
            WORLD_WIDTH, CAMERA_HEIGHT);

所有设置都像你给定的图像(除了面部的确切位置,必须给addFace(px, py)

编辑:Andengine GLES2 与 GLES2-AnchorCenter 中场景边界之间的差异

据我了解这个问题,我认为您会使用 GLES2,我想到了 AndEngine 的(旧)默认 GLES2 分支并发布了边界。正如您之前发现并在 cmets 中所述,您使用另一种方法来设置矩形 - 您需要将矩形中心设置为 pX 和 pY。这样做的原因其实是因为有了 AnchorCenter 分支,你不会再设置实体的左上角位置,而是使用它的中心位置。

【讨论】:

  • 谢谢,完美运行! :) 只有一件事:Rectangles(地面、屋顶、左、右)的代码是错误的,不是吗?它似乎遇到了我在问题中解释的相同问题(后来更正了)。如果您希望屋顶从0 变为WORLD_WIDTH,则不能将x 设置为0。您必须将其设置为 WORLD_WIDTH/2,因为 AndEngine 需要 Body 的中心坐标,而不是其左边缘。
  • 嗯,恕我直言,这不是真的 - 请参阅 nicolas 提供的 PhysicsExample 并在我的手机上工作 - 该示例应该完全符合您的需求,除了它们的 worldWidth = cameraWidth,而您的更大。我不太确定你为什么会遇到这个问题 - 你使用 anchorCenter 分支吗?如果您在 GLES2 上,您的初始帖子交换了顶部/底部栏,bc 0/0 位置是顶部/左侧(而在 anchorCenter 中它是底部/左侧),但这不应该是错误。
  • 我仍在考虑它,我无法想象,为什么您的边界代码有效而示例中的代码无效 - 让我有点头疼:-(但只要,因为它正在工作并且你很好,它可能没问题;-)
  • 我将再次编辑我的答案,以适应您的问题并提及 AnchorBranch 问题 ;-)
猜你喜欢
  • 2016-10-21
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 2012-01-20
  • 2021-03-10
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
相关资源
最近更新 更多