Autor |
Beitrag |
95CAHEK95
Hält's aus hier
Beiträge: 6
|
Verfasst: Fr 07.09.12 12:14
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
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: 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 ( ), die aufeinander schießen?!
Wer will denn solchen Schrott sehen?
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Boldar
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Sa 08.09.12 19:45
Für diesen Beitrag haben gedankt: FinnO
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Sa 08.09.12 22:10
Boldar hat folgendes geschrieben : | naja, andere sind vielleicht von ständig neuen kontextlosen Mathematikfragen genervt. So doch jedem das Seine. |
Dass Du Mathematik kontextlos findest, naja, ist lustig und ich kann damit leben. Das hilft aber 95CAHEK95 nicht weiter. Ich habe es wenigstens versucht.
Aber "Jedem das Seine"?? Ein paar Links für Deine Weiterbildung:
www.hollbeck.net/2012/07/jedem-das-seine/
www.spiegel.de/schul...-seine-a-612757.html
www.sopos.org/aufsae...c7d45aeb2e57/1.phtml
Solltest Du meinen "Jeder soll das programmieren, was er gern möchte!", dann sag es auch und ich stimme Dir zu! Aber nicht so!
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
95CAHEK95
Hält's aus hier
Beiträge: 6
|
Verfasst: 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
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: 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?
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Martok
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: 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? |
Vermutlich eine, in der Informatiklehrer schonmal irgendwann in ihrem Leben einen Computer benutzt haben (wow, sowas gibts? ) und deswegen das gute alte Scorched Tanks 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.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Für diesen Beitrag haben gedankt: FinnO
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: So 09.09.12 15:53
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
95CAHEK95
Hält's aus hier
Beiträge: 6
|
Verfasst: 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
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: 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 |
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Für diesen Beitrag haben gedankt: 95CAHEK95
|
|
|