Bewegen ohne Ruckeln

Für Fragen von Einsteigern und Programmieranfängern...
Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 385
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Bewegen ohne Ruckeln

Beitrag von Jorg3000 »

Warf hat geschrieben: So 25. Aug 2024, 21:37 was passiert ist das der Ball abgeschnitten ist, also nicht vollständig gezeichnet wird
Gegen das sogenannte Tearing (abschneiden oder schmieren) gibt es Double Buffering.
Weiter oben habe ich gelesen, dass es irgendein Problem damit gab und deshalb nicht verwendet wurde. Ich würde es mit Double Buffering versuchen.

Soweit ich gelesen habe, gibt es nativ unter Win32 keine Möglichkeit das Double Buffering gezielt mit der Bildwiederholrate abzugleichen, damit es sauber flüssig läuft.
Dazu müsste man Direct3D oder OpenGL verwenden, wo es V-Sync gibt, um den Pufferwechsel mit der Bildwiederholrate des Monitors zu synchronisieren.

wennerer
Beiträge: 609
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Bewegen ohne Ruckeln

Beitrag von wennerer »

Allen vielen Dank für die Antworten!

@Warf: ich hab dein game in Windows und Linux getestet. Windows ca 65fps, Linux ca. 195fps. Ich hab dann den Timer in Linux auf 15ms erhöht dann lieg ich da auch um die 60fps. Ein Ruckeln ist für mich nicht mehr erkennbar. Ich werde nun mal in Ruhe versuchen deinen Code zu verstehen. Herzlichen Dank dafür!

Viele Grüße
Bernd

Mathias
Beiträge: 6956
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bewegen ohne Ruckeln

Beitrag von Mathias »

TSchnuckenbock hat geschrieben: Mo 26. Aug 2024, 17:10 Ich hab' Warfs game.zip eben mal angetestet: Bei mir wird oben in der Caption 65 fps angezeigt. Lustiges Programm.
Bei mir sind es sogar 184,
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6956
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bewegen ohne Ruckeln

Beitrag von Mathias »

Dazu müsste man Direct3D oder OpenGL verwenden, wo es V-Sync gibt, um den Pufferwechsel mit der Bildwiederholrate des Monitors zu synchronisieren.
Von DirectX würde ich die Finger lasse, da ist man an Microsoft gebunden.
Wie schon gesagt, für dieses einfache 2D Spiele wurde ich den SDL-Renderer verwenden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Soner
Beiträge: 734
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Bewegen ohne Ruckeln

Beitrag von Soner »

Warf hat geschrieben: Mo 26. Aug 2024, 15:17 Also ich hab heute nochmal eine Version gebaut ohne Komponenten sondern rein mittels Canvas, und bekomme dabei auch solide > 60fps
Ich habe mal eine Frage zu der Funktion:

Code: Alles auswählen

function TimeDiff: Double;
const
  LastTick: QWord = 0;
var
  CurrentTime: QWord;
begin
  CurrentTime := GetTickCount64;
  if LastTick <> 0 then
    Result := (CurrentTime - LastTick) / 1000
  else
    Result := 0;
  LastTick := CurrentTime;
end; 
Da LastTick eine lokale Konstante ist, wie kann es seinen Wert behalten? Es müßte doch immer 0 sein. Irgendeine neue Entwicklung muss ich in Pascal verpaßt haben oder Tomaten auf den Augen haben.

siro
Beiträge: 761
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Bewegen ohne Ruckeln

Beitrag von siro »

Guten Morgen,

LastTick ist zwar eine lokale Variable, aber durch den Zusatz von const wird sie statisch lokal.
Das heisst, sie wird nicht auf den Stack abgelegt sondern liegt fest im Datensegment und behält damit seinen Wert.
Zugreifen kann man jedoch nur innerhalb der Procedure/Funktion auf diese Variable.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1650
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Bewegen ohne Ruckeln

Beitrag von fliegermichl »

siro hat geschrieben: Di 27. Aug 2024, 06:50 Guten Morgen,

LastTick ist zwar eine lokale Variable, aber durch den Zusatz von const wird sie statisch lokal.
Das heisst, sie wird nicht auf den Stack abgelegt sondern liegt fest im Datensegment und behält damit seinen Wert.
Zugreifen kann man jedoch nur innerhalb der Procedure/Funktion auf diese Variable.
Das war auch bei Delphi schon so und ist auch dokumentiertes Verhalten.

