Entwickler-Ecke
Multimedia / Grafik - [Delphi] 2D-Landschaft Schwerkraft
95CAHEK95 - Fr 07.09.12 12:14
Titel: [Delphi] 2D-Landschaft Schwerkraft
Hi Leute,
ich hoffe ich bin hier ihm richtigem Forum.
Ihr kennt doch bestimmt alle diese Spiel, wo 2 Panzer sich gegenseitig beschießen.
Ich habe so was ähnliches nach programmiert, doch komme jetzt bei einer Sache nicht wirklich weiter.
Und zwar will es so machen, dass die losen Pixel nach der Explosion runter fallen.
Hier ist meine Procedure dafür:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| PROCEDURE TForm1.Test (); VAR I, J, T: Integer; PFarbe: TColor; BEGIN FOR T := 1 TO 5 DO FOR I := ExKoord.X - 20 TO ExKoord.X + 20 DO FOR J := 1 TO ExKoord.Y + 20 DO BEGIN IF Landschaft.Canvas.Pixels [I, J] <> ClWhite THEN BEGIN PFarbe := Landschaft.Canvas.Pixels [I, J]; IF Landschaft.Canvas.Pixels [I, J + 1] = ClWhite THEN BEGIN Landschaft.Canvas.Pixels [I, J] := ClWhite;
Landschaft.Canvas.Pixels [I, J + 1] := ClRed; END; END; END; END; |
Die Prozedur funktioniert auch, doch mein Problem ist das wenn man t vergrößert fängt das Spiel an zu laggen.
Hat wer eine bessere Lösung für mein Problem?
Würde mich über jeden Tipp freuen.
Moderiert von Martok: Delphi-Tags hinzugefügt
Mathematiker - Fr 07.09.12 23:11
Hallo,
95CAHEK95 hat folgendes geschrieben : |
Die Prozedur funktioniert auch, doch mein Problem ist das wenn man t vergrößert fängt das Spiel an zu laggen. |
Nach Stupipedia gilt:
Zitat: |
Menschen, die älter sind als 4000 Jahre kennen das Wort "Laggen" nicht, wohl aber die Bedeutung, welche uns als soviel wie "Hängen" überliefert ist. |
Ich bin noch nicht ganz 4000 Jahre, aber fast, und vermute, dass Du verlangsamen/verzögern meinst?
Aus Deinem Text entnehme ich, dass Du für jedes T (41 x ExKoord.Y + 20) Punkte abfragst und eventuell änderst. Wie groß wird denn ExKoord.Y? Sollte es mehrere Hundert Pixel umfassen, ist die Verzögerung so kaum vermeidbar.
Ein einfacher Vorschlag: In einem Feld die Position der dargestellten Pixel merken und nur deren Position ändern. Das Abfragen des ganzen Darstellungsbereichs kostet Zeit.
Aber so nebenbei: 2 Panzer ( :puke: ), die aufeinander schießen?! :?!?:
Wer will denn solchen Schrott sehen?
Beste Grüße
Mathematiker
Boldar - Sa 08.09.12 19:45
Mathematiker hat folgendes geschrieben : |
Aber so nebenbei: 2 Panzer ( :puke: ), die aufeinander schießen?! :?!?:
Wer will denn solchen Schrott sehen?
Beste Grüße
Mathematiker |
naja, andere sind vielleicht von ständig neuen kontextlosen Mathematikfragen genervt. So doch jedem das Seine.
95CAHEK95 - So 09.09.12 14:22
ExKoord gibt die Koordinaten des Einschlages an. Also wenn das Geschoss vom Panzer die Landschaft trifft.
Und dann wird ein Ellipse, mit (ExKoord.X - 20, ExKoord.Y -20, ExKoord.X + 20, ExKoord.Y +20) an dieser Stelle, gezeichnet.
Könntest du dein Vorschlag mir bitte nochmal genauer erklären?
Verstehe nicht wie ich das anstellen soll.
Und unser Lehrer will es sehen ;)
Mathematiker - So 09.09.12 14:38
95CAHEK95 hat folgendes geschrieben : |
ExKoord gibt die Koordinaten des Einschlages an. Also wenn das Geschoss vom Panzer die Landschaft trifft.
Und dann wird ein Ellipse, mit (ExKoord.X - 20, ExKoord.Y -20, ExKoord.X + 20, ExKoord.Y +20) an dieser Stelle, gezeichnet.
Könntest du dein Vorschlag mir bitte nochmal genauer erklären? |
Nehmen wir an, dass Du 20 oder mehr Pixel verschieben möchtest. Dann wähle ich ein
Delphi-Quelltext
1:
| var punkte : array[1..20] of tpoint; |
In diesem speicherst Du die Anfangswerte (irgendetwas in Deiner Ellipse) Deiner Pixel, z.B.
Delphi-Quelltext
1: 2: 3: 4:
| for i:=1 to 20 do begin punkte[i].x:=exkoord.x-20 +irgendetwas; punkte[i].y:=exkoord.y-20 +irgendetwas; end; |
In einer Schleife (besser einem Timer) wird dann nur an den Stellen [punkte[i].x,punkte[i].y] die Hintergrundfarbe gesetzt, die y-Koordinate erhöht und am neuen Punkt die gewünschte Farbe gesetzt; bis zum Erreichen des Bodens.
Schön ist das nicht, aber wirksam. Da Du nur eine begrenzte Anzahl Punkte betrachtest, dürfte es schneller gehen, als die ganze Fläche zu testen.
95CAHEK95 hat folgendes geschrieben : |
Und unser Lehrer will es sehen ;) |
Aber hallo! Dein Lehrer will eine Explosion nach einem Panzerbeschuss als Programm sehen? Was ist denn das für eine Schule? :hair:
Beste Grüße
Mathematiker
Martok - So 09.09.12 15:02
Mathematiker hat folgendes geschrieben : |
95CAHEK95 hat folgendes geschrieben : | Und unser Lehrer will es sehen ;) |
Aber hallo! Dein Lehrer will eine Explosion nach einem Panzerbeschuss als Programm sehen? Was ist denn das für eine Schule? :hair: |
Vermutlich eine, in der Informatiklehrer schonmal irgendwann in ihrem Leben einen Computer benutzt haben (wow, sowas gibts? :shock:) und deswegen das gute alte
Scorched Tanks [
http://www.youtube.com/watch?v=P-9O1TOSfCM] vom Amiga kennen. Für die Jüngeren unter uns: Worms.
Grundsätzlich solltest du (
95CAHEK95) auf Canvas.Pixels[] verzichten (das ist furchtbar langsam). Sinnvoller ist es, die Landschaft in einem TBitmap zu halten und
nach den Berechnungen per Canvas.Draw auf die Ausgabe-Fläche zu malen.
TBitmap hat nämlich die Eigenschaft
SCANLINE, mit der du vieeel schneller auf Pixeldaten zugreifen kannst. 4000 Pixel (in deinem Beispiel) zu bearbeiten sollte damit nicht allzu lange dauern.
Mathematiker - So 09.09.12 15:53
Hallo Martok,
Schlechte Erfahrungen mit Informatiklehrern gemacht? :wink:
Martok hat folgendes geschrieben : |
Grundsätzlich solltest du (95CAHEK95) auf Canvas.Pixels[] verzichten (das ist furchtbar langsam). Sinnvoller ist es, die Landschaft in einem TBitmap zu halten und nach den Berechnungen per Canvas.Draw auf die Ausgabe-Fläche zu malen.
TBitmap hat nämlich die Eigenschaft SCANLINE, mit der du vieeel schneller auf Pixeldaten zugreifen kannst. 4000 Pixel (in deinem Beispiel) zu bearbeiten sollte damit nicht allzu lange dauern. |
Ich stimme Dir voll zu, vermute aber, dass 95CAHEK95 nun gar nicht mehr weiß, was er jetzt machen soll. Vielleicht kann er Deinem Link etwas entnehmen. Bleibt aber immer noch das Problem, wie er an das Bitmap kommt. Aber da gibt es ja
http://www.entwickler-ecke.de/viewtopic.php?t=97312&highlight=bitmap+verwenden
Beste Grüße
Mathematiker
95CAHEK95 - So 09.09.12 18:07
Danke für eure Tipps :)
Doch leider komm ich irgendwie mit Scanline nicht klar :(
Die Landschaft habe ich als eine BitMap gemacht. Und die RGB - Werte der Pixel auszulesen,
habe ich auch geschaft. Doch wie kann ich jetzt nur bestimmte Pixel weiss anmalen?
Also die sozusagen fallen zulassen :?: :?:
Martok - So 09.09.12 19:17
95CAHEK95 hat folgendes geschrieben : |
Und die RGB - Werte der Pixel auszulesen,
habe ich auch geschaft. Doch wie kann ich jetzt nur bestimmte Pixel weiss anmalen? |
Gebauso, wie du sie ausgelesen hast, nur andersrum. Der Einfachheit halber setze ich immer am Anfang das PixelFormat des Bitmaps auf pf32bit, also:
Delphi-Quelltext
1: 2: 3:
| var Landschaft: TBitmap; Landschaft.PixelFormat:= pf32bit; |
Das führt dazu, dass die Werte im passenden Format im Speicher liegen und wir uns nicht weiter drum kümmern müssen, das umzurechnen.
Wenn du jetzt den Pixel an (X, Y) bearbeiten willst, könntest du das so tun:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var SLine: PCardinal;
SLine:= Landschaft.ScanLine[Y]; inc(SLine, X);
if SLine^ = clWhite then SLine^:= clBlack; |
Der Einfachheit halber könntest du das auch in 2 Hilfsfunktionen verpacken:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| function GetPixel(Bitmap: TBitmap; X, Y: integer): TColor; var SLine: PCardinal; begin SLine:= Bitmap.ScanLine[Y]; inc(SLine, X); Result:= SLine^; end;
procedure SetPixel(Bitmap: TBitmap; X, Y: integer; Color: TColor); var SLine: PCardinal; begin SLine:= Bitmap.ScanLine[Y]; inc(SLine, X); SLine^:= Color; end; |
Die könntest du dann in deiner ursprünglichen Funktion statt den Zugriffen/Zuweisungen an Pixels verwenden und erstmal sehen, ob das vielleicht schon schnell genug ist.
Delphi-Quelltext
1:
| IF GetPixel(Landschaft, I, J) <> ClWhite then |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!