Nochmal Tetris: "Steinchen umdrehen"
lima-city → Forum → Programmiersprachen → Java
all
block
blocken
code
drehen
erstellen
feld
formel
methode
mittelpunkt
null
objekt
papier
position
problem
radius
speichern
stein
url
winkel
-
Hallo!
Mein Tetris-Projekt schreitet voran, eine erste Version für den PC funktioniert schon ziemlich gut. Allerdings gibt es ein Problem: Ich kann die Steine nicht drehen.
Realisiert habe ich das ganze im Wesentlichen durch drei Klassen: Eine Hauptklasse, die alle Steine verwaltet, eine Stein-Klasse für die großen Steine(ganze T, I, L-s), die ja wiederum aus einzelnen Blöcken bestehen, diese haben auch eine Klasse. Die Blöcke speichern relative Koordinaten zu ihrem Stein.
Nun sitze ich an der Methode für die Klasse Stein, die die Blöcke um die jeweilige Instanz drehen soll. Dabei kann ich die relativen Koordinaten einfach per getter/setter lesen bzw. ändern, das Problem lässt sich also programmiertechnisch einfach lösen. Allerdings fehlt mir gerade ein bisschen die Mathematik.
Meine erste Überlegung auf dem Papier war nach einem bisschen herumkritzeln folgendes:
Was aber nicht für alle Fällte klappt, ich habe es schließlich wieder verworfen.
Also dachte ich mir, ich gehe das mit mehr System an. Anhand von komplexen Zahlen habe ich mir überlegt, wie die Drehung aussieht. Also habe ich in der Methode zuerst einmal Radius und Winkel berechnet, um dann dem Winkel 90° drauf zu rechnen (pi/2). Danach wollte ich aus Winkel und Radius wieder an X und Y kommen.
Problem: Wenn X oder Y null sind, funktioniert es nicht den Winkel mittels Tangens zu berechnen, da er entweder unendlich ist oder man zuerst durch null teilen muss.
Habt ihr eine Idee, wie man das noch umsetzen könnte? Ich möchte möglichst einen Algorithmus benutzen. Mit vielen Ausnahmen schaffe ich das auch so, dann bin ich aber nicht mit meinem Code zufrieden !
mfg
Jonas -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hmmm ne doofe Frage :D warum verschiebst du nicht einfach die Blöcke?
du musst das ding ja im wesentlich nicht drehen, du kannst ja auch einfach die blöcke bewegen.
Also so zu sagen die dreh bewegung simulieren.
Du könntest aber auch ganz simple die blöcke sozusagen speichern :D
also in den verschiedenen dreh richtungen.
So hat es glaube ich auch nintendo gemacht.
Hier habe ich dir auch das mal als Link rausgesucht:
http://tetris.wikia.com/wiki/SRS?file=SRS-pieces.png
zu not steinchen recht untenin der ecke kommt nach links unten.
Usw und so fort.
So würde ich es machen.
Die rotierung würde auch im Grid so besser funktionieren :)
Ich zeichne dir kurz mal was.
https://www.draw.io/#Ltetris.xml
Daraus lässt sich dann auch ne formel erstellen.
Beitrag zuletzt geändert: 8.9.2015 12:59:59 von willstdueswissen -
So etwas wie das mit dem Speichern bekomme ich auch selbst hin. Ich möchte ja auch nicht wirklich drehen, sondern einfach die Blöcke innerhalb des Steines eben zur nächsten Position weiterbewegen. Was ich suche ist eine elegante Lösung, mit der man das umsetzen kann und nicht ein if-Konstrukt, dass für jeden Block die neue Position kennt.
Zum besseren Verständnis: Ich bin quasi an dieser Stelle:
public class Stone { private ArrayList<Block> blocks; // Hier kommen die Blöcke rein //... public void rotateRight() { for(int i=0; i<blocks.size(); i++) { // Für alle Blöcke durchführen int x = blocks.get(i).getRelX(); int y = blocks.get(i).getRelY(); // --> Setzen mit blocks.get(i).setRelX() bzw. .setRelY() } } //... }
mfg
Jonas
Beitrag zuletzt geändert: 8.9.2015 12:42:21 von jonas-bayer -
Du brauchst für Blöcke überhaupt keine Objekte, denn all das lässt sich als einfaches
-Array darstellen. Den gesamten Stein würde ich als Objekt machen, der dieses Array beinhaltet.boolean
Eine Rotation kannst du dann machen, indem du die boolean-Werte um den Mittelpunkt »drehst«. Das ist am einfachsten, wenn du das fix als Programmtext schreibst, also ca so:// boolean[][] block = new boolean[4][4]; /* bereits befüllter Block */ boolean[][] rotated = new boolean[4][4]; rotated[0][0] = block[0][3]; rotated[1][0] = block[0][2]; …
Natürlich wird es noch einfacher, wenn du das für 3x3 und 4x4 getrennt hast, dann sparst du dir all die Ausrichtungsunnötigkeiten, die sonst noch so existieren (wegen dem Mittelpunkt).
Wie du auf das kommst? Nimm dir ein kariertes Papier, markiere ein 3x3 bzw 4x4-Feld und schreib in jedes Kästchen die x/y-Koordinate. Dann drehst du das Papier und siehst, was wohin gehört.
Wenn du dir dann überlegst, wie du das »eleganter« schreiben kannst wirst du feststellen: das ist mit einigen Gedanken verbunden die sich gar nicht auszahlen, und Laufzeitmäßig ist es so wohl auch am schnellsten.
Beitrag zuletzt geändert: 8.9.2015 12:48:56 von hackyourlife -
In meinem ersten Beitrag habe ich dir auch dazu jetzt die Grafik hinterlegt.
Dort habe ich dir die beiden Felder (3*3; 4*4) dargestellt.
Du könntest eine Formel dafür erstellen, aber Root hat dar wahrscheinlich (ne nicht wahrscheinlich) recht!
Es ist einfacher eine Programmier Logik zu bauen als eine Mathematische Formel.
Sieh dir einfach meine Zeichnung an und du verstehst was ich oder eher der root meint. :)
happy coding
willstdueswissen -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage