4

我正在尝试设计我自己的俄罗斯方块克隆,但在形状旋转方面遇到了一点问题。我有一个表示 10 x 20 游戏网格和单个形状对象的二维数组,这些对象在初始化时包含网格上形状将从哪里开始下降的坐标。例如,当用户将形状向下移动时,每个坐标的 y 值都会递减,并且这种变化会反映在网格上。

我似乎无法弄清楚使用此实现处理形状旋转的有效方法。有什么办法可以在指定的枢轴周围使用这些坐标的矩阵?

任何建议将不胜感激,

谢谢你。

4

5 回答 5

6

如果经典旋转矩阵有效,将取决于您要使用的旋转系统。我将以SRS为例。

绕原点逆时针旋转的旋转矩阵为:

[0 -1]
[1  0]

现在,假设您有一个坐标列表 [(0, 1), (1, 1), (2, 1), (3, 1)] 表示 I 块在其初始位置:

 0123
0....
1####
2....
3....

请注意,我不使用笛卡尔坐标系,而是使用通常的屏幕坐标,从左上角开始。要正确旋转块,您首先必须考虑 y 轴的翻转。然后旋转矩阵变为:

[ 0 1]  ->  x_new = y_old
[-1 0]  ->  y_new = -x_old

接下来,要围绕枢轴点旋转,在旋转之前,您必须移动坐标,使枢轴点成为原点(sb如下所示)并在旋转后将它们移回(sa如下所示):

x_new = sa_x + (y_old - sb_x)
y_new = sa_y - (x_old - sb_y)

通常你会有sb = sa,但是对于俄罗斯方块块,枢轴点有时位于两个单元格之间的网格上(对于 I 和 O 块),有时在单元格的中心(对于所有其他块)。

事实证明

sa_x = 0
sb_x = 0
sa_y = 1
sb_y = me - 2

其中me是要旋转的块的最大范围(即 2、3 或 4),适用于所有块。所以总结一下,你得到:

x_new = y_old
y_new = 1 - (x_old - (me - 2))

顺时针旋转是类似的,但如果你缓存所有块方向的坐标,你只需要一个方向。

对于其他旋转系统,移位变量的其他值可能会起作用,但您可能必须再次移动工件,具体取决于块的当前方向(将SRS 旋转与I 块的DTET 旋转进行比较,以了解我的意思) .

于 2010-01-03T22:04:12.850 回答
5

当然,查找“仿射变换”。但是在您的情况下,您所得到的正是一个物体以离散角度的四种可能旋转——没有 70.3° 旋转,它只有 0、90°、180°、270°。那么为什么不预先计算呢?

于 2009-09-22T00:49:31.177 回答
1

这是经典的线性代数。你正在寻找一个旋转矩阵,除了你所有的角度都是直角,所以你可以预先计算正弦和余弦。

维基百科:旋转矩阵

要围绕一个点执行此操作,您必须先减去中心值(使该参考点成为中心原点)然后应用矩阵,然后将原始中心位置加回去。

于 2009-09-22T01:33:40.437 回答
1

我自己也遇到过这个问题,我找到了关于这个主题的很棒的维基百科页面(在“通用轮换”段落中:
https ://en.wikipedia.org/wiki/Rotation_matrix#Ambiguities

然后我写了下面的代码,超级冗长,以便清楚地了解发生了什么。

我希望它有助于更​​好地理解它是如何工作的。

要快速测试它,您可以在此处复制/粘贴:http:
//www.codeskulptor.org/

triangle = [[0,0],[5,0],[5,2]]
coordinates_a = triangle[0]
coordinates_b = triangle[1]
coordinates_c = triangle[2]

def rotate90ccw(coordinates):
    print "Start coordinates:"
    print coordinates
    old_x = coordinates[0]
    old_y = coordinates[1]
# Here we apply the matrix coming from Wikipedia
# for 90 ccw it looks like:
# 0,-1
# 1,0
# What does this mean?
#
# Basically this is how the calculation of the new_x and new_y is happening:
# new_x = (0)(old_x)+(-1)(old_y)
# new_y = (1)(old_x)+(0)(old_y)
#
# If you check the lonely numbers between parenthesis the Wikipedia matrix's numbers finally start making sense.
# All the rest is standard formula, the same behaviour will apply to other rotations
    new_x = -old_y
    new_y = old_x
    print "End coordinates:"
    print [new_x, new_y]

def rotate180ccw(coordinates):
    print "Start coordinates:"
    print coordinates
    old_x = coordinates[0]
    old_y = coordinates[1] 
    new_x = -old_x
    new_y = -old_y
    print "End coordinates:"
    print [new_x, new_y]

def rotate270ccw(coordinates):
    print "Start coordinates:"
    print coordinates
    old_x = coordinates[0]
    old_y = coordinates[1]  
    new_x = -old_x
    new_y = -old_y
    print "End coordinates:"
    print [new_x, new_y]

print "Let's rotate point A 90 degrees ccw:"
rotate90ccw(coordinates_a)
print "Let's rotate point B 90 degrees ccw:"
rotate90ccw(coordinates_b)
print "Let's rotate point C 90 degrees ccw:"
rotate90ccw(coordinates_c)
print "=== === === === === === === === === "
print "Let's rotate point A 180 degrees ccw:"
rotate180ccw(coordinates_a)
print "Let's rotate point B 180 degrees ccw:"
rotate180ccw(coordinates_b)
print "Let's rotate point C 180 degrees ccw:"
rotate180ccw(coordinates_c)
print "=== === === === === === === === === "
print "Let's rotate point A 270 degrees ccw:"
rotate270ccw(coordinates_a)
print "Let's rotate point B 270 degrees ccw:"
rotate270ccw(coordinates_b)
print "Let's rotate point C 270 degrees ccw:"
rotate270ccw(coordinates_c)
print "=== === === === === === === === === "
于 2017-03-14T15:04:51.063 回答
0

我假设你现在已经完成了。我不是程序员,但我确实记得在大学里做过这个。每件作品只有 4 个不同的对象(具有不同的旋转)。例如,“L”形有 1、2、3、4 块。如果您在 3 中的活动部件并且您顺时针旋转,那么您加载部件 4,再次顺时针旋转并加载部件 1。

于 2010-02-05T00:48:59.253 回答