我正在尝试设计我自己的俄罗斯方块克隆,但是在形状旋转方面遇到了一些问题。我有一个二维数组,表示一个10 x 20的游戏网格和各个形状对象,初始化时包含网格上的位置坐标,形状将从中开始下降。因此,例如,当用户向下移动形状时,每个坐标的y值都会递减,并且此更改会反映在网格上。
我似乎无法弄清楚是使用此实现处理形状旋转的有效方法。有没有办法在指定的枢轴周围使用矩阵这些坐标?
任何建议都将不胜感激,
谢谢。
答案 0 :(得分:5)
当然,请查看“仿射变换”。但是在你的情况下,你得到的是一个物体在离散角度中的四个可能的旋转 - 没有70.3°旋转,它只是0°,90°,180°,270°。那么为什么不预先计算?
答案 1 :(得分:4)
如果经典旋转矩阵有效,将取决于您要使用的rotation system。我将以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
)并在旋转后将它们移回(称为{{ 1}}下面):
sa
通常你会有x_new = sa_x + (y_old - sb_x)
y_new = sa_y - (x_old - sb_y)
,但对于俄罗斯方块块,枢轴点有时位于两个单元格之间的网格上(对于I块和O块),有时位于单元格的中心(对于所有其他单元格)块)。
事实证明
sb = sa
其中sa_x = 0
sb_x = 0
sa_y = 1
sb_y = me - 2
是要旋转的块的最大范围(即2,3或4),适用于所有块。总而言之,你得到:
me
顺时针旋转类似,但如果缓存所有块方向的坐标,则只需要一个方向。
对于其他旋转系统,移位变量的其他值可能有效,但您可能需要再次移动该块,具体取决于块的当前方向(比较{I}的SRS rotation到DTET rotation -block,看看我的意思。)
答案 2 :(得分:1)
这是经典的线性代数。你正在寻找一个旋转矩阵,除了你所有的角度都是直角,所以你可以预先计算正弦和余弦。
要围绕一个点进行操作,您必须先减去中心值(使该参考点成为中心原点)然后应用矩阵,然后再添加原始中心位置。
答案 3 :(得分:0)
我认为你现在已经完成了这个。 我不是程序员,但我记得这是一个Uni。我们每件只有4个不同的物体(不同的旋转)。例如,“L”形状具有片1,2,3,4。如果您的活动件在3中并且顺时针旋转则加载件4,再次顺时针旋转并装载件1.
答案 4 :(得分:0)
我自己遇到过这个问题,我找到了关于这个主题的精彩维基百科页面(在“共同轮换”段落中: 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 "=== === === === === === === === === "