Tetris Steine rotieren

  • Antworten:24
  • Bentwortet
dwjiidnsw
  • Forum-Beiträge: 58

16.05.2018, 23:36:52 via Website

Hallo,
ich komme bei der Rotation der Tetris Steine nicht weiter. Zwar werden die Steine gedreht, aber sie landen dann immer woanders auf dem Spielfeld, obwohl sie eigentlich immer an der gleichen Stelle bleiben müssten, eben nur gedreht.

Um den Stein zu drehen vertausche ic die x und y Koordinaten vom Stein.

 public void rotiereStein(Stein SpielStein) {
     löscheStein(SpielStein);
      int x1_tmp = SpielStein.x1; int y1_tmp = SpielStein.y1;
      int x2_tmp = SpielStein.x2; int y2_tmp = SpielStein.y2;
      int x3_tmp = SpielStein.x3; int y3_tmp = SpielStein.y3;
      int x4_tmp = SpielStein.x4; int y4_tmp = SpielStein.y4;


        SpielStein.x1 = y1_tmp;
        SpielStein.y1 = x1_tmp;

        SpielStein.x2 = y2_tmp;
        SpielStein.y2 = x2_tmp;

        SpielStein.x3 = y3_tmp;
        SpielStein.y3 = x3_tmp;

        SpielStein.x4 = y4_tmp;
        SpielStein.y4 = x4_tmp;
    }
Kommentieren
Beste Antwort
Jokel
  • Forum-Beiträge: 1.537

20.05.2018, 12:43:40 via Website

Hallo ein Rechteck drehen kannst du in etwas so.

float left = 100f;
float top = 100f;
float right = 150f;
float bottom = 110f;
int px =100;
int py =100;
int wingkel = 90;

RectF r = new RectF(left,top,right,bottom);
Matrix m = new Matrix();

m.setRotate(wingkel, px, py);
m.mapRect(r);

Bei deiner Methode ist es nicht nur gedreht sonderen auch gespiegelt.
Sowie auch im Raum Verschoben.

— geändert am 20.05.2018, 13:02:38

Hilfreich?
dwjiidnswPascal P.
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

17.05.2018, 07:56:25 via App

x und y tauschen ist aber nicht drehen.
Überlege mal: Bsp:
Deine Tasse auf dem Tisch hat x=1 und y=5 aber mit x=5 und y=1 steht die Tasse nicht auf dem Kopf sodass der Kaffee rausläuft.

Somit musst du die Drehung extra für jeden Stein speichern und beim Zeichnen berücksichtigen.

Zudem: nach OOP kann ein Stein rotieren und die Rotierfunktion bekommt einen Stein. Somit müsste das Rotieren in der Stei klasse liegen. Dann kannst du auch Stein#rotate(int angle) aufrufen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

17.05.2018, 15:44:14 via Website

Ich glaube ich habe es etwas missverständlich geschriben. Hier sind 2 Screenshots die einen Stein vor und nach der Drehung zeigen(an der Rotation habe ich nichts verändert) und der Stein hat seine Position deutlcih verändert.
imageimage

— geändert am 17.05.2018, 15:46:29

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

17.05.2018, 16:26:27 via App

Und wenn du an der Rotstion nichts änderst, was wird dann geändert? Wenn du x und y tauschst wird der Stein auf dem Spielfeld verschoben, so wie bei dir dargestellt.
Du darfst diese nicht tauschen...

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

17.05.2018, 17:18:30 via Website

Wenn du x und y vertauscht ist er zwar gedreht. Aber er fällt wohl in y Richtung nach unten. Nach dem drehen ist y die horizontale somit wird der Stein wohl nach rechts verschoben wie es aussieht.
Pascal sagte ja das du den Stein in der Stein klasse drehen sollst und den Stein(klasse) nach unten fallen lassen sollst.

Überlege mal was passiert wenn du auf einem
Koordinaten System bei einen Punkt x und y tauscht. zb ein 400x400 Raster. Oben links ist 0,0 so wie bei Canvas. Ein Punkt am linken Rand in der Mitte ist x 0, y 200 . Wo ist er wenn du tauscht?
Der Punkt ist dann oben oben in der Mitte .

— geändert am 17.05.2018, 17:55:36

Hilfreich?
dwjiidnsw
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

