Delphi-PRAXiS
Seite 6 von 9   « Erste     456 78     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Pac-Man Hilfe (https://www.delphipraxis.net/184622-pac-man-hilfe.html)

Mavarik 14. Apr 2015 15:31

AW: Pac-Man Hilfe
 
Zitat:

Zitat von himitsu (Beitrag 1297722)
Und was ist bei 73,4%?

Man nimmt die Zeit bis vorm letzten Zeichnen und weiß, wie weit man sich jetzt bewegen muß. :angle:

Pac-Man ist aber Pixelorientiert und nicht darauf ausgelegt Pixel zu überspringen!

himitsu 14. Apr 2015 15:41

AW: Pac-Man Hilfe
 
Das kann man ja ändern. :stupid:

* Intern mit Teilpixelrechnen
* auf ganze Pixel gerundet anzeigen
* oder intern mit ganzen Pixeln rechnen, aber über längere Zeit die Geschwindigkeit berechnen/verrechnen
* ...
* Zwischenschritte interpolieren

Sir Rufo 14. Apr 2015 16:08

AW: Pac-Man Hilfe
 
Zitat:

Zitat von Mavarik (Beitrag 1297724)
Zitat:

Zitat von himitsu (Beitrag 1297722)
Und was ist bei 73,4%?

Man nimmt die Zeit bis vorm letzten Zeichnen und weiß, wie weit man sich jetzt bewegen muß. :angle:

Pac-Man ist aber Pixelorientiert und nicht darauf ausgelegt Pixel zu überspringen!

Es gibt ein Zell-Raster und ein Schritt-Raster. Das Schritt-Raster hat zur damaligen Zeit (Auflösung) direkt auf das Pixel-Raster gepasst. Das geht heute nicht mehr, sonst braucht man eine Lupe.
Zitat:

Zitat von himitsu (Beitrag 1297703)
Beim Programmablauf ist es seltener ein Problem, aber beim Debuggen wird es spassig, außer man debuggt schneller, als die Timer zuschlagen. :stupid:

Der Debugger müsste die Timer anhalten und um die Pausenzeiten verlängern. :cry:

Das kann man auch anders unterdrücken, indem man zwar die Zeiten berücksichtigt, aber egal wie lange der Zeit zwischen den Berechnungen gedauert hat, es werden maximal nur 2 Schritte berechnet.

himitsu 14. Apr 2015 16:30

AW: Pac-Man Hilfe
 
Diese Aussage bezog sich nur auf mehrere Timer. (noch ohne die Betrachtung einer Interpolation)

* Timer1 = 100 ms
* Timer2 = 500 ms

Timer1 müsste also 5 Mal so oft auslösen, wie Timer2,
aber wenn man jetzt mehr als 100 ms benötigt, zum Debuggen einer Methode (bis zum nächsten ProcessMessage), dann verschiebt sich das natürlich.

Oder besonders schön wird es, wenn man ProcessMessages im Code drin hat.
* Timer-Event benöigt 10 ms, das Timer-Intervall ist 100 ms
Das geht normaler Weise, wenn man jetzt debuggt und mehr als 100 ms bis zum ProcessMessages braucht, dann debuggt man sich in eine Endlosschleife, weil in dem ProcessMessages der Timer erneut ausgelöst wird, bevor das aktuelle Event fertig geworden ist.

mkinzler 14. Apr 2015 16:32

AW: Pac-Man Hilfe
 
Dann wäre es aber Aktion2 nur bei jedem 5. Durchlauf des Timers auszuführen

himitsu 14. Apr 2015 16:42

AW: Pac-Man Hilfe
 
Siehst'e ... also ist doch ein Timer besser als zwei/mehr Timer.
Somit haben wir den Beweis dafür. :stupid:

Popov 14. Apr 2015 21:38

AW: Pac-Man Hilfe
 
Pac-Man zu programmieren ist sowas von 1980. Sparrt euch die Arbeit, denn bald kommt der Pac-Man Film.

Hier der Trailer: https://www.youtube.com/watch?v=MAT0TpYMswI

Bjoerk 14. Apr 2015 21:45

AW: Pac-Man Hilfe
 
Schweinerei. PacMan ist nicht böse. :shock: :-D

Bjoerk 20. Apr 2015 12:54

AW: Pac-Man Hilfe
 
Zitat:

Zitat von Sir Rufo (Beitrag 1297691)
Zitat:

Zitat von Bjoerk (Beitrag 1297689)
Sieht nach einer Menge Timer aus?

Um genau zu sein, braucht man für die Bewegung einen Timer ;)

