Bewegen ohne Ruckeln

Für Fragen von Einsteigern und Programmieranfängern...
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

Bewegen ohne Ruckeln

Beitrag von wennerer »

Hallo an Alle,
ich weiß das über dieses Thema schon viel geschrieben wurde. Von daher habe ich natürlich auch angefangen mit doublepuffered über in eine Bitmap zeichnen nach erasebackground so ziemlich alles getestet was im Netz zu finden ist.
In meinem angehängten Versuch hab ich mich (so denke ich) an diesen Wiki Beitrag gehalten: https://wiki.freepascal.org/Developing_ ... _vermeidet

Unter Linux Mint (gtk) läuft es eigentlich fast ohne Ruckeln, aber auch hier könnte es noch besser sein. In Windows ist es bei mir extrem langsam, selbst wenn ich den Timer auf 1 ms stelle. Erhöhe ich die Schritte auf 2 oder 3 Pixel ruckelt es und die Darstellung ist oft nicht komplett.
Mich würde interessieren geht da ohne OpeGL oder ein Gamepack mit einfachen Tricks mehr, mach ich da was komplett falsch oder ist dass das Beste was so möglich ist.

Vielleicht hat ja Jemand Lust meinen Versuch etwas zu verbessern. Ich denke ohne etwas Beispielcode verstehe ich nicht wie das gehen kann.

Viele Grüße
Bernd
Dateianhänge
playwithaball.zip
(141.66 KiB) 60-mal heruntergeladen

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

Re: Bewegen ohne Ruckeln

Beitrag von theo »

Naja, als Erstes würde ich TRacket und TBall anders angehen.
TCustomControl (Vofahr TWinControl) ist viel zu fett und mächtig.
Die beiden Objekte zeichnen ja im Grunde nur eine simple Grafik an einem bestimmten Ort auf den Form.Canvas bzw. das PufferBmp.
Sie müssen ja selber nicht auf Tastatur und Mauseingaben reagieren.
Wenn du dafür unbedingt eine (System-) Klasse benutzen willst, dann wäre TGraphicControl besser geeignet.

My 2 ¢

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 Theo,
hab ich jetzt probiert. Die Procedure ErasureBackground und die Eigenschaft Doublepuffered muss ich dann auskommentieren (lässt sich nicht ableiten). Ansonsten kann ich bei mir weder in Windows noch in Linux einen Unterschied erkennen. Bei mir ruckelt es und unter Windows ist es extrem langsam.

Viele Grüße
Bernd

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

Re: Bewegen ohne Ruckeln

Beitrag von theo »

Ich bin nicht auf Windows, deshalb kann ich das nicht überprüfen.
Ich fange so etwas einfach grundsätzlich anders an.

Ich fülle (in diesem Fall) drei Bitmaps in OnCreate mit den Grafiken.

Der Timer macht eigentlich nur:

Code: Alles auswählen

procedure TMainForm.Timer1Timer(Sender: TObject);   
begin
 Invalidate;
end;   
Also er veranlasst nur das Neuzeichnen (Paint).
(Deine 5ms sind natürlich viel zu niedrig. Das wären 200 Frames per second. Das kannst du total vergessen).

OnPaint kopiere ich erst den Hintergrund und dann die "beweglichen" Bitmaps auf den Puffer und dann den Puffer auf den Canvas.
Eigentlich brauchst du bis dahin gar kein TBall und TRacket.
Jeweils X,Y (bzw. TPoint) und die Bitmaps reichen dafür.
Vielleicht musst du die Position pro Schritt um mehr als 1 Pixel ändern, damit die Geschwindigkeit subjektiv stimmt.

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 »

Ansonsten kann ich bei mir weder in Windows noch in Linux einen Unterschied erkennen. Bei mir ruckelt es und unter Windows ist es extrem langsam.
Ich habe natives Linux und wine probiert. Einzig was ich feststellen kann, unter Linux läuft es schneller, Und unter wine kann ich kaum Ruckler erkennen.
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,
ich habe es nun mal so wie von Theo beschrieben umgestellt (hoffe ich zumindest). Unter Linux sehe ich eigentlich keinen Unterschied. In Windows 11 (native) läuft es immer noch viel langsamer, ich kann aber jetzt mehrere Pixel als Schritt einstellen ohne das es stark ruckelt. So komme ich ungefähr an das Ergebnis in Linux hin.
Mein Werk hab ich angehängt. Vielleicht sind ja doch noch Ändrungen nötig bzw. möglich.

Viele Grüße
Bernd
Dateianhänge
PlayWithABall2.zip
(141.48 KiB) 47-mal heruntergeladen

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

Re: Bewegen ohne Ruckeln

Beitrag von theo »

Wie oben gesagt: Dein Timer-Intervall ist nicht sinnvoll. Jetzt hast du 1ms drin, das heisst du verlangst 1000 x Neuzeichnen pro Sekunde.
Das schafft er sowieso nicht.
Mach den Wert auf z.B. 50 (20x Neuzeichnen pro Sekunde) und passe die Geschwindigkeit der Bewegung durch grössere Schritte an.
So hast du auch die Chance, dass es auf allen Rechner etwa gleich schnell aussieht.
Aber irgendwo ist natürlich Schluss. Hängt wohl auch von BS + Grafik ab.
Wenn das nicht reicht, musst du wirklich auf OpenGL etc. ausweichen.

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 »

Wenn das nicht reicht, musst du wirklich auf OpenGL etc. ausweichen.
Oder für so ein einfaches Spiel würde auch SDL2 genügen. Ausser man braucht das Widget-Set von der LCL.
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,
ich hab es nun mit 50ms (und +/-20) und größeren Schritten probiert. Das macht das Ergebnis auch nicht besser, aber ich weiß nun das es nicht an meinem Code liegt, sondern das dies mit "normalen" Mitteln wohl das beste Ergebnis ist.
Auf jeden Fall besten Dank für alle Antworten!

Viele Grüße
Bernd

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 »

Dein Code hatte ne Menge sachen die etwas suboptimal waren, darum hab ich mal ne minimale version gebaut und einen FPS Counter eingebaut. Der Timer tickt schon mit >60fps, das ist also nicht das Problem, und bei mir "Ruckelt" es auch nicht unter Windows, sondern was passiert ist das der Ball abgeschnitten ist, also nicht vollständig gezeichnet wird.
Demnach ist das Problem nicht im eigenen Code, denn der läuft mehr als schnell genug, das Problem ist das das Windows interne Fenstersystem nicht mit dem Updaten hinterherkommt.
Dateianhänge
breakout.zip
(3.96 KiB) 58-mal heruntergeladen

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,
hab es bei mir unter Linux und Windows probiert. Ja bei mir läuft dein Code auch mit 60fps in Windows, also richtig schnell. Ich werde mir in Ruhe ansehen was du alles verbessert hast. Letztlich bleibt aber das Ergebnis das gleiche. Für eine bessere Ausgabe bleibt nur OpenGL oder ein GamePack etc.
Eine Frage hätte ich noch, du legst zwei Konstanten fest:

Code: Alles auswählen

const
  RacketBaseSpeed = 500.;
  BallBaseSpeed = 500.;  
Was genau macht der Punkt hinter der 500?

Viele Grüße
Bernd

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 »

Das sagt einfach nur das die Zahl auf jeden Fall ein Fließkomma Typ ist, da diese form von Const nicht typisiert ist:

Code: Alles auswählen

const
  NumConst = 500;
  FloatConst = 500.;

var
  i: Integer;
  d: Double;
begin
  // NumConst funktioniert bei jedem Zahlentyp
  i:=NumConst;
  d:=NumConst;
  // FloatConst nur bei Fließkommatypen
  d:=FloatConst;
  i:=FloatConst; // Error 
Ist in diesem Fall nicht notwendig, aber manchmal bekommt man lustige Umwandlungsfehler (bzw. unerwartete berechnungen im Falschen typen) wenn man immer mit Zahlen Konstanten arbeitet die auch als Integer typen verwendet werden können, weshalb ich mir Angewöhnt hab, alles was ein Float ist auch als solchen zu schreiben.

Wenn einem das . nicht gefällt kann man auch 500.0 schreiben ums ein bisschen offensichtlicher zu machen

Benutzeravatar
six1
Beiträge: 837
Registriert: Do 1. Jul 2010, 19:01

Re: Bewegen ohne Ruckeln

Beitrag von six1 »

Ich weiß ja nicht genau, wie deine Erwartungshaltung ist.
Für einfache Spiele reicht es eigentlich...
viewtopic.php?f=11&t=13468
viewtopic.php?f=11&t=13459
Gruß, Michael

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 »

Also ich hab heute nochmal eine Version gebaut ohne Komponenten sondern rein mittels Canvas, und bekomme dabei auch solide > 60fps
Dateianhänge
game.zip
(3.85 KiB) 67-mal heruntergeladen

TSchnuckenbock
Beiträge: 118
Registriert: Do 20. Jul 2017, 23:47
OS, Lazarus, FPC: Win7 und Win10
CPU-Target: xxBit
Wohnort: Südheide (Schnuckenland)

Re: Bewegen ohne Ruckeln

Beitrag von TSchnuckenbock »

Ich hab' Warfs game.zip eben mal angetestet: Bei mir wird oben in der Caption 65 fps angezeigt. Lustiges Programm.

Antworten