19.05.2018, 23:07:56 via Website

Koordinaten System bei einen Punkt x und y tauscht. zb ein 400x400 Raster. Oben links ist 0,0 so wie bei Canvas. Ein Punkt am linken Rand in der Mitte ist x 0, y 200 . Wo ist er wenn du tauscht?
Der Punkt ist dann oben oben in der Mitte .
<
Ich dachte das würde ich verhindern weil ich ja die tmp Variablen habe.
Wie kann ich den Stein den dann drehen?

Hilfreich?
Kommentieren
Beste Antwort
Jokel
  • Forum-Beiträge: 1.537

20.05.2018, 12:43:40 via Website

Hallo ein Rechteck drehen kannst du in etwas so.

float left = 100f;
float top = 100f;
float right = 150f;
float bottom = 110f;
int px =100;
int py =100;
int wingkel = 90;

RectF r = new RectF(left,top,right,bottom);
Matrix m = new Matrix();

m.setRotate(wingkel, px, py);
m.mapRect(r);

Bei deiner Methode ist es nicht nur gedreht sonderen auch gespiegelt.
Sowie auch im Raum Verschoben.

— geändert am 20.05.2018, 13:02:38

Hilfreich?
dwjiidnswPascal P.
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

20.05.2018, 21:55:20 via Website

Hallo,
Danke, dass mit dem Rechteck rotieren klappt schonmal.
Also müsste ich praktisch den Stein in ein Rechteck, setzen und das Rechteck dann rotieren, richtig so? Dann muss ich mein ganzes Programm nochmal abändern, weil so wie ich es bisher habe, funktioniert dann das glaube ich nicht.

— geändert am 20.05.2018, 21:55:55

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

20.05.2018, 22:05:28 via Website

Oder du musst eben vier mal deine Rechtecke drehen, natürlich muss dabei der Drehpunkt für alle der gleiche sein.
Meine jedes Rechteck nur ein mal aber alle vier mit dem gleichen Drehpunkt.

— geändert am 20.05.2018, 22:07:18

Hilfreich?
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

20.05.2018, 23:13:24 via Website

Also meinst du jedes Teilquadrat von den 4, aus denen jeder Stein besteht drehen?

Hilfreich?
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

20.05.2018, 23:46:00 via Website

Ich habe mir jetzt noch was anderes überlegt, ich habe jetzt x1,y1 vom Stein als drehpunkt gesetzt:

 public void rotiereStein(Stein SpielStein) {
    int tmp_x1, tmp_y1;
    int tmp_x2, tmp_y2;
    int tmp_x3, tmp_y3;

    löscheStein(SpielStein);
    tmp_x1 = drehe_Um_x1(SpielStein, SpielStein.y2);
    tmp_y1 = drehe_Um_y1(SpielStein, SpielStein.x2);
    SpielStein.x2 = tmp_x1;
    SpielStein.y2 = tmp_y1;

    tmp_x2 = drehe_Um_x1(SpielStein, SpielStein.y3);
    tmp_y2 = drehe_Um_y1(SpielStein, SpielStein.x3);
    SpielStein.x3 = tmp_x2;
    SpielStein.y3 = tmp_y2;

    tmp_x3 = drehe_Um_x1(SpielStein, SpielStein.y4);
    tmp_y3 = drehe_Um_y1(SpielStein, SpielStein.x4);
    SpielStein.x4 = tmp_x3;
    SpielStein.y4 = tmp_y3;
}

 public int drehe_Um_x1(Stein SpielStein, int y) {
    return SpielStein.x1 + y - SpielStein.y1;
}

public int drehe_Um_y1(Stein SpielStein, int x) {
    return SpielStein.y1 - x + SpielStein.x1;
}

So werden die Steine zwar richtig gedreht, aber nach 2-3 Drehungen bleiben sie in der Luft stehen, hört sich jetzt komisch an, aber ich weiß nicht wie ich es besser schreiben soll.

— geändert am 20.05.2018, 23:52:30

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 10:40:25 via Website

Hallo, bevor ich dir hier helfen kann.

So wie ich es sehe bestehen deine Steine aus zwei Rechtecken oder?
Wie ist die Zuordnung der Punkte zu den Rechtecken?

