2009-09-22 9 views
4

J'essaye de concevoir mon propre clone de tetris mais ai rencontré un petit problème avec des rotations de forme. J'ai un tableau bidimensionnel représentant une grille de jeu de 10 x 20 et des objets de forme individuels qui, une fois initialisés, contiennent les coordonnées de l'endroit où la forme commencera à tomber sur la grille. Ainsi, par exemple, lorsque l'utilisateur déplace la forme vers le bas, la valeur y de chaque coordonnée est décrémentée et cette modification est répercutée sur la grille.Rotation cordinates autour du pivot? (tetris)

Ce que je n'arrive pas à comprendre est un moyen efficace de gérer les rotations de forme en utilisant cette implémentation. Est-il possible d'utiliser une matrice de ces coordonnées autour d'un pivot désigné?

Toutes les suggestions seront grandement appréciés,

Merci.

Répondre

5

Bien sûr, recherchez "affine transformer". Mais dans votre cas, ce que vous avez est exactement quatre rotations possibles d'un objet dans des angles discrets - il n'y a pas de rotation, c'est juste 0, 90 °, 180 °, 270 °. Alors pourquoi ne pas précalculer?

+3

En outre, toute rotation « appropriée » aura du mal à localiser les blocs sur les limites de la grille appropriée. Pour un ensemble typique de pièces Tetris, je devrais coder en dur les 4 rotations pour chacune des pièces. – Kylotan

+0

Ou, si vous devez le faire de manière procédurale, vous pouvez obtenir des rotations à angle droit grâce à de simples échanges et négations sur les coordonnées x, y - faites le sur papier et vous verrez que c'est facile. – Crashworks

+0

Faites également attention aux rotations qui se produisent lorsque la pièce est sur le bord de la planche. Dans certaines circonstances, vous devrez replacer la pièce dans la table. +1 pour le codage en dur, ainsi que pour l'algorithme. – Flavius

1

Ceci est l'algèbre linéaire classique. Vous cherchez une matrice de rotation, sauf que tous vos angles sont à angle droit, vous pouvez donc calculer les sinus et les cosinus.

Wikipedia: Rotation matrix

Pour ce faire autour d'un point, vous devez soustraire la valeur centrale premier (faire ce point de référence à l'origine du centre) puis appliquer la matrice, et ajouter la position centrale d'origine en arrière.

4

Si les matrices de rotation classiques fonctionnent, cela dépendra du rotation system que vous souhaitez utiliser. Je vais utiliser SRS comme exemple.

La matrice de rotation pour la rotation dans le sens antihoraire autour de l'origine est:

[0 -1] 
[1 0] 

Maintenant, supposons que vous avez une liste de coordonnées [(0, 1), (1, 1), (2, 1), (3, 1)] représentant la I-bloc dans sa position initiale:


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

Notez que je ne pas utiliser un système de coordonnées cartésiennes, mais les coordonnées d'écran habituels, en commençant en haut à gauche. Pour faire pivoter le bloc correctement, vous devez d'abord prendre en compte le retournement de l'axe y. La matrice de rotation devient alors:

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

Ensuite, pour tourner autour d'un point de pivot, avant de tourner, il faut décaler les coordonnées de sorte que le point de pivot devient l'origine (appelé sb ci-dessous) et les déplacer en arrière après une rotation (appelé sa ci-dessous):

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

Normalement, on aurait sb = sa, mais pour des blocs de tetris le point de pivot est parfois sur la grille entre les deux cellules (pour I et O-blocs) et parfois à la centre d'une cellule (pour tous les autres blocs).

Il se trouve que

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

me est l'étendue maximale (à savoir 2, 3 ou 4) du bloc de rotation, qui fonctionne pour tous les blocs.Donc, pour résumer, vous obtenez:

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

rotation Contraire est similaire, mais si vous mettez en cache les coordonnées pour toutes les orientations pour de bloc, vous aurez seulement besoin d'une direction. Pour d'autres systèmes de rotation, d'autres valeurs des variables de décalage peuvent fonctionner, mais vous devrez peut-être déplacer de nouveau la pièce, en fonction de l'orientation actuelle du bloc (comparez SRS rotation à DTET rotation du bloc I, pour voir ce que je signifier).

0

Je suppose que vous avez terminé cela maintenant. Je ne suis pas programmeur mais je me souviens d'avoir fait un Uni. Nous avons juste eu 4 objets différents (avec des rotations différentes) pour chaque pièce. Par exemple, la forme "L" a la pièce 1,2,3,4. Si votre pièce active en 3 et vous tournez dans le sens des aiguilles d'une montre, vous chargez la pièce 4, tournez à nouveau dans le sens horaire et chargez la pièce 1.

0

J'ai moi-même eu ce problème et j'ai trouvé la bonne page wikipedia sur le sujet (en " rotations commun » paragraphe:
https://en.wikipedia.org/wiki/Rotation_matrix#Ambiguities

Ensuite, je l'ai écrit le code suivant, super bavard afin d'avoir une compréhension claire de ce qui se passe

J'espère qu'il peut être utile pour mieux comprendre comment cela.

Pour le tester rapidement vous peut copier/coller ici:
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 "=== === === === === === === === === "