2009-09-22 114 views
4

我試圖設計我自己的俄羅斯方塊克隆,但遇到了形狀旋轉的小問題。我有一個2維數組,代表10 x 20的遊戲網格和單個形狀對象,當初始化時它們包含形狀將從哪裏開始落下的座標。因此,例如,當用戶將形狀向下移動時,每個座標的y值將遞減,並且此更改將反映在網格上。圍繞樞軸旋轉座標? (俄羅斯方塊)

我似乎無法弄清楚是使用此實現來處理形狀旋轉的有效方法。有沒有什麼辦法可以使用矩陣這些座標圍繞指定的樞軸?

任何意見將不勝感激,

謝謝。

回答

5

當然,查一下「仿射變換」。但在你的情況下,你得到的是一個物體的四個可能的旋轉角度 - 沒有70.3 °的旋轉,它只是0,90 °,180 °,270 °。那麼爲什麼不預先計算?

+3

此外,任何「適當的」旋轉將有麻煩定位於適當的網格邊界的塊。對於一套典型的俄羅斯方塊作品,我只需要對每個作品的4個旋轉進行硬編碼。 – Kylotan 2009-09-22 09:51:46

+0

或者,如果你必須在程序上做到這一點,你可以通過簡單的互換和否定x上直角旋轉,y座標 - 做出來的紙,你會看到它很容易。 – Crashworks 2009-09-23 00:32:09

+0

另外照顧有關旋轉存在的,而部分是在板的邊緣。在某些情況下,您將不得不將該部分移回桌子。 +1用於硬編碼,以及算法。 – Flavius 2011-07-14 21:52:49

1

這是經典的線性代數。你正在尋找一個旋轉矩陣,除了你所有的角度都是直角,所以你可以預先計算正弦和餘弦。

Wikipedia: Rotation matrix

要做到這點周圍,你必須先減去中心值(即製作基準點的中心原點)然後應用矩陣,並添加原來的中心位置回來。

4

如果經典旋轉矩陣工作,將取決於您要使用的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,看看我意思)。

0

我假設你已經通過,現在完成了這個。 我不是一個程序員,但我記得這樣一個統一。我們每個作品只有4個不同的對象(不同的旋轉)。例如「L」形狀有1,2,3,4。如果您在3活躍一塊木頭,你順時針方向旋轉,然後裝入一塊4,再次旋轉,順時針和負載一塊1

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 "=== === === === === === === === === "