derletztekick: Drehung einer Ebene wird doppelt ausgeführt

Hallo,

ich habe ein Clone von Tetris erstellt - ist schon etwas her - der in allen von mir getesteten Browsern (Opera, Gecko, IE) problemlos läuft. Nun habe ich erfahren, das der Maxthon-Browser sich nicht korrekt verhält - nachdem ich diesen installiert habe, kann ich das auch bestätigen. Einen Fehler kann ich trotzdem nicht finden. Möglicherweise zeigen auch andere Browser noch das selbe Problem.

Was ist nun das Problem? Ein Tetrisbaustein kann gedreht werden. Meine Steine bestehen aus Arrays vom Typ Boolean - true steht für den Stein, false für die Lücken zB das J:

  
figureTypes[0] =  [[true, false, false],  
                  [true, true, true]];

Gedreht werden die Spielsteine über eine Rotationsmatrix um 90°:

  
var R = new Array();  
R[0] = new Array(0, (-1*val));  
R[1] = new Array((1*val),  0);

wobei die Variabel "val" die Drehrichtung (links/rechts) angibt und dementsprechend 1 bzw. -1 ist. Es werde dann die true-false-Werte getauscht, an der Anzeige ändert sich dadurch jedoch noch nichts.

Wenn ein Stein gedreht wird, führe ich intern diese Rotation durch, prüfe, ob diese zulässig war und drehe den Stein zurück in seine Ausgangslage. Wenn die Drehung nicht gültig ist, bleibt alles so, wie es ist. Ist die Drehung hingegen möglich, entferne ich die sichtbaren Felder (Hintergurndfarbe transparent) drehe den Stein und mache die Felder sichtbar, die im Array true sind:

  
var kc = getKeyCode(e);  
if (kc == 32 || kc == 38 || kc == 83 || kc == 115 || kc == 73) {  
  Block.rotate();  
  if (GP.canInsert(Block,Block.y,Block.x)){  
    //Stein kann nach Drehung eingestetzt werden  
    Block.rotate(-1);  
    //Entferne Felder - Hintergrundfarbe  
    GP.removeToken(Block);  
    Block.rotate();  
    //Mache neue Feler sichtbar  
    GP.moveSidelongToken(Block, 0);  
  }  
  else {  
    //Stein kann nicht gesetzt werden, Testdrehung rückgängig machen  
    Block.rotate(-1);  
  }  
}

Im Maxthon-Browser wird jedoch diese Rotation zweimal durchgeführt. Es kommen also scheinbar nur Drehungen um 180° zu stande - sieht man beim T-Stein. Setze ich zwischen der Hin- und Rückdrehungen ein alert() und lass mit das Array testweise ausgeben, kommt 1. das korrekt raus und 2. wird nur um 90° gedreht - alles schein korrekt zu funktionieren! Selbigen Effekt erhält man auch, wenn man die [ALT]-Taste beim drehen drückt?!

Zur Navigation sind neben einigen Alternativen die Tasten I,J,K,L recht geeignet, wie mir scheint. Wer es also mal live testen will - nur zu zum Spiel...

Kann mir einer sagen, warum und wodurch dieses Problem auftritt?

Versucht habe ich auch schon, den Spielstein zu clonen und mit diesem Clone die Prüfdrehungen durchzuführen - erfolglos.

