Ankündigung

Einklappen
Keine Ankündigung bisher.

Frequenz von requestAnimationFrame ändern

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

  • Frequenz von requestAnimationFrame ändern

    Ich habe eine Applikation mit Animationen. Diese werden mit requestAnimationFrame erzeugt.
    requestAnimationFrame hat ja in der Regel eine Frequenz von 60/s, bzw. richtet sich nach der Bildwiederholrate des Monitors.

    Auf meinem PC funktioniert das wunderbar, aber auf dem Raspberry Pi, wo die Applikation schlussendlich laufen soll ist die Frequenz deutlich niedriger. Warum das so ist weiss ich nicht; die Bildwiederholrate habe ich extra auf 60Hz festgelegt.
    Das problem ist, dass durch die niedrigere Frequenz ungewollte Effekte in der Animation auftauchen.

    Gibt es eine Möglichkeit, die Frequenz von requestAnimationFrame auf einen bestimmten Wert festzulegen?


  • #2
    Du bist hier bei Javascript, lauft mit Animationen gewöhnlich auf dem Client oder Browser und da hat der ausliefernde Server (Raspberry Pi) nichts mit zu tun.

    Wenn es anders ist, dann bitte mal mit lauffähigem Code damit sich das ansehen kann.

    EDIT:
    https://developer.mozilla.org/en-US/...AnimationFrame da muss nichts angepasst werden, da die Bildwiederholrate automatisch und passend eingestellt wird. Ab 30 sollte es eh flüssig laufen, zumindest für das menschliche Auge.

    Kommentar


    • #3
      Zitat von protestix Beitrag anzeigen

      Wenn es anders ist, dann bitte mal mit lauffähigem Code damit sich das ansehen kann.
      Das ist nun etwas schwierig, da das Ding nur als ganzes Projekt läuft und auf einem proprietären FrameWork basiert.
      Aber ich versuche das problem so gut es geht zu erklären. Ich habe eine Schlange, die aus mehreren Teilen besteht und bei jeder Wiederholung neu auf ein Canvas gezeichnet wird
      Code:
      paint: function () {
          var i,
          width,
          height;
      
          // Snake-Elemente mit Kollisionserkennung ermitteln
          if (this.snakeElementCount > 1) {
              for (i = 1; i < this.snakeElementCount; i++) {
                  if (i <= 6) {
                      this.snakeElements[i].testCollision = false;
                  } else {
                      this.snakeElements[i].testCollision = true;
                  }
              }
          }
      
          // Werte des Kopfelements bei Spielbeginn definieren
          if (this.snakeElements[0].x === null) {
              this.snakeElements[0] = {
                  x: this.x,
                  y: this.y,
                  testCollision: false
              };
              // this.grow() zwei Mal ausführen für Initiallänge(3)
              this.grow();
              this.grow();
          }
          this.directions[0] = this.direction;
      
          // Snake aussen zeichnen
          for (i = 0; i < this.snakeElementCount; i++) {
              if (this.directionChanges.length > 0 && i > 0) {
                  for (j = 0; j < this.directionChanges.length; j++) {
                      if (this.snakeElements[i].x === this.directionChanges[j].x &&
                          this.snakeElements[i].y === this.directionChanges[j].y) {
                          this.directions[i] = this.directionChanges[j].direction;
                          this.directionChanges[j].count--;
                      }
                      // nicht mehr benötigte Elemente aus directionChanges löschen
                      if (this.directionChanges[j].count === 0 && i === this.snakeElementCount - 1) {
                          this.directionChanges.splice(j, 1);
                      }
                  }
              }
      
              switch (this.directions[i]) {
              case 'R':
                  this.snakeElements[i].x += this.speed;
                  break;
              case 'L':
                  this.snakeElements[i].x -= this.speed;
                  break;
              case 'U':
                  this.snakeElements[i].y -= this.speed;
                  break;
              case 'D':
                  this.snakeElements[i].y += this.speed;
                  break;
              }
      
              this.context.fillStyle = 'black';
              this.context.beginPath();
              this.context.globalAlpha = 0.4;
              this.context.arc(this.snakeElements[i].x + (this.snakeElementWidth / 2), this.snakeElements[i].y + (this.snakeElementHeight / 2), this.snakeElementWidth / 2, 0, 2 * Math.PI);
              this.context.fill();
              this.context.globalAlpha = 1;
          }
      
          // Snake innen zeichnen
          for (i = this.snakeElementCount - 1; i >= 0; i--) {
              width = this.snakeElementWidth - this.border;
              if (width < 1) {
                  width = 1;
              }
              height = this.snakeElementHeight - this.border;
              if (height < 1) {
                  height = 1;
              }
      
              var grd = this.context.createRadialGradient(this.snakeElements[i].x + ((width + this.border) / 2), this.snakeElements[i].y + ((height + this.border) / 2), 3, this.snakeElements[i].x + ((width + this.border) / 2), this.snakeElements[i].y + ((height + this.border) / 2), 15);
              grd.addColorStop(0, this.borderColor);
              grd.addColorStop(1, this.newColor);
              this.context.fillStyle = grd;
              this.context.beginPath();
              this.context.arc(this.snakeElements[i].x + ((width + this.border) / 2), this.snakeElements[i].y + ((height + this.border) / 2), width / 2, 0, 2 * Math.PI);
              this.context.fill();
          }
      }
      this.speed hat auf dem Raspi den Wert 6. Auf meinem Rechner bewegt sich die Schlange mit diesem Wert aber viel zu schnell, weshalb ich ihn dort auf 2 gesenkt habe.
      Wie man sieht, kann mit den tasten L, R, U und D die Richtung geändert werden.

      Die Funktion grow() sieht so aus:
      Code:
      grow: function () {
          var lastElementX = this.snakeElements[this.snakeElementCount - 1].x;
          var lastElementY = this.snakeElements[this.snakeElementCount - 1].y;
          var lastElementDirection = this.directions[this.directions.length - 1];
      
          this.directions.push(lastElementDirection);
      
          for (i = 0; i < this.directionChanges.length; i++) {
              this.directionChanges[i].count++;
          }
          // Abstand zum nächsten Element festlegen
          // ACHTUNG! Abstand muss durch 'speed' teilbar sein!
          switch (lastElementDirection) {
          case 'R':
              lastElementX -= 12;
              break;
          case 'L':
              lastElementX += 12;
              break;
          case 'U':
              lastElementY += 12;
              break;
          case 'D':
              lastElementY -= 12;
              break;
          }
          this.snakeElements.push({
              x: lastElementX,
              y: lastElementY,
              testCollision: false
          });
          this.snakeElementCount++;
      }
      Die Animation läuft auf beiden Systeme flüssig, aber das Problem ist, dass sich die Schlange bei einem Richtungswechsel manchmal teilt, d.h. der Kopf bewegt sich in eine andere Richtung weiter als der Körper (manchmal teilt sich auch noch der Körper in weitere Teile auf). Dies passiert aber nur auf dem Raspi (dort ist Chromium installiert). Auf meinem Rechner habe ich die Applikation mit Firefox, Chrome, Chromium und Edge getestet (im Internetexplorer läuft die Applikation grundsätzlich nicht). Das Phänomen tauchte dort aber nie auf.

      Kommentar


      • #4
        Zusatz: ich habe die Bildwiederholungsrate meines Bildschirms versuchsweise auf 30Hz, bzw. 24Hz eingestellt. Das Problem taucht aber dennoch nicht auf.

        Kommentar


        • #5
          dir fehlt halt noch dein delta Wert

          https://coderwall.com/p/iygcpa/gameloop-the-correct-way

          du musst den unterschied zu deinen Positionen dazu addieren

          du siehst zb in der Demo http://jsfiddle.net/xDZa4/ dass da dx*delta gerechnet wird das gleiche musst du auch bei dir machen
          lastElementX -= 12 * delta;
          apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp

          Kommentar


          • #6
            Zitat von BlackScorp Beitrag anzeigen

            du musst den unterschied zu deinen Positionen dazu addieren
            Das macht das Problem nur noch schlimmer.
            Zudem besteht das Problem ja nur auf dem Raspi. Wenn es am Deltawert liegen würde, würde das Problem ja auch auf meinem Rechner auftauchen.

            Kommentar


            • #7
              Zitat von MrChangelog Beitrag anzeigen

              Das macht das Problem nur noch schlimmer.
              Zudem besteht das Problem ja nur auf dem Raspi. Wenn es am Deltawert liegen würde, würde das Problem ja auch auf meinem Rechner auftauchen.
              Das Ding ist, requestAnimationFrame wird so oft es geht aufgerufen. Dein Raspberry PI ist langsamer also wird es nicht so oft aufgerufen wie auf deinem PC. Du musst also, damit es konstant bleibt. Deine Frames Per Second festlegen.

              Es gibt hier ein gutes gameloop tutorial https://www.koonsolo.com/news/dewitters-gameloop/ dort wird erklärt welche gameloops es gibt.

              Ich habe das ein wenig anders gemacht:

              https://github.com/BlackScorp/tiled2...me/game.js#L55 hier als Beispiel, da hab ich gesagt, ich will 25 FPS haben und bei jedem getAnimationRequest addiere ich ein frame dazu und gucke ob es durch 25 Teilbar ist, wenn nein dann mach ich nichts. Nachteil ist natürlich dass es bei schnellen PCs nicht flüssig ist

              Wie dem auch sei. Ich kann bei deinem Problem nicht direkt mit Beispielcode helfen weil ich deine Gameloop nicht gesehen habe. Du hast halt das Problem dass deine Geschwindigkeit abhängig ist von deiner PC leistung. deine x/y Werte aktualisieren sich so schnell es geht.
              apt-get install npm -> npm install -g bower -> bower install <package> YOLO https://www.paypal.me/BlackScorp

              Kommentar

              Lädt...
              X