Tiled地图对象的位置为x,y(以像素为单位)和旋转度(以度为单位)。
我正在从地图加载坐标和旋转,并尝试将它们分配给box2d正文。位置模型之间存在一些差异,例如Tiled对象旋转以度为单位,box2d体角度为弧度。
如何将位置转换为BodyDef坐标x,y和角度,以便在正确的位置创建正文?
使用代码:
float angle = -rotation * MathUtils.degreesToRadians;
bodyDef.angle = angle;
bodyDef.position.set(x, y);
当旋转为0时工作,但当旋转不是0时,正文未正确定位。
我在这里找到了几个提示:
http://www.tutorialsface.com/2015/12/qu ... dx-solved/
在这里:
https://github.com/libgdx/libgdx/issues/2742
这似乎解决了这个确切的问题,但是这两个解决方案对我都不起作用,在应用这些转换后,身体对象仍然处于错误状态。如果定位错误,我的意思是主体位于地图区域应该是,但稍微取决于其旋转。
我觉得它应该很简单,但我不知道如何调解Tiled和box2d位置之间的差异。
作为参考,这些是我从上面的链接尝试的两个解决方案(在将值x,y,宽度,高度从像素转换为世界单位之后):
float angle = rotation * MathUtils.degreesToRadians;
bodyDef.angle = -angle;
Vector2 correctionPosition = new Vector2(
height * MathUtils.cosDeg(-rotation - 90),
height + height * MathUtils.sinDeg(-rotation - 90));
bodyDef.position.set(x, y).add(correctionPosition);
和
float angle = rotation * MathUtils.degreesToRadians;
bodyDef.angle = -angle;
// Top left corner of object
Vector2 correctedPosition = new Vector2(x, y + height);
// half of diagonal for rectangular object
float radius = (float)Math.sqrt(width * width + height * height) / 2.0f;
// Angle at diagonal of rectangular object
float theta = (float)Math.tanh(height / width) * MathUtils.degreesToRadians;
// Finding new position if rotation was with respect to top-left corner of object.
// X=x+radius*cos(theta-angle)+(h/2)cos(90+angle)
// Y=y+radius*sin(theta-angle)-(h/2)sin(90+angle)
correctedPosition = correctedPosition
.add(
radius * MathUtils.cos(theta - angle),
radius * MathUtils.sin(theta - angle))
.add(
((height / 2) * MathUtils.cos(MathUtils.PI2 + angle)),
(-(height / 2) * MathUtils.sin(MathUtils.PI2 + angle)));
bodyDef.position.set(correctedPosition);
任何暗示都会受到高度欢迎。
答案 0 :(得分:0)
找到正确的解决方案,失去了我生命中的大约1天:)
上述链接中的信息不正确和/或过时。目前Tiled根据其类型保存对象位置。对于图像相对于左下角位置。
Box2d实际上没有“原点”,但你可以考虑它的中心,附着在身体上的灯具的形状应相对于(0,0)定位。
第1步:阅读平铺属性
float rotation = textureMapObject.getRotation();
float x = textureMapObject.getX();
float y = textureMapObject.getY();
float width = textureMapObject.getProperties()
.get("width", Float.class).floatValue();
float height = textureMapObject.getProperties()
.get("height", Float.class).floatValue();
步骤2:根据您的box2d世界大小缩放这些内容,例如x = x * 1/25;等
步骤3:创建一个没有任何位置或角度的主体。
步骤4:用以下方法转换身体位置和角度:
private void applyTiledLocationToBody(Body body,
float x, float y,
float width, float height,
float rotation) {
// set body position taking into consideration the center position
body.setTransform(x + width / 2, y + height / 2, 0);
// bottom left position in local coordinates
Vector2 localPosition = new Vector2(-width / 2, -height / 2);
// save world position before rotation
Vector2 positionBefore = body.getWorldPoint(localPosition).cpy();
// calculate angle in radians
float angle = -rotation * MathUtils.degreesToRadians;
// set new angle
body.setTransform(body.getPosition(), angle);
// save world position after rotation
Vector2 positionAfter = body.getWorldPoint(localPosition).cpy();
// adjust position with the difference (before - after)
// so that the bottom left position remains unchanged
Vector2 newPosition = body.getPosition()
.add(positionBefore)
.sub(positionAfter);
body.setTransform(newPosition, angle);
}
希望它有所帮助。