Benutzeravatar
theo
Beiträge: 10921
Registriert: Mo 11. Sep 2006, 19:01

Re: Bewegen ohne Ruckeln

Beitrag von theo »

fliegermichl hat geschrieben: Di 27. Aug 2024, 10:06 Das war auch bei Delphi schon so und ist auch dokumentiertes Verhalten.
Ja, aber es ist gleich in zweierlei Hinsicht verwirrend und daher mMn "unpascalisch". :wink:
1. Konstante ist beschreibbar.
2. Lokal global (implizit)
Ich kann schon verstehen, wenn man da die Stirn runzelt, obwohl der Wunsch nach so einer Funktionalität nachvollziehbar ist.
Leider alles ohne explizite Keywords (z.B. writeable, global etc...)

https://pascal.today/2016/08/05/local-global-variables/

Ich mache um so etwas einen Bogen, da mir die Gefahr zu gross ist, dass ich selber beim nächsten Mal lesen diese Ausnahmeregeln nicht mehr auf dem Schirm habe.
Ich nehme an, diese Diskussion ist nicht neu.

Warf
Beiträge: 2142
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Bewegen ohne Ruckeln

Beitrag von Warf »

Soner hat geschrieben: Di 27. Aug 2024, 00:12 Da LastTick eine lokale Konstante ist, wie kann es seinen Wert behalten? Es müßte doch immer 0 sein. Irgendeine neue Entwicklung muss ich in Pascal verpaßt haben oder Tomaten auf den Augen haben.
Das ganze heißt "writable const", ein wunderschönes Oxymoron, und ist eine Variable mit Globaler Lebensdauer aber Lokalem Scope. Damit ist der Speicher persistent, die Variable allerdings nur in der definierenden Funktion benutzbar ist. Der Name und die Syntax ist verwirrend, das Konzept ist aber sehr hilfreich, denn manchmal braucht man einen Wert der Zwischen Funktionsaufrufen gleich bleibt, aber ausschließlich in der Funktion benutzt wird, weshalb eine Globale Variable oder ein Feld in der Klasse (Globale Variable mit extra Schritten) einen zu großen Scope hat.

Wird bei der UpdateFPS Funktion genauso gemacht für den Frame und Sekunden Zähler.

Ein paar Limitation sind allerdings das es natürlich global ist, d.h. wenn du mehrere Instanzen der selben form hast mit mehreren Timern hätten die würden sich gegenseitig die Zeiten updaten (macht aber ja keinen Sinn das irgendwer das Spiel zwei mal spielt) und es ist nicht thread local, also mehrere threads würden sich gegenseitig den Counter kanibalisieren.

Soner
Beiträge: 734
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Bewegen ohne Ruckeln

Beitrag von Soner »

Danke für die Erklärungen.

Mathias
Beiträge: 6956
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bewegen ohne Ruckeln

Beitrag von Mathias »

siro hat geschrieben: Di 27. Aug 2024, 06:50 Guten Morgen,

LastTick ist zwar eine lokale Variable, aber durch den Zusatz von const wird sie statisch lokal.
Das heisst, sie wird nicht auf den Stack abgelegt sondern liegt fest im Datensegment und behält damit seinen Wert.
Zugreifen kann man jedoch nur innerhalb der Procedure/Funktion auf diese Variable.
Dies ist nach meiner Meinung ein bisschen unglücklich gelöst in Pascal.
const sollte immer etwas unverändertes sein, wen Änderungen möglich sein sollten, gibt es war.
Andere Sprachen lösen dies besser, da gibt es "static".
So wäre es viel eindeutiger.

Code: Alles auswählen

procedure blabla;
var
  i: Integer; static;
 begin
Wenigstens In classen kennt Pascal static.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wennerer
Beiträge: 609
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Bewegen ohne Ruckeln

Beitrag von wennerer »

Hallo Warf,
ich möchte mich nochmal für deinen Code bedanken! Hat etwas gedauert aber ich musste erst einmal einige Artikel im Internet lesen um deine Unit GameMath zu verstehen (und sicherlich blieb mir noch einiges verborgen).
Das ist ja super elegant. Sobald das Wetter schlechter wird werd ich damit sicherlich einiges probieren.

Viele Grüße
Bernd

Antworten