表示和旋转俄罗斯方块游戏棋子的最佳算法(和解释)是什么?我总是发现片段轮换和表示方案令人困惑。
大多数俄罗斯方块游戏似乎在每次旋转时都使用天真的“重新制作块数组”:
http://www.codeplex.com/Project/ProjectDirectory.aspx?ProjectSearchText=俄罗斯方块 http://www.codeplex.com/Project/ProjectDirectory.aspx?ProjectSearchText=tetris
然而,有些使用预先构建的编码数字和位移来表示每个部分:
http://www.codeplex.com/wintris http://www.codeplex.com/wintris
有没有一种方法可以使用数学来做到这一点(不确定这是否适用于基于单元的电路板)?
当我试图弄清楚旋转如何适用于我的俄罗斯方块游戏时,这是我在堆栈溢出上发现的第一个问题。尽管这个问题很老了,但我认为我的输入将帮助其他人尝试通过算法解决这个问题。首先,我不同意对每个部分进行硬编码和旋转会更容易。 Gamecat的答案是正确的,但我想详细说明一下。以下是我在 Java 中解决旋转问题的步骤。
对于每个形状,确定其原点在哪里。我使用了图中的点这一页 http://tetris.wikia.com/wiki/SRS分配我的原点。请记住,根据您的实现,您可能必须在用户每次移动该块时修改原点。
旋转假设原点位于点 (0,0),因此您必须先平移每个块,然后才能旋转它。例如,假设您的原点当前位于点 (4, 5)。这意味着在旋转形状之前,每个块必须在 x 坐标中平移 -4,在 y 坐标中平移 -5,以相对于 (0,0)。
在Java中,典型的坐标平面从左上角的点(0,0)开始,然后向右和向下增加。为了在我的实现中补偿这一点,我在旋转之前将每个点乘以 -1。
-
以下是我用来计算逆时针旋转后新的 x 和 y 坐标的公式。有关这方面的更多信息,我会查看维基百科页面旋转矩阵 http://en.wikipedia.org/wiki/Rotation_matrix。 x' 和 y' 是新坐标:
x' = x * cos(PI/2) - y * sin(PI/2) 且 y' = x * sin(PI/2) + y * cos(PI/2)
。
对于最后一步,我只是以相反的顺序执行步骤 2 和 3。所以我再次将结果乘以-1,然后将块转换回原来的坐标。
以下是对我有用的代码(Java),以了解如何用您的语言执行此操作:
public synchronized void rotateLeft(){
Point[] rotatedCoordinates = new Point[MAX_COORDINATES];
for(int i = 0; i < MAX_COORDINATES; i++){
// Translates current coordinate to be relative to (0,0)
Point translationCoordinate = new Point(coordinates[i].x - origin.x, coordinates[i].y - origin.y);
// Java coordinates start at 0 and increase as a point moves down, so
// multiply by -1 to reverse
translationCoordinate.y *= -1;
// Clone coordinates, so I can use translation coordinates
// in upcoming calculation
rotatedCoordinates[i] = (Point)translationCoordinate.clone();
// May need to round results after rotation
rotatedCoordinates[i].x = (int)Math.round(translationCoordinate.x * Math.cos(Math.PI/2) - translationCoordinate.y * Math.sin(Math.PI/2));
rotatedCoordinates[i].y = (int)Math.round(translationCoordinate.x * Math.sin(Math.PI/2) + translationCoordinate.y * Math.cos(Math.PI/2));
// Multiply y-coordinate by -1 again
rotatedCoordinates[i].y *= -1;
// Translate to get new coordinates relative to
// original origin
rotatedCoordinates[i].x += origin.x;
rotatedCoordinates[i].y += origin.y;
// Erase the old coordinates by making them black
matrix.fillCell(coordinates[i].x, coordinates[i].y, Color.black);
}
// Set new coordinates to be drawn on screen
setCoordinates(rotatedCoordinates.clone());
}
此方法是将形状向左旋转所需的全部方法,结果比为每个形状定义每次旋转要小得多(取决于您的语言)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)