Zitat:

Zitat von himitsu (Beitrag 1297695)
Oder zwei Timer.
* Einer für die Bewegung
* und Einer für's Umschalten der Modi

Oder alles in einen Timer, mit der kleinsten nötigen Zeiteinheit (kleinster gemeinsamer Teiler) und dann bissl Mathematik (Zähler), um die größeren Zeiteinheiten rauszubekommen.

Zitat:

Zitat von DeddyH (Beitrag 1297701)
Aus eigener Erfahrung weiß ich, dass sich mehrere Timer gerne mal gegenseitig ins Gehege kommen. Dann lieber nur einen verwenden und ggf. ein wenig mehr rechnen.

Ich hab jetzt sogar eine Extra Komponente dafür erstellt. Ist vom Handling her dann einfacher ins Spiel zu integrieren.

Delphi-Quellcode:
unit uTimerEx;

interface

uses
  Math, Classes, ExtCtrls;

type
  TOnTimerExTimer = procedure(Timer: integer) of object;

  TTimerEx = class
  private
    FIntervall, FEnabled, FTickCount, FTimerTickCount: TList;
    FTimer: TTimer;
    FActive, FStoreActive: boolean;
    FOnTimerExTimer: TOnTimerExTimer;
    function GetCount: integer;
    function GetEnabled(Index: integer): boolean;
    function GetIntervall(Index: integer): integer;
    procedure SetActive(const Value: boolean);
    procedure SetEnabled(Index: integer; const Value: boolean);
    procedure SetIntervall(Index: integer; const Value: integer);
    function GetTickCount(Index: integer): integer;
    function GetTimerTickCount(Index: integer): integer;
    procedure SetTickCount(Index: integer; const Value: integer);
    procedure SetTimerTickCount(Index: integer; const Value: integer);
    property TickCount[Index: integer]: integer read GetTickCount write SetTickCount;
    property TimerTickCount[Index: integer]: integer read GetTimerTickCount write SetTimerTickCount;
    function GreatestCommonDivisor(A, B: integer): integer;
    function TimerIntervall: integer;
    procedure BeginUpdate;
    procedure EndUpdate;
    procedure TimerExTimer(Sender: TObject);
  public
    procedure Add(Intervall: integer = 1000; Enabled: boolean = true);
    procedure Delete(Index: integer);
    property Intervall[Index: integer]: integer read GetIntervall write SetIntervall;
    property Enabled[Index: integer]: boolean read GetEnabled write SetEnabled;
    property Active: boolean read FActive write SetActive;
    property Count: integer read GetCount;
    property OnTimerExTimer: TOnTimerExTimer read FOnTimerExTimer write FOnTimerExTimer;
    constructor Create;
    destructor Destroy; override;
  end;

implementation

{ TTimerEx }

constructor TTimerEx.Create;
begin
  FTimer := TTimer.Create(Nil);
  FTimer.Enabled := false;
  FTimer.OnTimer := TimerExTimer;
  FIntervall := TList.Create;
  FEnabled := TList.Create;
  FTickCount := TList.Create;
  FTimerTickCount := TList.Create;
end;

destructor TTimerEx.Destroy;
begin
  FActive := false;
  FTimer.Free;
  FIntervall.Free;
  FEnabled.Free;
  FTickCount.Free;
  FTimerTickCount.Free;
  inherited;
end;

procedure TTimerEx.Add(Intervall: integer = 1000; Enabled: boolean = true);
begin
  BeginUpdate;
  FIntervall.Add(Pointer(Intervall));
  if Enabled then
    FEnabled.Add(Pointer(1))
  else
    FEnabled.Add(Pointer(0));
  FTickCount.Add(Pointer(0));
  FTimerTickCount.Add(Pointer(0));
  EndUpdate;
end;

procedure TTimerEx.Delete(Index: integer);
begin
  BeginUpdate;
  FIntervall.Delete(Index);
  FEnabled.Delete(Index);
  FTickCount.Delete(Index);
  FTimerTickCount.Delete(Index);
  EndUpdate;
end;

function TTimerEx.GetCount: integer;
begin
  Result := FIntervall.Count;
end;

function TTimerEx.GetEnabled(Index: integer): boolean;
begin
  if Integer(FEnabled[Index]) = 1 then
    Result := true
  else
    Result := false;
end;

function TTimerEx.GetIntervall(Index: integer): integer;
begin
  Result := Integer(FIntervall[Index]);
end;

function TTimerEx.GetTickCount(Index: integer): integer;
begin
  Result := Integer(FTickCount[Index]);
end;

function TTimerEx.GetTimerTickCount(Index: integer): integer;
begin
  Result := Integer(FTimerTickCount[Index]);
end;

procedure TTimerEx.SetActive(const Value: boolean);
begin
  if Value then
  begin
    BeginUpdate;
    EndUpdate;
  end;
  FActive := Value;
  FTimer.Enabled := Value;
end;

procedure TTimerEx.SetEnabled(Index: integer; const Value: boolean);
begin
  if Value then
    FEnabled[Index] := Pointer(1)
  else
    FEnabled[Index] := Pointer(0);
end;

procedure TTimerEx.SetIntervall(Index: integer; const Value: integer);
begin
  BeginUpdate;
  FIntervall[Index] := Pointer(Value);
  EndUpdate;
end;

procedure TTimerEx.SetTickCount(Index: integer; const Value: integer);
begin
  FTickCount[Index] := Pointer(Value);
end;

procedure TTimerEx.SetTimerTickCount(Index: integer; const Value: integer);
begin
  FTimerTickCount[Index] := Pointer(Value);
end;

function TTimerEx.GreatestCommonDivisor(A, B: integer): integer;
var
  C: integer;
begin
  while B <> 0 do
  begin
    C := A mod B;
    A := B;
    B := C;
  end;
  Result := A;
end;

function TTimerEx.TimerIntervall: integer;
var
  I, J: integer;
begin
  Result := 1000;
  if Count = 1 then
    Result := Intervall[0]
  else
    if Count > 1 then
    begin
      Result := MaxInt;
      for I := 0 to Count - 2 do
        for J := I + 1 to Count - 1 do
          Result := Min(Result, GreatestCommonDivisor(Intervall[I], Intervall[J]));
    end;
  for I := 0 to Count - 1 do
    TickCount[I] := Intervall[I] div Result;
end;

procedure TTimerEx.BeginUpdate;
begin
  FStoreActive := FActive;
  FActive := false;
  FTimer.Enabled := false;
end;

procedure TTimerEx.EndUpdate;
var
  I: integer;
begin
  FTimer.Interval := TimerIntervall;
  for I := 0 to Count - 1 do
    TimerTickCount[I] := 0;
  FActive := FStoreActive;
  FTimer.Enabled := FStoreActive;
end;

procedure TTimerEx.TimerExTimer(Sender: TObject);
var
  I: integer;
begin
  FTimer.Enabled := false;
  try
    I := 0;
    while FActive and (I < Count) do
    begin
      TimerTickCount[I] := TimerTickCount[I] + 1;
      if TickCount[I] = TimerTickCount[I] then
      begin
        TimerTickCount[I] := 0;
        if Enabled[I] and Assigned(FOnTimerExTimer) then
          FOnTimerExTimer(I);
      end;
      Inc(I);
    end;
  finally
    if FActive then
      FTimer.Enabled := true;
  end;
end;

end.

Sherlock 20. Apr 2015 15:03

AW: Pac-Man Hilfe
 
Neugier: Wieso verwendest Du Pointer und nicht die Werte an sich?

Sherlock


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:18 Uhr.
Seite 6 von 9   « Erste     456 78     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz