Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Programmoptimierung (https://www.delphipraxis.net/148646-programmoptimierung.html)

HansDampf43 5. Mär 2010 19:21


Programmoptimierung
 
Moin Community,

Also, ich arbeite derzeit an einer "Art" Pacman.
Das ganze sieht so aus: Man steuert ein Pacman durch die typische "Pacman" Karte und frisst Geister auf die dort zufällig herumlaufen.
Klappt eigentlich soweit auch alles.

Nun zu meinem Problem: bei etwas erhöhter Zahl von Geister, insbesondere bei Leistungsschwächeren Rechner fängt das Spiel schnell an zu ruckeln.

Dazu muss man sagen: ich war bislang beim programmieren froh WENN es geklappt hat, egal wie schön(ressourcen sparsam) es programmiert war. Meint also: mir ist bewusst dass das ganze ziemlich "hässlich" programmiert ist.

Also es funktioniert so, das die Geister auf einen Timer immer 1 pixel in eine richtung gehen, vor jeder Bewegung wird die procedure "Kollisionsabfrageg" gestartet.


Delphi-Quellcode:
procedure TForm1.KollisionsabfrageG;
var
l,r,i,v:integer;

begin
 if anzahl>0 then                //Anzahl=Anzahl der Geister
for i:=1 to anzahl do begin

  if existiert[i]=true then begin


   if geister[i].left<1 then
geister[i].left:=750;

if geister[i].left>750 then
geister[i].left:=-0;

if ((image1.canvas.pixels[Geister[i].left-1,geister[i].top] = RGBtocolor (0,0,255)))or                //Image1 ist das "hintergrundbild, also die Karte, die "Wände" sind blau
   ((image1.canvas.pixels[Geister[i].left-1,geister[i].top+29] = RGBtocolor (0,0,255)))               // 0,0,255
 then
 l:=1
 else
 l:=0;


if ((image1.canvas.pixels[geister[i].left+29,geister[i].top] = RGBtocolor (0,0,255)))or
   ((image1.canvas.pixels[geister[i].left+29,geister[i].top+29] = RGBtocolor (0,0,255)))
   then
   r:=1
   else
   r:=0;

if (l=0) and (r=0) then
kollisiong[i]:=false
else begin
kollisiong[i]:=true;
end;
if kollisiong[i]=true then begin
 if richtungg[i]=1 then geister[i].left:=geister[i].left-2;              
 if richtungg[i]=2 then geister[i].top:=geister[i].top+2;
 if richtungg[i]=3 then geister[i].left:=geister[i].left+2;
 if richtungg[i]=4 then geister[i].top:=geister[i].top-2;
   case richtungg[i] of
 1: case v of 0:richtungg[i]:=1; 1:richtungg[i]:=2; 2:richtungg[i]:=4;end;
 2: richtungg[i]:=random(3)+1;
 3: richtungg[i]:=random(3)+2;
 4: case v of 0:richtungg[i]:=1; 1:richtungg[i]:=3; 2:richtungg[i]:=4;end;
 end;

 end;
 end;
  end;
Gut also was ich gerne wissen möchte:

Habt ein paar tipps um ressourcen schonender zu programmieren ? Was sind wahre CPU Fresser ? Zufallszahlen ? Bilder laden etc ?
Habt ihr vielleicht sogar eine bessere Idee zur Realisierung ?

Wenn ihr noch Fragen habt, oder andere Programmteile sehen wollt, oder ich mich unverständlich ausgedrückt habe, sagt es mir bitte =)


Vielleicht kann ja jemand helfen :)
DAnke schonmal im vorraus =)

PS: Achja ich arbeite mit Lazarus

Medium 5. Mär 2010 21:50

Re: Programmoptimierung
 
:shock: Schick das ganze bitte noch mal durch einen Beautifiyer und stell's noch mal ein. So ist der Code ja unmöglich zu überblicken.

Coder 5. Mär 2010 23:00

Re: Programmoptimierung
 
nur Beauty.
Leider keinen Vorschlag.
Delphi-Quellcode:
procedure TForm1.KollisionsabfrageG;
var
  l, r, i, v: integer;

begin
  if anzahl > 0 then //Anzahl=Anzahl der Geister
    for i := 1 to anzahl do begin

      if existiert[i] = true then begin


        if geister[i].left < 1 then
          geister[i].left := 750;

        if geister[i].left > 750 then
          geister[i].left := -0;

        if ((image1.canvas.pixels[Geister[i].left - 1, geister[i].top] = RGBtocolor(0, 0, 255))) or //Image1 ist das "hintergrundbild, also die Karte, die "Wände" sind blau
          ((image1.canvas.pixels[Geister[i].left - 1, geister[i].top + 29] = RGBtocolor(0, 0, 255))) // 0,0,255
          then
          l := 1
        else
          l := 0;


        if ((image1.canvas.pixels[geister[i].left + 29, geister[i].top] = RGBtocolor(0, 0, 255))) or
          ((image1.canvas.pixels[geister[i].left + 29, geister[i].top + 29] = RGBtocolor(0, 0, 255)))
          then
          r := 1
        else
          r := 0;

        if (l = 0) and (r = 0) then
          kollisiong[i] := false
        else begin
          kollisiong[i] := true;
        end;
        if kollisiong[i] = true then begin
          if richtungg[i] = 1 then geister[i].left := geister[i].left - 2;
          if richtungg[i] = 2 then geister[i].top := geister[i].top + 2;
          if richtungg[i] = 3 then geister[i].left := geister[i].left + 2;
          if richtungg[i] = 4 then geister[i].top := geister[i].top - 2;
          case richtungg[i] of
            1: case v of 0: richtungg[i] := 1; 1: richtungg[i] := 2; 2: richtungg[i] := 4; end;
            2: richtungg[i] := random(3) + 1;
            3: richtungg[i] := random(3) + 2;
            4: case v of 0: richtungg[i] := 1; 1: richtungg[i] := 3; 2: richtungg[i] := 4; end;
          end;

        end;
      end;
    end;

Lumpiluk 5. Mär 2010 23:07

Re: Programmoptimierung
 
Zitat:

Zitat von Medium
Schick das ganze bitte noch mal durch einen Beautifiyer

Ist das jetzt metaphorisch gemeint oder gibt es sowas tatsächlich? :)

Zitat:

Habt ein paar tipps um ressourcen schonender zu programmieren ? Was sind wahre CPU Fresser ? Zufallszahlen ? Bilder laden etc ?
So oft werden hier Zufallszahlen jetzt nicht angewendet, dass das einen großen Unterschied machen sollte.
Mir wurde aber mal beigebracht, dass man Funktion des Programms und visuelle Ausgabe möglichst voneinander trennen sollte, also z.B. die Kollisionsabfrage nicht über Canvas.Pixels zu machen, sondern dafür die Daten aus einer zweidimensionalen Array nehmen...
Zum Laden der Bilder: Das kommt darauf an, ob du sie nur einmal am Anfang lädst oder in jedem OnPaint-Ereignis, und natürlich auf die Größe. Oder meinst du das Zeichnen auf die Canvas? Vor einigen Monaten hatte ich mal einen Moorhuhn-Klon geschrieben, der auf alten PCs auch sehr geruckelt hat. Nachdem ich den in OpenGL umgesetzt hatte, lief er aber dank Hardwarebeschleunigung sogar auf 10 jahre alten PCs ;) (in deinem Fall sollte es aber noch ohne OpenGL oder DirectX gehen).

Sir Rufo 5. Mär 2010 23:08

Re: Programmoptimierung
 
btw. Bitte nachsprechen: "Ich werde niemals wieder auf true oder false prüfen"
Delphi-Quellcode:
if Status = true then // das ist igitt
Delphi-Quellcode:
if Status then // das ist nicht nur kürzer
Gründe dafür kannst du hier im Forum nachlesen


Zitat:

Zitat von Lumpiluk
Zitat:

Zitat von Medium
Schick das ganze bitte noch mal durch einen Beautifiyer

Ist das jetzt metaphorisch gemeint oder gibt es sowas tatsächlich? :)

ja, Delphi 2010 - Code-Formatierer

Medium 6. Mär 2010 01:01

Re: Programmoptimierung
 
Von welchen Typ ist Geister[]?
Über wie viele Geister reden wir ca.?
Wie schnell ist der Timer?
Wie und worauf zeichnest du?
Warum das case nach dem genau die gleichen Prüfungen zuvor mit ifs schon gemacht wurden?
Und vor allem: Wo wird v je ein Wert zugewiesen?

HansDampf43 6. Mär 2010 09:47

Re: Programmoptimierung
 
Zitat:

Zitat von Medium
Von welchen Typ ist Geister[]?


Delphi-Quellcode:
 TGeist= class(Timage)
  constructor erzeugen;
  public
  end;


Zitat:

Zitat von Medium
Über wie viele Geister reden wir ca.?

25-30 etwa.
Es gibt auch noch "Geister" die pacman fressen, also von dem man ausweichen muss, sind im prinzip das gleiche.
Hab dafür ne neue Classe(auch timage) und neue Kollisionsabfrage, die genauso läuft nur das man ein leben verliert wenn man sie "frisst".



Zitat:

Zitat von Medium
Wie schnell ist der Timer?

100 MS

Zitat:

Zitat von Medium
Wie und worauf zeichnest du?

Ich zeichne eigentlich garnicht.
Ich lasse nur Images(Geister) auf Image1 bewegen,

Zitat:

Zitat von Medium
Und vor allem: Wo wird v je ein Wert zugewiesen?

sry den habe ich fälschlicherweise rauskopiert. Eigentlich stand da noch v:=random(2)+1

Zitat:

Zitat von Medium
Warum das case nach dem genau die gleichen Prüfungen zuvor mit ifs schon gemacht wurden?

Danke =) Das ist wirklich unsinnig und werde ich ändern.



So ich zeig euch nochmal die procedure Fressen, diese wird nach jeden pixel bewegung von "pacman" aufgerufen:

Delphi-Quellcode:
if anzahl>0 then

    for i:=1 to anzahl do begin

        if existiert[i]=true then begin

         if (((image2.left>geister[i].left) and (image2.left<geister[i].left+30)) and
            ((image2.top>geister[i].top) and (image2.top<geister[i].top+30))) or

            (((image2.left+26>geister[i].left) and (image2.left+26<geister[i].left+30)) and
            ((image2.top>geister[i].top) and (image2.top<geister[i].top+30))) or

            (((image2.left+26>geister[i].left) and (image2.left+26<geister[i].left+30)) and
            ((image2.top+26>geister[i].top) and (image2.top+26<geister[i].top+30))) or

            (((image2.left>geister[i].left) and (image2.left<geister[i].left+30)) and
            ((image2.top+26>geister[i].top) and (image2.top+26<geister[i].top+30))) then

            begin


            geister[i].free;
            existiert[i]:=false;
            end;
         end;

  end;

end;

DeddyH 6. Mär 2010 10:06

Re: Programmoptimierung
 
Holla, da sind aber ein paar Haken drin. Der Konstruktor von TImage (und allen anderen Klassen) heißt Create, das solltest Du unbedingt einhalten.
Delphi-Quellcode:
TGeist= class(Timage)
  public
    constructor Create(aOwner: TComponent);override;
  end;
Die If-Abfrage vor der for-Schleife kannst Du Dir sparen, da letztere bei Werten < 1 gar nicht durchlaufen wird. Dann wurde bereits gesagt, dass man nicht mit true vergleicht. Außerdem könntest Du ggf. noch subtrahieren und mit in vergleichen, da muss man aber aufpassen, dass man im Bereich von 0 bis 255 bleibt. Und dann machst Du einige Vergleiche doppelt, das könntest Du in Subroutinen verschieben.

Wannebee 7. Mär 2010 10:21

Re: Programmoptimierung
 
Wobei man sagen muss das Subroutinen/Funktionen nicht immer schneller sind (zumindest bei D7 nicht). Da hatte ich irgendwie mal einen Zeitgewinn dadurch, dass ich den Code 2x geschrieben habe, anstatt dafür ne Funktion (wie ich es ursprünglich auch gedacht hatte).

lg
Wannebee

DeddyH 7. Mär 2010 13:07

Re: Programmoptimierung
 
Mir ging es nicht um Zeitgewinn, sondern um Übersichtlichkeit und Wartbarkeit.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:42 Uhr.
Seite 1 von 2  1 2      

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