旋转坐标(Java 和几何)
Rotating Coordinates (Java and Geometry)
我正在使用 AWT canvas 作为基础开发 2D java 游戏引擎。这个游戏引擎的一部分是它需要有碰撞箱。不仅仅是内置的矩形(已经尝试过那个系统),我还需要我自己的 Hitbox class 因为我需要更多的功能。所以我做了一个,支持圆形和 4 边形的多边形碰撞盒。 hitboxclass的设置方式是用4个坐标点作为4个角顶点连接起来形成一个矩形。绘制连接点的线,这些线用于检测与其他碰撞盒的交点。但是我现在有一个问题:旋转。
box hitbox有两种可能,可以是4个坐标点,也可以是4个坐标点附加到一个gameobject上。不同之处在于前者只是基于 0,0 作为序数的 4 个坐标,而附加到游戏对象的坐标存储坐标中的偏移量而不是原始位置数据,因此 (-100,-100) 例如表示主机的位置游戏对象,但向左 100 像素,向上 100 像素。
在网上找到了绕原点旋转点的公式。由于基于 Gameobject 的碰撞盒以特定点为中心,我认为这将是尝试它的最佳选择。此代码运行每个刻度以更新玩家角色的命中框
//creates a rectangle hitbox around this gameobject
int width = getWidth();
int height = getHeight();
Coordinate[] verts = new Coordinate[4]; //corners of hitbox. topLeft, topRight, bottomLeft, bottomRight
verts[0] = new Coordinate(-width / 2, -height / 2);
verts[1] = new Coordinate(width / 2, -height / 2);
verts[2] = new Coordinate(-width / 2, height / 2);
verts[3] = new Coordinate(width / 2, height / 2);
//now go through each coordinate and adjust it for rotation
for(Coordinate c : verts){
if(!name.startsWith("Player"))return; //this is here so only the player character is tested
double theta = Math.toRadians(rotation);
c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
}
getHitbox().vertices = verts;
对于视频质量不佳,我深表歉意,但这是上面的结果:https://www.youtube.com/watch?v=dF5k-Yb4hvE
所有相关的 class 都可以在这里找到:https://github.com/joey101937/2DTemplate/tree/master/src/Framework
编辑:期望的效果是框轮廓跟随字符成一圈,同时保持纵横比,如下所示:https://www.youtube.com/watch?v=HlvXQrfazhA。目前系统使用的是上面的代码,效果见上一个视频link。 我应该如何修改四个 2D 坐标以在围绕一个点的整个旋转过程中保持相对纵横比?
当前轮换系统如下:
- x = x*Cos(theta) - y *Sin(theta)
- y = x*Sin(theta) + y *Cos(theta)
其中 theta 是 raidians 中的旋转度数
你犯了经典错误:
c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
在第二行中,您使用 修改后的 值 c.x
。记住 tempx = c.x
在计算之前使用它。
tempx = c.x;
c.x = (int)(tempx*Math.cos(theta)-c.y*Math.sin(theta));
c.y = (int)(tempx*Math.sin(theta)+c.y*Math.cos(theta));
另一个问题:四舍五入 每次旋转后的坐标会在某些旋转后导致扭曲和收缩。明智的做法是将坐标存储在浮点数中并将它们四舍五入仅用于输出,或者记住起始值并按累积角度对它们应用旋转。
我正在使用 AWT canvas 作为基础开发 2D java 游戏引擎。这个游戏引擎的一部分是它需要有碰撞箱。不仅仅是内置的矩形(已经尝试过那个系统),我还需要我自己的 Hitbox class 因为我需要更多的功能。所以我做了一个,支持圆形和 4 边形的多边形碰撞盒。 hitboxclass的设置方式是用4个坐标点作为4个角顶点连接起来形成一个矩形。绘制连接点的线,这些线用于检测与其他碰撞盒的交点。但是我现在有一个问题:旋转。
box hitbox有两种可能,可以是4个坐标点,也可以是4个坐标点附加到一个gameobject上。不同之处在于前者只是基于 0,0 作为序数的 4 个坐标,而附加到游戏对象的坐标存储坐标中的偏移量而不是原始位置数据,因此 (-100,-100) 例如表示主机的位置游戏对象,但向左 100 像素,向上 100 像素。
在网上找到了绕原点旋转点的公式。由于基于 Gameobject 的碰撞盒以特定点为中心,我认为这将是尝试它的最佳选择。此代码运行每个刻度以更新玩家角色的命中框
//creates a rectangle hitbox around this gameobject
int width = getWidth();
int height = getHeight();
Coordinate[] verts = new Coordinate[4]; //corners of hitbox. topLeft, topRight, bottomLeft, bottomRight
verts[0] = new Coordinate(-width / 2, -height / 2);
verts[1] = new Coordinate(width / 2, -height / 2);
verts[2] = new Coordinate(-width / 2, height / 2);
verts[3] = new Coordinate(width / 2, height / 2);
//now go through each coordinate and adjust it for rotation
for(Coordinate c : verts){
if(!name.startsWith("Player"))return; //this is here so only the player character is tested
double theta = Math.toRadians(rotation);
c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
}
getHitbox().vertices = verts;
对于视频质量不佳,我深表歉意,但这是上面的结果:https://www.youtube.com/watch?v=dF5k-Yb4hvE
所有相关的 class 都可以在这里找到:https://github.com/joey101937/2DTemplate/tree/master/src/Framework
编辑:期望的效果是框轮廓跟随字符成一圈,同时保持纵横比,如下所示:https://www.youtube.com/watch?v=HlvXQrfazhA。目前系统使用的是上面的代码,效果见上一个视频link。 我应该如何修改四个 2D 坐标以在围绕一个点的整个旋转过程中保持相对纵横比?
当前轮换系统如下:
- x = x*Cos(theta) - y *Sin(theta)
- y = x*Sin(theta) + y *Cos(theta)
其中 theta 是 raidians 中的旋转度数
你犯了经典错误:
c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
在第二行中,您使用 修改后的 值 c.x
。记住 tempx = c.x
在计算之前使用它。
tempx = c.x;
c.x = (int)(tempx*Math.cos(theta)-c.y*Math.sin(theta));
c.y = (int)(tempx*Math.sin(theta)+c.y*Math.cos(theta));
另一个问题:四舍五入 每次旋转后的坐标会在某些旋转后导致扭曲和收缩。明智的做法是将坐标存储在浮点数中并将它们四舍五入仅用于输出,或者记住起始值并按累积角度对它们应用旋转。