SpielStein.x1; SpielStein.y1;
SpielStein.x2; SpielStein.y2;
SpielStein.x3; SpielStein.y3;
SpielStein.x4; SpielStein.y4;

Ich bin davon ausgegangen das du vier Rechtecke für deinen Stein benutzt. Können aber eigentlich nur zwei sein. Denn es sind nur 4 Punkte. Die Variablennahmen sind auch etwas nichts sagend.
Deshalb auch im letzten Post von mir das mit der Vier was dich wohl etwas durch einander gebracht hat.
und nun die Punkte seinbar einzeln zu drehen versuchst.
Hättest aber auch nachfragen können.

Auf meinen Vorschlag mit der Matrix und den Rechtecken bist du nicht eingegangen.
Du versuchst weiter die Punkte einzeln zu drehen dafür müsstest du viel Mathematische Berechnungen mit Cos und Sin machen. Das nimmt dir die Matrix ab.

Ich denke die Zuordnung ist so.

RectF r1 = new RectF( SpielStein.x1, SpielStein.y1, SpielStein.x2, SpielStein.y2);
RectF r2 = new RectF( SpielStein.x3, SpielStein.y3, SpielStein.x4, SpielStein.y4);

Darauf aufbauend meine Dreh Methode

public Stein rotiereStein(Stein SpielStein, int winkel) {

    Matrix m = new Matrix();
    Stein stein = new Stein();

    RectF r1 = new RectF( SpielStein.x1, SpielStein.y1,  SpielStein.x2,  SpielStein.y2);
    RectF r2 = new RectF( SpielStein.x3, SpielStein.y3,  SpielStein.x4,  SpielStein.y4);


    m.setRotate(winkel, SpielStein.x1, SpielStein.y1); // den Drehpunkt must du estscheiden
    m.mapRect(r1);
    m.mapRect(r2);

    stein.x1 = (int) r1.left;
    stein.y1 = (int) r1.top;
    stein.x2 = (int) r1.right;
    stein.y2 = (int) r1.bottom;

    stein.x3 = (int) r2.left;
    stein.y3 = (int) r2.top;
    stein.x4 = (int) r2.right;
    stein.y4 = (int) r2.bottom;

    return stein;
}

Wenn du in deiner Stein Klasse auch gleich Rechtecke „RectF“ benutzt ist das einfacher. Canvas kann damit auch umgehen.

Du darfst die Punkte nicht einzeln drehen. Immer ein Rechteck.

Hoffe das hilft erst mal weiter.

Ps. Ich weiß mit dem Nachfragen ist es hier im Forum etwas Doof da man nicht weiß wer Online ist.
Das währe eine sinnvolle Erweiterung des Forums.

— geändert am 21.05.2018, 11:17:24

Hilfreich?
dwjiidnsw
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

21.05.2018, 11:26:33 via Website

Danke für die Mühe.
Jetzt ist irgendwie bei beiden Rotations Methoden das selbe Problem.(bei meiner aus dem vorherigen Post) Die Steine drehen klappt, aber nach ein paar Drehungen bleiben sie einfach in der Luft stehen. Wenn die Steine aber nicht gedreht werden fallen sie ganz normal nach unten.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 11:37:41 via Website

Ohne etwas mehr von deinen Code.
Werden wir hier nicht weiter kommen.

Aufbau der Klasse Stein
Methode zum Fallen
Zeichnen der Steine

Kann es sein das du beim drehen (besser nach dem drehen) auserhalb des Zeichenberiches von canvas bist?

Hilfreich?
Pascal P.dwjiidnsw
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

21.05.2018, 11:58:12 via Website

Aus dem Zeichenbereich kann der Stein eigentlich nicht raus sein:
Ich habe mir jetzt mal die x1, y1 Koordinaten vom Stein ausgeben lassen, bis zur Drehung geht der Stein normal runter und nach der Drehung wird dann aber ein neuer Stein eingesetzt.