Mit freundlichem Gruß
Micha

  1. Hallo derletztekick.

    Zur Navigation sind neben einigen Alternativen die Tasten I,J,K,L recht geeignet, wie mir scheint. Wer es also mal live testen will - nur zu zum Spiel...

    Nichts zu deinem Problem, aber könntest du neben [↑] und [Space] noch eine andere Taste zum Drehen der Steine zulassen? Im Opera bewirken beide, dass die Seite gescrollt wird, was hier eher nicht erwünscht ist.

    Einen schönen Samstag noch.

    Gruß, Mathias

    --
    ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
    debian/rules
    1. Hallo Mathias,

      Zur Navigation sind neben einigen Alternativen die Tasten I,J,K,L recht geeignet, wie mir scheint. Wer es also mal live testen will - nur zu zum Spiel...

      Nichts zu deinem Problem, aber könntest du neben [↑] und [Space] noch eine andere Taste zum Drehen der Steine zulassen?

      Es sind noch A, S, und I zulässig. Im Opera scheint mir I die beste Lösung zu sein, da hier fast alle Tasten schon vorbelegt sind und I scheinbar keine für die Seite relevante Funktion besitzt.

      Mit freundlichem Gruß
      Micha

      1. Hallo derletztekick.

        Zur Navigation sind neben einigen Alternativen die Tasten I,J,K,L recht geeignet, wie mir scheint. Wer es also mal live testen will - nur zu zum Spiel...

        Nichts zu deinem Problem, aber könntest du neben [↑] und [Space] noch eine andere Taste zum Drehen der Steine zulassen?

        Es sind noch A, S, und I zulässig. Im Opera scheint mir I die beste Lösung zu sein, da hier fast alle Tasten schon vorbelegt sind und I scheinbar keine für die Seite relevante Funktion besitzt.

        Öhm, ja, lesen sollte ich in der Tat statt einfach nur loszuspielen. Ich Frevler.

        Einen schönen Samstag noch.

        Gruß, Mathias

        --
        ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
        debian/rules
  2. Hi there,

    Leider keine Lösung zu Deinem Problem, aber das Spiel gefällt mir sehr gut, auch wenn das Ende ein wenig aprupt kommt;))

    1. Hallo Klawischnigg,

      aber das Spiel gefällt mir sehr gut,

      Danke!

      auch wenn das Ende ein wenig aprupt kommt;))

      Versuche so lange wie möglich *keine* Reihe abzuräumen. Mit jeder Reihe, die Du entfernst, steigerst Du die Geschwindigkeit. Aber, räumst Du gleichzeitig mehr als eine Reihe ab, so addiert sich die Anzahl nicht. Sprich, vier einzelne Reihen erhöht viermal die Geschwindigkeit. Das gleichzeitige Abräumen von vier Reihen erhöht den Speed nur einfach - dafür erhöht sich ggf. das Risiko, Lücken zu bekommen

      Viel Spaß!

      Mit freundlichem Gruß
      Micha

  3. Hallo,

    ich habe das Problem für mein Tetris JavaScript gelöst bekommen und somit zwangsläufig auch ein weiteres entfernt. *freu*

    Zunächst: es macht für diesen Browser (Maxthon) einen Unterschied, ob ich onkeypress oder nur onkeydown nutze. Mit erstgenannten dreht er die Steinchen nur einmal - also wie gewünscht.
    Onkeypress hat den schönen Nebeneffekt, das man auch die Taste gedrückthalten kann und nicht wiederholt die Pfeil nach unten Taste drücken muss, um den Stein schneller nach unten zu bewegen - zumindest im Opera und Gecko.
    Komischerweise funktionieren die Cursortasten dann im IE und Maxthon nicht mehr, sodass hierfür wiederum keydown herhalten muss, welches jedoch als keypress scheinbar interpretiert wird?!

      
    if (typeof(window.event) != "undefined" && !window.opera)  
      document.onkeydown = function(e) {  
        //Bewegungsanweisungen  
      };
    

    Das Problem, welches Du, Mathias, angespochen hast - Seite sprint beim Navigieren mittels Leer- und Cursotasten -, habe ich versucht anzugehen. Ich habe die Felder nun etwas kleiner gemacht (12 Pixel, vorher 15), sodass zumindest bei mir in allen Browsern das Spielfeld vollständig zu sehen war.

    Zur Feier gibts auf Wunsch einen weiteren fiesen Spielstein - das U ;-)

    Mit freundlichem Gruß
    Micha

    1. Hallo derletztekick.

      Das Problem, welches Du, Mathias, angespochen hast - Seite sprint beim Navigieren mittels Leer- und Cursotasten -, habe ich versucht anzugehen. Ich habe die Felder nun etwas kleiner gemacht (12 Pixel, vorher 15), sodass zumindest bei mir in allen Browsern das Spielfeld vollständig zu sehen war.

      Ja, ist nun angenehmer zu spielen.

      Ist es eigentlich gewünscht, dass ein schnelles Ablegen der Steine kontinuierlich möglich ist? Momentan kann man per Druck auf [↓] in Nullkommanichts das Spiel beenden; der Tastendruck sollte also besser nicht für neu im Spielfeld platzierte Steine gelten.

      Einen schönen Sonntag noch.

      Gruß, Mathias

      --
      ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
      debian/rules
      1. Hallo Mathias,

        Ja, ist nun angenehmer zu spielen.

        Schön!

        Momentan kann man per Druck auf [↓] in Nullkommanichts das Spiel beenden;

        Das könnte mit Return noch schneller gehen nur, warum willst Du oder allg. man das tun? In einem Ego-Shooter kann man auch eine Handgranate vor sich hinlegen/werfen und dabei Selbstmord begehen, ob sinnvoll oder nicht.

        der Tastendruck sollte also besser nicht für neu im Spielfeld platzierte Steine gelten.

        Ich glaube, ich weiß, wie Du es meinst aber auf die Schnelle sehe ich keine Möglichkeit. Wenn ein Stein erstellt wird, vgl. die Funktion initBlock(), reagiert er auch auf die Tastatur. Ich muss es vermutlich trennen, um Deinem Wunsch nackommen zu können - ich werds mal durchdenken. Wenn Du was hast, bin ich natürlich auch offen für Anregungen.

        Mit freundlichem Gruß
        Micha

        1. Hallo derletztekick.

          Ja, ist nun angenehmer zu spielen.
          Schön!

          Momentan kann man per Druck auf [↓] in Nullkommanichts das Spiel beenden;
          Das könnte mit Return noch schneller gehen nur, warum willst Du oder allg. man das tun? In einem Ego-Shooter kann man auch eine Handgranate vor sich hinlegen/werfen und dabei Selbstmord begehen, ob sinnvoll oder nicht.

          Och, wenn man keine Wahl hat …

          der Tastendruck sollte also besser nicht für neu im Spielfeld platzierte Steine gelten.
          Ich glaube, ich weiß, wie Du es meinst aber auf die Schnelle sehe ich keine Möglichkeit. Wenn ein Stein erstellt wird, vgl. die Funktion initBlock(), reagiert er auch auf die Tastatur. Ich muss es vermutlich trennen, um Deinem Wunsch nackommen zu können - ich werds mal durchdenken. Wenn Du was hast, bin ich natürlich auch offen für Anregungen.

          Das einzige, was mir hier einfiele, wäre innerhalb der onkeypress-Funktion in einem Interval auf ein bestimmtes Flag (Stein abgelegt) zu prüfen. Wurde dieses Flag aktiviert, wird nur noch false zurück gegeben. Bei onkeyup setzt du dieses Flag wieder zurück, womit die eigentliche Funktionalität von onkeypress (Stein schneller nach unten bewegen) wieder verfügbar wird.

          Klingt hässlich, ist es auch. Ich hoffe dass jemand eine besser Idee hat.

          Einen schönen Sonntag noch.

          Gruß, Mathias

          --
          ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
          debian/rules
          1. Hallo Mathias Brodala,

            Das einzige, was mir hier einfiele, wäre innerhalb der onkeypress-Funktion in einem Interval auf ein bestimmtes Flag (Stein abgelegt) zu prüfen. Wurde dieses Flag aktiviert, wird nur noch false zurück gegeben. Bei onkeyup setzt du dieses Flag wieder zurück, womit die eigentliche Funktionalität von onkeypress (Stein schneller nach unten bewegen) wieder verfügbar wird.

            Sowas in der Art fiel mir auch ein - noch nicht ganz so durchdacht aber ähnlich ;-). Ich Frage mich im Moment jedoch noch, ob es wirklich ein Gewinn fürs Spiel wäre? Ich nutze diese Funktion nicht, sondern Drehe, Platziere und drück Enter.
            Gerade am Ende, wenn es etwas rasanter wird, ist man mE bestrebt, nur noch die neuen Steine von der Mitte weg zu bewegen, um den "Eingang" so lange wie möglich frei zu halten. Ein kontrolliertes Drehen und Platzieren ist da meist nicht mehr möglich. Hier fände ich afaik ein kontinuierliches >nach links< Bewegen hilfreicher, als zwischenzeitlich noch die Taste loslassen zu müssen. Natürlich könnte man das Event gedrückte [↓]-Taste explizit abfragen und lediglich hier Deinen oder einen ähnlichen Weg bestreiten aber das machts ja auch nicht einfacher (-:

            Trotzdem Danke schon einmal!

            Mit freundlichem Gruß
            Micha

            1. Hallo derletztekick.

              Das einzige, was mir hier einfiele, wäre innerhalb der onkeypress-Funktion in einem Interval auf ein bestimmtes Flag (Stein abgelegt) zu prüfen. Wurde dieses Flag aktiviert, wird nur noch false zurück gegeben. Bei onkeyup setzt du dieses Flag wieder zurück, womit die eigentliche Funktionalität von onkeypress (Stein schneller nach unten bewegen) wieder verfügbar wird.

              Sowas in der Art fiel mir auch ein - noch nicht ganz so durchdacht aber ähnlich ;-). Ich Frage mich im Moment jedoch noch, ob es wirklich ein Gewinn fürs Spiel wäre?

              Gewiss, da es so seltener vorkommt, dass man versehentlich einen Stein ablegt. Momentan muss man höllisch aufpassen, die Taste rechtzeitig loszulassen um die Kontrolle zu behalten.

              Ich nutze diese Funktion nicht, sondern Drehe, Platziere und drück Enter.

              Am Anfang ist sie schon recht praktisch um das Spiel etwas zu beschleunigen.

              Einen schönen Montag noch.

              Gruß, Mathias

              --
              ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
              debian/rules
              1. Hallo Mathias,

                Momentan muss man höllisch aufpassen, die Taste rechtzeitig loszulassen um die Kontrolle zu behalten.

                Gut, ich habe es versucht umzusetzen - zum Spiel. Mir kommt es nur ab und zu so vor, als würde er das gelegentlich "ignorieren"; kann mich aber irren, da er erst einen Schritt macht und dann fließen nach unten sich bewegt.

                Mit freundlichem Gruß
                Micha

                1. Hallo derletztekick.

                  Momentan muss man höllisch aufpassen, die Taste rechtzeitig loszulassen um die Kontrolle zu behalten.

                  Gut, ich habe es versucht umzusetzen - zum Spiel. Mir kommt es nur ab und zu so vor, als würde er das gelegentlich "ignorieren"; kann mich aber irren, da er erst einen Schritt macht und dann fließen nach unten sich bewegt.

                  Dein Eindruck täuscht nicht, aber ich persönlich empfinde dies nicht als störend. Dafür lässt es sich nun sicherer spielen.

                  Einen schönen Montag noch.

                  Gruß, Mathias

                  --
                  ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
                  debian/rules
                  1. Hallo Mathias Brodala,

                    Dafür lässt es sich nun sicherer spielen.

                    Na dann viel Spaß und vielen Dank für Deine Anregung!

                    Mit freundlichem Gruß
                    Micha