AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

OnIdle-Timer

Ein Thema von Cöster · begonnen am 13. Sep 2006 · letzter Beitrag vom 14. Sep 2006
Antwort Antwort
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#1

OnIdle-Timer

  Alt 13. Sep 2006, 15:52
Hi!

Mein Spiel arbeitet bisher mit einem normalen Timer mit dem Intervall 13. Bei jedem Timer-Aufruf wird ein Ball auf dem Bildschirm um eine bestimmte Anzahl Pixel in eine bestimmte Richtung (abhängig von der gedrückten Pfeiltaste) verschoben.

Nun wollte diesen durch einen OnIdle-Timer ersetzen, damit die Positionen so oft wie möglich neu berechnet werden und neu gezeichnet wird.
Wie sollte ich das dann am besten machen?

Ich hab es mir so gedacht:
Ich habe 2 Variablen: Start und End vom Typ Integer. Ich speicher zu Beginn jedes Aufrufs der OnIdle-procedure GetTickCount unter End, ermittle mittels End - Start die vergangene Zeit seit dem letzten Aufruf und multipliziere diese mit einem Geschwindigkeitsfaktor (der kleiner als 1 ist). Daraus ergibt sich die aktuelle Position, die unter einer Variablen gespeichert wird. Zum Zeichnen muss diese durch Trunc() noch auf einen Integer gerundet werden. Start wird irgendwann während der procedure auf End gesetzt, aber erst nachdem die Zeitdifferenz berechnet wurde.

Ist die Überlegung gut? Wäre es schneller, statt mit einer Zahl kleiner als 1 zu multiplizieren durch eine Zahl größer als 1 zu teilen? Wird die ganze procedure vielleicht dadurch ausgebremst, dass mit Floats gerechnet wird? Das war ja bei dem Standard-Timer nicht so. Da hab ich einfach nur (wenn VK_Right gedrückt ist) PositionX + 5 gerechnet um die neue Position zu ermitteln. Sollte ich statt GetTickCount TimeGetTime benutzen? Es ist genauer, aber ist es auch schneller ermittelt?

Ich hoffe, ich könnt mir sagen, wie ich das möglichst performant hinkriege.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: OnIdle-Timer

  Alt 13. Sep 2006, 16:09
Hi,
ich denke mal alle 13 Sek. (das wären doch so ziemlich 75Hz ist mehr als ausreichend. Das menschliche Auge dürfte hier schon wieder langsamer auflösen und Flachbildschirme werden z.B. auch nur mit 60 Hz betrieben (viele zumindest). Das reicht also für Bewegungen schon aus. Die Frage ist also, warum brauchst du einen anderen Timer?
Ich denke mal, dass du eher wieder ein Problem mit dem Zeichnen hast, flimmert es oder springt dir der Ball zu sehr?

Nebenbei bemerkt, das ermitteln der vergangenen Zeit dürfte kaum ins Gewicht fallen. Die Unterschiede hier werden schon völlig durch dein Zeichnen dominiert, da muss deutlich mehr gemacht werden. Auch die Floatingpoint-Einheiten heutiger CPUs werden für deinen Fall keinen (ernsthaften) Flaschenhals darstellen.


Gruß Der Unwissende
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: OnIdle-Timer

  Alt 13. Sep 2006, 16:37
Naja, es ruckelt schon ein bisschen. DoubleBuffered ist True. Die Zeichnen-procedure (nested procedure, weil ich hier gelesen hab, dass das schneller ist) sieht so aus:

(Wert ist ein Array[1..7, 1..4], in dem Daten wie z.B. X-, Y-Position, Radius, Geschwindigkeit usw von Spieler 1 und 2 sowie von 2 Beamlöchern gespeichert sind. X, Y, Radius sind Integer-Konstanten.

Delphi-Quellcode:
procedure Zeichnen(Cvs: TCanvas; Spieler: Byte);
begin
  with Cvs do begin
    Pen.Color := Farbe[Spieler];
    Brush.Color := Farbe[Spieler];
    Ellipse(Wert[X, Spieler] - Wert[Radius, Spieler],
      Wert[Y, Spieler] - Wert[Radius, Spieler],
      Wert[X, Spieler] + Wert[Radius, Spieler],
      Wert[Y, Spieler] + Wert[Radius, Spieler]);
  end;
end;
Es wird nicht direkt auf das Image gezeichnet, sondern erst aufs Canvas einer globalen Variablen von Typ TBitmap. Ich erzeuge das Bitmap nicht immer neu, weil ich mir dachte, dass wichtige Zeit verloren geht, wenn ich jedesmal Bmp.Width und Height anpassen müsste und immer wieder Bmp := TBitmap.Create und Bmp.Free aufgerufen wird. Ist dieser Zeitgewinn kleiner als der Zeitverlust, der entsteht, weil Bmp global statt lokal ist?

Delphi-Quellcode:
with Bmp.Canvas do
begin
  Pen.Color := $00D8E9EC;
  Brush.Color := $00D8E9EC;
  Rectangle(0, 0, Bmp.Width, Bmp.Height);
end;
Zeichnen(Bmp.Canvas, Loch1);
Zeichnen(Bmp.Canvas, Loch2);
Zeichnen(Bmp.Canvas, 1);
Zeichnen(Bmp.Canvas, 2);
ImSpiel.Picture.Bitmap := Bmp;
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: OnIdle-Timer

  Alt 14. Sep 2006, 16:47
*push*
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz