在AndEngine中追逐相机并限制世界范围(Chase player with camera in AndEngine and limit world's bounds)

编程入门 行业动态 更新时间:2024-10-27 20:36:46
在AndEngine中追逐相机并限制世界范围(Chase player with camera in AndEngine and limit world's bounds)

使用AndEngine for Android,我想让我的场景如下所示:

红色框是必须限制给定尺寸的世界,例如2000px*450px 。

蓝色框是Camera ,它也是如此(如往常一样),例如750px*450px 。

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

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

为了达到这个目的,我尝试添加两种尺寸:

相机大小( CAMERA_WIDTH , CAMERA_HEIGHT ) 世界大小( WORLD_WIDTH , WORLD_WIDTH )

而这个功能是为了增加世界的边界,以便物理引擎阻止玩家离开这些边界:

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或者任何最新版本?

Using AndEngine for Android, I would like to have my scene look like this:

The red box is the world which must be limited to a given size, say 2000px*450px.

The blue box is the Camera, which is limited as well (as usual), for example to 750px*450px.

For the whole scene, I have a background image that is exactly 450px high. So my Camera can be scaled to whatever size is appropriate, but the background must exactly fit to the height. The width of the Camera may be variable.

The player (circle) must always be in the center (horizontally) but may not leave the world's boundaries.

To achieve this, I've tried adding two types of sizes:

camera size (CAMERA_WIDTH, CAMERA_HEIGHT) world size (WORLD_WIDTH, WORLD_HEIGHT)

And this function was to add boundaries to the world so that the physics engine prevents the player from leaving those boundaries:

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

But this is not working, unfortunately. (see edit)

Setting the camera to chase the player has the wrong result for me: The player does really stay in the center of the screen all time, but I want the player only to stay in the center horizontally, not vertically.

What am I doing wrong and what can I change? And the basic question is: How can I make the world wider than the camera view, while the height is equal to the camera view. The result should be that you can horizontally walk through your world (moving camera) and you can always see the full height.

Edit:

As you define the coordinates of the Rectangle's center and not its top-left corner, you have to do it like this, it seems:

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

However, I had found the other solution in several tutorials. Are these authors not testing their code before writing the tutorials or did the behaviour change from GLES1 to GLES2 or with any recent version?

最满意答案

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

物理世界边界

对于进一步的研究,您可以从Play商店下载nicolas的AndEngine示例应用程序,并在此查找不同的示例(GLES_2,并未查找AnchorCenter): https : //github.com/nicolasgramlich/AndEngineExamples/tree/GLES2/ SRC /组织/ andengine /例子

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

这个方法为“你的玩家”创建一个物理体+精灵(在这种情况下,是一个盒装脸),并将精灵设置为相机跟随的chaseEntity。 由于相机有界限,不能超过,并且相机将具有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位置的静态最终字段。

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

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

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

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

编辑:Andengine GLES2与GLES2-AnchorCenter中场景边界的区别

据我了解这个问题,我想你会使用GLES2,我想到了AndEngine的(旧的)默认GLES2分支并且发布了边界。 当你发现自己并在评论中陈述时,你可以使用另一种方法来设置矩形 - 你需要将矩形中心设置为pX和pY。 其原因实际上是,使用AnchorCenter分支,您不会再设置实体的左上角位置,而是使用它的中心位置。

i think your question about the world boundaries is self answered, isn't it?

PhysicsWorld Boundaries

for further research you can download nicolas' AndEngine Examples App from the Play Store and look up the different examples here (GLES_2, didn't look for AnchorCenter yet): https://github.com/nicolasgramlich/AndEngineExamples/tree/GLES2/src/org/andengine/examples

Taken from the PhysicsExample, the code for the rectangles should look like this, if the bounds are set to the camera bounds. in your case, you can extend width like you want (3 times 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);

Camera following player for the Camera to follow your player, you can lookup the code of the BoundCameraExample https://github.com/nicolasgramlich/AndEngineExamples/blob/GLES2/src/org/andengine/examples/BoundCameraExample.java

the interesting part for you should be the addFace method at the bottom

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

this method creates a physics body + sprite for "your player" (in this case, a boxed face) and sets the sprite as a chaseEntity for the camera to follow. Since the camera has bounds, that it can't exceed and your camera will have the height of your PhysicWorld boundaries, you can use this to let your camera follow the player in x, but not in y direction.

if you (i don't know why) don't want to use these boundaries, you can overwrite the onUpdate method of your Sprite and re-locate your camera only in x-direction, instead of xy coords

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

where the CAMERA_Y_POSITION is a static final field with the y-position.

I hope this answers your question(s). :-)

edit: oops, i forgot to mention, how to achieve the camera to be bound and i will edit the world width above:

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

all settings are like your image given (except the exact position of the face, that has to be given to the addFace(px, py))

Edit: Difference between scene boundaries in Andengine GLES2 vs GLES2-AnchorCenter

As far as i understood the question, i thought you would use GLES2, i thought of the (older) default GLES2 branch of AndEngine and posted the boundaries. As you found out yourself before and stated in the comments, you use another approach to set the rectangles - where you need to set the rectangles center as pX and pY. The reason for this is in fact, that with the AnchorCenter branch, you won't set the upper left position of an entity anymore and instead use it's center position.

更多推荐

本文发布于:2023-07-21 09:40:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1209025.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:相机   世界   Chase   AndEngine   player

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!