05-21 05:44:40.667 2290-2290/com.example.admin.tetris V/Log1: 1
05-21 05:44:40.667 2290-2290/com.example.admin.tetris V/Log2: 8
...
05-21 05:44:42.471 2290-2290/com.example.admin.tetris V/Log1: 5
05-21 05:44:42.471 2290-2290/com.example.admin.tetris V/Log2: 8
05-21 05:44:42.863 2290-2290/com.example.admin.tetris V/Log3: drehung
05-21 05:44:42.923 2290-2290/com.example.admin.tetris V/Log1: 6
05-21 05:44:42.923 2290-2290/com.example.admin.tetris V/Log2: 8
05-21 05:44:43.371 2290-2290/com.example.admin.tetris V/Log1: 1 // hier wird ein neuer Stein eingesetzt
05-21 05:44:43.371 2290-2290/com.example.admin.tetris V/Log2: 0

— geändert am 21.05.2018, 11:59:16

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 12:01:01 via Website

Wieso ein neuer Stein?
Du wilst ihn ja im fallen drehen oder?

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 12:03:53 via Website

wie Groß ist dein Spielfeld? Wie ist die Umsetzung vom Virtuellen Spielfelf zum Canvas?
Wie und wo Prüfst du ob der Stein unten oder auf einen anderen liegt?

— geändert am 21.05.2018, 12:05:39

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 12:11:13 via Website

@Pascal P. Danke für den Like.

Hilfreich?
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

21.05.2018, 12:16:45 via Website

Das ist ja das Problem, dass ein neuer SpielStein eingesetzt wird.

Hiermit drehe ich ja den aktuellen Stein:
case R.id.buttondrehen: spielFeld.rotiereStein(aktuellerStein()); invalidate(); break;

Das SpielFeld hat die Größe 30*30, wobei ein Kästchen vom Stein 30pixel sind, das canvas ist also 900*900.
In der SpielFeld klasse habe ich eine Methode die prüft ob der Stein nach unten verschiebar ist, also ob die SpielStein koordinaten kleiner sind als die Höhe vom Spielfeld, und ob das Feld noch leer ist.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 12:21:18 via Website

Diese Code Fragmente brigen mir nichts ich brauche den Zusammenhang.
wie so ein neuer Stein erstellt wird kann ich dir nicht sagen dazu brauchen wir den Code.
zeige mal die komplette Metohde rotiereStein und auch die Mehode des Fallens.

— geändert am 21.05.2018, 12:24:16

Hilfreich?
dwjiidnsw
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

21.05.2018, 12:36:25 via Website

Ich habe jetzt einen Fehler gefunden:

public boolean nachUntenverschiebar(Stein SpielStein) {
    if(SpielStein.x4<=höhe-2 && (SpielFeld[SpielStein.x4+1][SpielStein.y4]==0)  ) { 
        return true;
    }
    return false;
}

So hat es ohne die Rotation geklappt, aber wenn der Stein rotiert wurde kann es sein das der zweite Teil der if() Bedingung nicht mehr erfüllt wird und dann in der Tetris klasse ein neuer Stein erzeugt wird.
Nehme ich nähmlich den zweiten Teil der if() Bedingung weg lässt sich der Stein Einwand frei rotieren.

Endlich funktioniert die Rotation :), die hat mich glaube ich schon seit über 1 Woche beschäftigt.

Danke für die Hilfe @Jokel:)

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 12:53:56 via Website

Kann alles sein. Wie ich schon sagte nur mit solchen Code fragmenten ist es schwierig einen Rat zu geben.

Hilfreich?
dwjiidnsw
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 13:12:27 via Website

Hi mal eine Frage?
Wie Prüfst du den ob der Stein in eine Lücke passt. Für mich sieht es so aus als ob du nur den Raum unter dem Stein Prüfst.
Was machst du zb bei einem "L" nach unten gedreht was in eine Lücke soll. Da würde deine Test Methode bestimmt fehl schlagen.

Hilfreich?
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

21.05.2018, 13:14:32 via Website

Ja, dass muss ich noch machen und mir da noch was überlegen. Habe deine Antwort als beste Antwort markiert:).

Hilfreich?
Jokel
Kommentieren
Jokel
  • Forum-Beiträge: 1.537

21.05.2018, 18:06:14 via Website

Warum für jede Möglichkeit ein Sonderfall? Überlege dir eine allgemeingültiges Konzept. Sieht für mich etwas sehr zusammen gestückelt und nicht richtig durchdacht aus. Dein Konzept und die Umsetzung.

Überdenke nochmal richtig dein Konzept .

Übrigens danke für die beste Antwort.

LG J.

Hilfreich?
Pascal P.
Kommentieren