【问题标题】:libgdx camera position using viewport使用视口的libgdx相机位置
【发布时间】:2017-04-04 18:05:45
【问题描述】:

我是经验丰富的 libgdx 开发人员,但我在一个问题上苦苦挣扎了一段时间,所以我决定在这里提问。

我使用 FillViewport、TiledMap、Scene2d 和 OrtographicCamera。我希望相机跟随我的播放器实例,但定义了边界(等于地图大小)。这意味着相机永远不会离开地图之外,所以当玩家到达地图的尽头时,相机会停止跟随并且他会走到屏幕本身的边缘。也许听起来很复杂,但它很简单,我相信你知道我的意思,它在每个游戏中都会用到。

我计算了 4 个值:

minCameraX = camera.viewportWidth / 2;
minCameraY = camera.viewportHeight / 2;
maxCameraX = mapSize.x camera.viewportWidth / 2;
maxCameraY = mapSize.y - camera.viewportHeight / 2;

我删除了单位转换、camera.zoom 等不必要的东西。然后我像这样设置相机位置:

camera.position.set(Math.min(maxCameraX, Math.max(posX, minCameraX)), Math.min(maxCameraY, Math.max(posY, minCameraY)), 0);

(posX, posY is player position) 这基本上是将相机设置为玩家位置,但如果它太高或太低,它会将其设置为之前在右轴上定义的最大值或最小值。 (我也尝试过 MathUtils.clamp(),它的工作原理是一样的。

到目前为止,一切都很完美。当纵横比改变时会出现问题。默认情况下,我使用 1280x768,但我的手机有 1280x720。由于 FillViewport 的工作方式,屏幕的底部和顶部边缘被切断。因为我的地图的那部分被切断了。

我尝试修改最大值和最小值,计算比率差异并将它们添加到计算中,更改相机尺寸,不同的视口和其他一些东西,但没有成功。

你们能帮忙吗? 谢谢

【问题讨论】:

  • 到底是什么问题?您的相机边界机制不再起作用,还是屏幕部分被切断的问题?
  • 第二个。顶部和底部边缘被切割,因此我看不到例如地图结束框。当然我知道这就是 FillViewport 的工作方式,但应该可以修改相机边界来修复它
  • 我不确定它在这种情况下是否有效,但您可以尝试将 getTopGutterHeight() 和 getBottomGutterHeight() 添加到您的 minCameraY 和 maxCameraY (或者可能反过来并减去而不是添加? )
  • 晚上一定要试试。我会告诉你的
  • @noone - 这不是仅适用于 FitViewport 吗?

标签: camera libgdx viewport bounds tiled


【解决方案1】:

我从上面的 cmets 尝试了 noone 和 Tenfour04 的解决方案。两者都不完美,但我猜我很满意:

没有人:

camera.position.x = MathUtils.clamp(camera.position.x, screenWidth/2 + leftGutter, UnitConverter.toBox2dUnits(mapSize.x) - screenWidth/2 + rightGutter);
camera.position.y = MathUtils.clamp(camera.position.y, screenHeight/2 + bottomGutter, UnitConverter.toBox2dUnits(mapSize.y) - screenHeight/2 - topGutter);

但它只适用于小范围的分辨率。对于宽高比与默认分辨率大不相同的奇怪分辨率,我在边框后看到了白色条纹。这意味着整个边界都是打印机,而边界之外的世界的某些部分。不知道为什么

Tenfour04: 我将视口更改为 ExtendViewport。没有任何东西被截断,但在不同的纵横比下,我也可以看到边界之外的世界。

两者的解决方案是分别清除与边框颜色相同的屏幕和水平背景,这两种情况下的效果都令人满意。

它仍然有一些限制。由于边框是世界的一部分(平铺块),所以当它具有相同的颜色时就可以了。如果边框有不同的颜色,在边框之外渲染一种颜色将不是解决方案。

感谢 noone 和 Tenfour04,我仍然愿意寻求建议:)

以下是一些截图: https://www.dropbox.com/sh/00h947wkzo73zxa/AAADHehAF4WI8aJ8bu4YzB9Va?dl=0

【讨论】:

  • 只要世界至少和屏幕一样大,假设您使用问题中显示的相机夹紧装置,我不确定您最终会如何看到边界之外.我所做的是使用 4:3 分辨率的虚拟宽度和高度,然后确保世界有足够的空间覆盖至少 16:9 的版本。例如,如果您的虚拟尺寸是 400x300,那么您的世界至少需要 534 宽才能确保您永远看不到虚空。您可以添加额外的风景图块以确保在小舞台上做到这一点。
  • 我添加了一些截图来可视化问题
【解决方案2】:

为什么不使用FitViewport 而不是FullViewport?这样它就不会切断你的屏幕,对吧?

【讨论】:

  • 制作难看的白色条纹
【解决方案3】:

虽然有点晚了,但我有一个不折不扣的解决方案!

这里的宽度和高度是以像素为单位的世界大小。我将此代码与 FillViewport 一起使用,一切正常!

float playerX = player.getBody().getPosition().x*PPM;
float playerY = player.getBody().getPosition().y*PPM;

float visibleW =  viewport.getWorldWidth()/2 + (float)viewport.getScreenX()/(float)viewport.getScreenWidth()*viewport.getWorldWidth();//half of world visible
float visibleH = viewport.getWorldHeight()/2 + (float)viewport.getScreenY()/(float)viewport.getScreenHeight()*viewport.getWorldHeight();

float cameraPosx=0;
float cameraPosy=0;

if(playerX<visibleW){
    cameraPosx = visibleW;
}
else if(playerX>width-visibleW){
    cameraPosx = width-visibleW;
}
else{
    cameraPosx = playerX;
}

if(playerY<visibleH){
    cameraPosy = visibleH;
}
else if(playerY>height-visibleH){
    cameraPosy = height-visibleH;
}
else{
    cameraPosy = playerY;
}

camera.position.set(cameraPosx,cameraPosy,0);

camera.update();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2016-02-01
    相关资源
    最近更新 更多