2009-03-14 4 views
17

Ich programmiere einen Tetris Klon und in meinem Spiel speichere ich meine Tetromino Blöcke als 4x4 Blöcke. Ich muss nun in der Lage sein, die Integer-Positionen in den Arrays so zu rotieren, dass ich einen gedrehten Tetris-Block bekomme. Ich kann die Textur nicht einfach rotieren, weil alle meine Kollisionserkennung usw. so entworfen wurde, dass sie mit dem 2D-Array funktioniert. Das Spiel wird mit XNA in C# geschrieben.Wie man ein 2D Array von ganzen Zahlen dreht

Wie kann ich mein 2D-Array von Ints um 90 Grad im Uhrzeigersinn/gegen den Uhrzeigersinn drehen.

Hier ist mein 'L' Block als Beispiel gespeichert.

0 1 0 0 
0 1 0 0 
0 1 1 0 
0 0 0 0 

Vielen Dank für Ihre Hilfe.

+0

C# und C++? –

Antwort

29

Wenn es sich um ein 2D-Array handelt, können Sie die Rotation implementieren, indem Sie mit verschiedenen Array-Zugriffsreihenfolgen kopieren.

das heißt, für eine Drehung im Uhrzeigersinn, versuchen:

int [,] newArray = new int[4,4]; 

for (int i=3;i>=0;--i) 
{ 
    for (int j=0;j<4;++j) 
    { 
     newArray[j,3-i] = array[i,j]; 
    } 
} 

gegen den Uhrzeigersinn ähnlich ist.

+0

Gute Lösung, aber Overkill angesichts der Problemdomäne. –

+0

Testen Sie diesen Code jetzt ... –

+0

Ich stimme dies, es sollte als die Lösung markiert werden. Nicht sicher, was du meinst rde6173, es sei denn, du verbürgst dich auch dafür, 4 Orientierungsarrays zu speichern. – Ricket

4

Wenn Sie eine 4 x 4-Block drehen möchten, bewegen Sie sich nur die Positionen:

A B C A 
C D D B 
B D D C 
A C B A 

Jeder A bewegt sich zur nächsten A, und das gleiche gilt für B, C und D.

/-----\ 
    |  | 
    |  V 
    A B C A 
/->C D>D B--\ 
| B D D C | 
| A C B A | 
| |^ | 
| | | | 
\----/ \----/  
+0

Ich denke, dein Bild ist ein wenig aus, Ich bin mir nicht sicher, was genau du damit klären willst, und die Pfeile scheinen eher auf b -> c und a -> c zu zeigen, als deine Anweisungen zu unterstützen. fmsf, erwachsen werden. – Ricket

+0

@Ricket danke, korrigiert es. –

6

In klassischen Tetris gibt es sehr wenige Permutationen von Objekten. Ich würde einfach ein konstantes Array für jedes "Tetromino" an jeder der 4 Positionen und eine einfache Logik haben, um das geeignete basierend auf der Eingabe zu wählen.

Warum verschwenden CPU-Zyklen versuchen, es zu drehen?

+0

Die Mathematik ist in diesem Fall so einfach, sie ist wahrscheinlich genauso schnell zu rotieren wie die Permutationssuche basierend auf dem aktuellen Blockstil + Position. –

+0

Das ist lächerlich. –

+0

Ich würde auch hinzufügen, dass es vom Gameplay- und Design-Standpunkt aus besser wäre, voreingestellte Drehungen zu haben. Was machst du, wenn du das lange 4x1 Stück bekommst? Wenn Sie es zweimal drehen, sollte es wirklich ein voller Raum zur Seite sein (was wäre es, wenn Sie reine Mathematik verwenden würden)? –

11

Die Teile nicht mit Code drehen. Speichern Sie einfach ein Array der verschiedenen Teilorientierungen und durchlaufen Sie sie, wenn das Teil gedreht wird. Sie müssen sie in einem Tetris-Spiel nicht dynamisch drehen.

Da die Problemdomäne Tetris ist, werden Sie feststellen, dass ein Rotationsalgorithmus unerwünschte Effekte verursacht, wie z. B. das lange dünne Tetronimo, das nicht zwischen zwei Positionen wechselt (wie in der realen Sache).

+0

-1; Es gibt keinen Vorteil, 4 Orientierungen jedes Stückes zu speichern, anstatt nur zu rotieren. Sie sollten sich darauf konzentrieren, seine Frage zu beantworten, ihn nicht zu entmutigen, es sei denn, er macht einen kritischen Fehler; was er sicherlich nicht ist. – Ricket

+0

Es würde viel weniger Zeit brauchen, um eine doppelte for-Schleife zu schreiben, wie oben vorgeschlagen. –

+4

Ricket, einfach auf den Ton dort. Ich habe meine Antwort aktualisiert, um anzuzeigen, warum Rotation in diesem Fall eine schlechte Idee ist. – Jon

1

Ich würde (x, y) Koordinaten der "Zellen" speichern und Rotationsmatrix verwenden, um sie zu drehen. Siehe zum Beispiel Drawing a Rotated Rectangle. Sie müssen das Ergebnis wahrscheinlich auf das nächste 0,5-Inkrement runden.

0

js Code für beide im Uhrzeigersinn und gegen den Uhrzeigersinn:

function arrRotation90(arr, clockwise) { 
      var arr_rotated = []; 
      for (var i = 0; i < arr[0].length; i++) { 
       arr_rotated[i] = []; 
      } 
      if (clockwise) { 
       for (var i = 0; i < arr.length; i++) { 
        for (var j = 0; j < arr[i].length; j++) { 
         arr_rotated[arr[i].length-1-j][i] = arr[i][j]; 
        } 
       } 
      } else { 
       for (var i = 0; i < arr.length; i++) { 
        for (var j = 0; j < arr[i].length; j++) { 
         arr_rotated[j][arr.length - 1 - i] = arr[i][j]; 
        } 
       } 
      } 
      return arr_rotated; 
     }