我试图设计我自己的俄罗斯方块克隆,但遇到了形状旋转的小问题。我有一个2维数组,代表10 x 20的游戏网格和单个形状对象,当初始化时它们包含形状将从哪里开始落下的坐标。因此,例如,当用户将形状向下移动时,每个坐标的y值将递减,并且此更改将反映在网格上。围绕枢轴旋转坐标? (俄罗斯方块)
我似乎无法弄清楚是使用此实现来处理形状旋转的有效方法。有没有什么办法可以使用矩阵这些坐标围绕指定的枢轴?
任何意见将不胜感激,
谢谢。
我试图设计我自己的俄罗斯方块克隆,但遇到了形状旋转的小问题。我有一个2维数组,代表10 x 20的游戏网格和单个形状对象,当初始化时它们包含形状将从哪里开始落下的坐标。因此,例如,当用户将形状向下移动时,每个坐标的y值将递减,并且此更改将反映在网格上。围绕枢轴旋转坐标? (俄罗斯方块)
我似乎无法弄清楚是使用此实现来处理形状旋转的有效方法。有没有什么办法可以使用矩阵这些坐标围绕指定的枢轴?
任何意见将不胜感激,
谢谢。
当然,查一下“仿射变换”。但在你的情况下,你得到的是一个物体的四个可能的旋转角度 - 没有70.3 °的旋转,它只是0,90 °,180 °,270 °。那么为什么不预先计算?
这是经典的线性代数。你正在寻找一个旋转矩阵,除了你所有的角度都是直角,所以你可以预先计算正弦和余弦。
要做到这点周围,你必须先减去中心值(即制作基准点的中心原点)然后应用矩阵,并添加原来的中心位置回来。
如果经典旋转矩阵工作,将取决于您要使用的rotation system。我将以SRS为例。
为原点周围的逆时针旋转的旋转矩阵:
[0 -1]
[1 0]
现在,假设你有坐标[(0,1),(1,1),(2,1名单),(3,1)],表示在其初始位置的I块:
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 rotation给我块的DTET rotation,看看我意思)。
我假设你已经通过,现在完成了这个。 我不是一个程序员,但我记得这样一个统一。我们每个作品只有4个不同的对象(不同的旋转)。例如“L”形状有1,2,3,4。如果您在3活跃一块木头,你顺时针方向旋转,然后装入一块4,再次旋转,顺时针和负载一块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 "=== === === === === === === === === "
此外,任何“适当的”旋转将有麻烦定位于适当的网格边界的块。对于一套典型的俄罗斯方块作品,我只需要对每个作品的4个旋转进行硬编码。 – Kylotan 2009-09-22 09:51:46
或者,如果你必须在程序上做到这一点,你可以通过简单的互换和否定x上直角旋转,y坐标 - 做出来的纸,你会看到它很容易。 – Crashworks 2009-09-23 00:32:09
另外照顾有关旋转存在的,而部分是在板的边缘。在某些情况下,您将不得不将该部分移回桌子。 +1用于硬编码,以及算法。 – Flavius 2011-07-14 21:52:49