Autor Beitrag
95CAHEK95
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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:

ausblenden 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 //T steht für dich Anzahl der Schichten die runterfallen 
     FOR I := ExKoord.X - 20 TO  ExKoord.X + 20 DO // Bei den ExKoord.X und Y wird eine Ellipse gezeichnet
         FOR J := 1 TO ExKoord.Y + 20 DO
         BEGIN (* FOR J *)
              IF Landschaft.Canvas.Pixels [I, J] <> ClWhite
                 THEN
                     BEGIN (* IF <> ClWhite *)
                          PFarbe := Landschaft.Canvas.Pixels [I, J];
                          IF Landschaft.Canvas.Pixels [I, J + 1] = ClWhite
                             THEN
                                 BEGIN (* IF = ClWhite *)
                                 Landschaft.Canvas.Pixels [I, J] := ClWhite;

                                 Landschaft.Canvas.Pixels [I, J + 1] := ClRed;
                                 END(* IF = ClWhite *)
                     END(* IF <> ClWhite *)
         END(* FOR J *)
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 user profile iconMartok: Delphi-Tags hinzugefügt
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 07.09.12 23:11 
Hallo,
user profile icon95CAHEK95 hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Sa 08.09.12 19:45 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:

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.

Für diesen Beitrag haben gedankt: FinnO
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 08.09.12 22:10 
user profile iconBoldar hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 09.09.12 14:38 
user profile icon95CAHEK95 hat folgendes geschrieben Zum zitierten Posting springen:
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
ausblenden Delphi-Quelltext
1:
var punkte : array[1..20of tpoint;					

In diesem speicherst Du die Anfangswerte (irgendetwas in Deiner Ellipse) Deiner Pixel, z.B.
ausblenden 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.
user profile icon95CAHEK95 hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 09.09.12 15:02 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
user profile icon95CAHEK95 hat folgendes geschrieben Zum zitierten Posting springen:
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 vom Amiga kennen. Für die Jüngeren unter uns: Worms.


Grundsätzlich solltest du (user profile icon95CAHEK95) 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 Suche in: Delphi-Forum 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 09.09.12 15:53 
Hallo Martok,
user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
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 vom Amiga kennen.

Schlechte Erfahrungen mit Informatiklehrern gemacht? :wink:

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Grundsätzlich solltest du (user profile icon95CAHEK95) 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 Suche in: Delphi-Forum 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 www.entwickler-ecke....ght=bitmap+verwenden

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
95CAHEK95 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 09.09.12 19:17 
user profile icon95CAHEK95 hat folgendes geschrieben Zum zitierten Posting springen:
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:
ausblenden 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var SLine: PCardinal;
//...

//Zeile holen, SLine Zeigt dann auf das erste Pixel der Zeile.
SLine:= Landschaft.ScanLine[Y];
//zum Pixel "spulen", d.h. "verschiebe SLine X-mal weiter"
inc(SLine, X);

//SLine ist ein Zeiger, d.h. es enthält nicht den Wert selber, sondern die Stelle im Speicher
//an der sich der (Farb)Wert befindet.
//Wir wollen aber den Wert erhalten/bearbeiten, müssen den Zeiger "de-referenzieren". Das macht der ^ -Operator.
if SLine^ = clWhite then
  SLine^:= clBlack;


Der Einfachheit halber könntest du das auch in 2 Hilfsfunktionen verpacken:
ausblenden 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.
ausblenden 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