Ankündigung

Einklappen
Keine Ankündigung bisher.

Pausefunktion

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Pausefunktion

    Ich habe ein Spiel entwickelt und verwende dort die Funktion "requestAnimationFrame();":
    PHP-Code:
    function defineAnimationFrame(_this) {
        var 
    loopWrapper = function() {
            
    _this.loop.call(_this);
            if (
    _this.isRunning) {
                
    _this._loopHandle window.requestAnimationFrame(loopWrapper);
            }
        };
        
    this._loopHandle window.requestAnimationFrame(loopWrapper);

    Das Spiel soll per Druck auf die Leertaste auch pausierbar sein:
    PHP-Code:
    function keyDownEvent(e) {
        if (
    e.key === ' ') {
            
    // Spiel pausieren
            
    var gameOver = new spiel.GameOver(this.spielfeldthis.spielfeld.figuresnullnullnull);
            
    gameOver.showPause();
        }

    Die Funktion gameOver.showPause() sieht so aus:
    PHP-Code:
    function showPause() {
        
    this.spielfeld.isRunning false;
        
    window.addEventListener('keydown'this.setFocusfalse);
        var 
    msgPause '<p style="color:lawngreen"><u>Pause!</u></p><p>Weiterspielen?</p>';
        
    this.spielfeld.rules[this.figures[0].no].innerHTML msgPause;
        
    document.body.appendChild(this.spielfeld.rules[this.snakes[0].no]);

        
    // Buttons 'Klar!' und 'Keine Lust' einfügen
        
    var buttonYes document.createElement('button');
        var 
    buttonNo document.createElement('button');

        
    buttonYes.classList.add('buttonPause');
        
    buttonYes.setAttribute('id''yes');
        
    buttonNo.classList.add('buttonPause');
        
    buttonNo.setAttribute('id''no');

        
    buttonYes.innerHTML 'Klar!';
        
    buttonNo.innerHTML 'Keine Lust!';

        
    buttonYes.addEventListener('click'this.resumeGamefalse);
        
    buttonNo.addEventListener('click'this.resumeGamefalse);

        
    this.spielfeld.rules[this.figures[0].no].appendChild(buttonYes);
        
    this.spielfeld.rules[this.figures[0].no].appendChild(buttonNo);
        
    buttonYes.focus();

    Bei Click auf die Buttons wird das Spiel entweder fortgesetzt (yes) oder abgebrochen (no):
    PHP-Code:
    function clickEvent(el) {
        if (
    el.currentTarget.innerHTML.includes('Klar!')) {
            
    window.removeEventListener('keydown'this.eventhandler);
            
    document.body.removeChild(this.spielfeld.rules[this.figures[0].no]);
            
    this.spielfeld.defineAnimationFrame(this.spielfeld);
            
    this.spielfeld.isRunning true;
        } else if (
    el.currentTarget.innerHTML.includes('Keine Lust!')) {
            
    document.location.reload();
        }

    Das Problem: wenn ich die Leertaste drücke pausiert das spiel zwar und das Pause-Div (this.spielfeld.rules) wird angezeigt. Lasse ich die Leertaste aber wieder los, wird das Spiel automatisch fortgesetzt. Ich komme also gar nie dazu, auf einen der Buttons zu drücken. Mit jeder anderen Taste (z.B. Shift) funktioniert es problemlos. Woran kann das liegen?

    PS: die Funktion setFocus() setzt den Fokus bei Drücken der Pfeiltasten Links-Rechts auf den linken, bzw. rechten Button. Das Spiel so schlussendlich ohne Maus spielbar sein.


  • #2
    Wo kommt die Variable e her?

    Kommentar


    • #3
      Zitat von hellbringer Beitrag anzeigen
      Wo kommt die Variable e her?
      Du meinst bei 'e.key'? Von der Callback-Function des Keydown-Events.

      Edit: habe im Eingansgpost den Code verständlicher gemacht.

      Kommentar


      • #4
        Schon mal mit einem Debugger nachgeschaut, was genau passiert bzw. wie oft die Funktion showPause() aufgerufen wird?

        Kommentar


        • #5
          Wenn ich im Browser debugge (F12) funktioniert die Funktion genau so, wie sie soll. Dabei setze ich einen Haltepunkt auf die Zeile, in der die Funktion showPause() aufgerufen wird.
          Offensichtlich tritt das Problem nur auf, wenn einer der 'Ja Klar!'-Button den Fokus erhält. Wenn ich das Skript nach dem Haltepunkt forsetze wird dies nämlich verhindert.

          Kommentar


          • #6
            Die Leertaste triggert wohl deinen "Ja"-Button.
            Du solltest e.stopPropagation in deinem KeyDown-Handler aufrufen.

            https://en.wikipedia.org/wiki/Event_bubbling

            Grüße.

            Kommentar


            • #7
              php1704 ich habe e.stopPropagation in der Funktion 'keyDownEvent(e)' nach dem Kommentar eingefügt. Zudem habe ich es auch mit e.stopImmediatePropagation() versucht. Das Problem besteht aber weiterhin.

              Kommentar


              • #8
                MrChangelog

                Ich will jetzt nicht im Einzelnen auf Deinen Code eingehen, betrachte mal folgende Zeilen, evtl. ist das hilfreich...

                HTML-Code:
                <!DOCTYPE html>
                <html lang="de">
                 <meta charset="utf-8">   
                  <title>Pause Animation</title>
                  <style>
                    svg{width:400px;border:1px solid gray;display:block;}
                    #myRotate{fill:#f00;stroke:#000;stroke-width:4;transform-origin: 50% 50%;}
                    button{display:none;}
                  </style>
                  <p>Das läuft nicht unter IE - babel.js und polyfills helfen...</p>
                  <svg viewBox="0 0 400 400">
                    <rect id=myRotate x=100 y=100 width=200 height=200 />
                  </svg>     
                  <button id=play>Play</button>
                  <script>
                    var rotateAngel = 0,
                    sikStep = step = 2 
                    function animate() {
                      requestAnimationFrame(animate);
                      rotateAngel = rotateAngel == 360 ? 0 : rotateAngel
                      myRotate.setAttribute("transform", `rotate(${rotateAngel+= step})`)  
                    }
                    window.focus();
                    animate();
                    document.addEventListener('keydown', ev => {
                      console.log(ev.key);
                      step = ev.key !== ' '
                      play.style.display='block'
                      })  
                    play.addEventListener('click', () => {
                      play.style.display='none';
                      step = sikStep;
                      if (document.activeElement) 
                          document.activeElement.blur()
                      })
                  </script>

                Kommentar


                • #9
                  Zitat von php1704 Beitrag anzeigen
                  Die Leertaste triggert wohl deinen "Ja"-Button.
                  Sieht so aus. Merkwürdig: wenn ich statt der Leertaste die Eingabe-Taste verwende wird nicht nur der Button getriggert, aus unerfindlichen Gründen wird auch die Animation schneller

                  Kommentar


                  • #10
                    #8 sollte zum Nachdenken anregen...

                    Nimm bspw. folgende Code:
                    HTML-Code:
                    <!DOCTYPE html>
                    <html lang="de">
                     <meta charset="utf-8">  
                      <title>Pause Animation</title>
                      <style>
                        svg{width:400px;border:1px solid gray;display:block;}
                        #myRotate{fill:#f00;stroke:#000;stroke-width:4;transform-origin: 50% 50%;}
                      </style>
                      <svg viewBox="0 0 400 400">
                        <rect id=myRotate x=100 y=100 width=200 height=200 />
                      </svg>    
                      <button id=play>Play</button>
                     <script>
                        var α=0, δ=3, pause=true,
                        ani = () => !pause && requestAnimationFrame(ani) !=
                          myRotate.setAttribute("transform",`rotate(${α=α==360?0:α+=δ})`)
                        window.onkeydown = ev => play.hidden = !(pause=ev.key==' ')
                        play.onclick = () => play.hidden = !(pause=false) != ani() != play.blur()
                      </script>
                    streichst Du play.blur() wird bei Drücken der Leertaste click ausgeführt da play noch den Focus hat (mit Firefox getestet).

                    Deine Animation wird schneller weil Du mehrfach requestAnimationFrame aufrufst.

                    Ansonsten wäre es hilfreich ein fiddle zu bauen. Deine Codefragmente helfen wenig.

                    Kommentar


                    • #11
                      Zitat von kaminbausatz Beitrag anzeigen

                      Deine Animation wird schneller weil Du mehrfach requestAnimationFrame aufrufst.
                      Korrekt!
                      Ich hab das Problem nun beheben können:
                      PHP-Code:
                      setTimeout(function(){buttonYes.focus();}, 10); 
                      So erhält der Button den Fokus etwas verzögert und kann nicht mehr versehentlich getriggert werden.

                      Kommentar


                      • #12
                        Zitat von MrChangelog Beitrag anzeigen
                        So erhält der Button den Fokus etwas verzögert und kann nicht mehr versehentlich getriggert werden.
                        Ist das eine Lösung oder nicht doch eher eine Krücke?

                        Kommentar

                        Lädt...
                        X