![]() |
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:
Gut also was ich gerne wissen möchte:
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; 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 |
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.
|
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; |
Re: Programmoptimierung
Zitat:
Zitat:
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). |
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:
Gründe dafür kannst du hier im Forum nachlesen
if Status then // das ist nicht nur kürzer
Zitat:
|
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? |
Re: Programmoptimierung
Zitat:
Delphi-Quellcode:
TGeist= class(Timage)
constructor erzeugen; public end; Zitat:
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:
Ich lasse nur Images(Geister) auf Image1 bewegen, Zitat:
Zitat:
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; |
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:
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.
TGeist= class(Timage)
public constructor Create(aOwner: TComponent);override; end; |
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 |
Re: Programmoptimierung
Mir ging es nicht um Zeitgewinn, sondern um Übersichtlichkeit und Wartbarkeit.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:04 Uhr. |
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