Programm wie Space Invaders

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...

Programm wie Space Invaders

Beitragvon navyseabear » 21. Jan 2018, 19:58 Programm wie Space Invaders

Moin moin,
ich möchte gerne ein Lernprogramm für Kinder schreiben, bei dem ich eine Linie benötige, welche ich von einem Objekt zu einem anderen Objekt zeichne. Die Objekte sind beweglich und ändern ihre Position ständig.
Das zeichnen der Linie ist ja soweit ganz einfach mit
Code: Alles auswählen
.Canvas.MoveTo(X,Y)
und
Code: Alles auswählen
.Canvas.LineTo(X,Y)
.
Wie aber kann ich diese Linie nun wieder löschen und zwar nur die Linie?
Ich habe im Hintergrund ein Bitmap und andere kleinere Grafiken welches für die Erklärung des Vorgangs wichtig sind. Dies sollte und muss auch erhalten bleiben.
Gibt es eine Möglichkeit das einfach und unkompliziert hin zu bekommen?
Wenn ich die alte Linie mit einer anderen Farbe überzeichne ist mein Hintergrund beschädigt. Ähnlich ist es wenn ich ein Rechteck über den gesamten Bereich zeichne.
Es muss doch eine einfache und schnelle Methode geben, da ich ja auch Dinge wie z.B. ein Label durch Änderung der Left und Top Werte einfach so über mein Bitmap schieben kann, ohne das der Hintergrund dabei beschädigt wird.

mfg
Tobias
navyseabear
 
Beiträge: 5
Registriert: 21. Jan 2018, 09:27

Beitragvon theo » 21. Jan 2018, 20:13 Re: Programm wie Space Invaders

Kopiere einfach immer alles neu auf den Bildschirm, auch den Hintergrund.
Das ist schnell genug.
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon Mathias » 21. Jan 2018, 20:18 Re: Programm wie Space Invaders

Die einzige Lösung wird sein, im Repaint-Ereigniss als neu zu zeichnen.
Auf diese Art und Weise sind die meisten Programme aufgebaut.

Wen es waagrechte und senkrechte Linien sind, könntest du das ganze evtl. mit einer TShape umgehen.

So nebenbei kann man eine Linie mit einem Befehl zeichnem.
Code: Alles auswählen
Canvas.Line(x1, y1, x2, y2);


Ich habe im Hintergrund ein Bitmap und andere kleinere Grafiken welches für die Erklärung des Vorgangs wichtig sind.

Wie bringst du dies Bitmaps auf den Schirm ?

Es muss doch eine einfache und schnelle Methode geben, da ich ja auch Dinge wie z.B. ein Label durch Änderung der Left und Top Werte einfach so über mein Bitmap schieben kann,

ZB. ein Label, auch andere Komponenten, werden immer in einem Repaint-Ereigniss neu gezeichnet. ZB wen es vorher von einem anderen Fenster verdeckt war.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon fliegermichl » 23. Jan 2018, 07:11 Re: Programm wie Space Invaders

Hallo,
Es gibt zwei Möglichkeiten. Die erste ist einfach.

Code: Alles auswählen
 
procedure ZeichneLinie(x1, y1, x2, y2 : integer);
begin
 Canvas.Draw(0, 0, bmp);       // Überzeichnen mit dem Hintergrund (davon ausgehend, daß die Grafik in bmp so groß wie die zu bemalende Fläche ist)
 Canvas.Line(x1, y1, x2, y2);
end;
 


Für eine oder wenige Linien ist das absolut ausreichend. Wenn es aber viele Linien sind und evtl. deren Positionen zwischendurch ermittelt werden sollen usw. wird diese Art irgendwann ruckelig und der Anwender kann sehen, wie die Linien nacheinander gezeichnet werden. Dann kann man eine zweite Bitmap zu Hilfe nehmen und zunächst für den Anwender unsichtbar, da seine Linien rein zeichnen.
Wenn das erledigt ist, wird der Inhalt der Hilfsbitmap mit einem Kopiervorgang auf den Bildschirm gebracht.

Auch da kann man noch etwas optimieren, indem man anstelle von TCanvas.Draw die Systemfunktion BitBlt (aus LCLIntF) verwendet.

Code: Alles auswählen
 
procedure Zeichne1MioLinien(const a : array of TRect); // Die Linien werden immer von a.TopLeft nach a.BottomRight gezeichnet
var bmp2 : TBitmap;
     i : integer;
begin
 bmp2 := TBitmap.Create;
 try
   bmp2.width := bmp.Width;
   bmp2.Height := bmp.Height;
   BitBlt(bmp2.Canvas.Handle, 0, 0, bmp.width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY); // Zeichnet (zunächst unsichtbar) den Hintergrund aus bmp in bmp2
 
   // Jetzt werden die Linien in bmp2 gezeichnet. Das ist für den Anwender ebenfalls unsichtbar
   for i := Low(a) to High(a) do Canvas.Line(a[i].TopLeft, a[i].BottomRight);
 
   // Jetzt wird die fertige Grafik aus bmp2 auf einen Schlag auf den Bildschirm kopiert
 
  BitBlt(Canvas.Handle, 0, 0, bmp2.Width, bmp2.Height, bmp2.Canvas.Handle, 0, 0, SRCCOPY);
 finally
  bmp2.Free;
 end;
end;
 


Viele Grüße
Michael
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon kupferstecher » 23. Jan 2018, 08:32 Re: Programm wie Space Invaders

TBitmap kennt doch auch Transparenz, oder? Dann einfach den Hintergrund in eine Bitmap und darueber die Linien auf eine transparente Bitmap zeichnen.
kupferstecher
 
Beiträge: 165
Registriert: 17. Nov 2016, 11:52

Beitragvon fliegermichl » 23. Jan 2018, 09:03 Re: Programm wie Space Invaders

kupferstecher hat geschrieben:TBitmap kennt doch auch Transparenz, oder? Dann einfach den Hintergrund in eine Bitmap und darueber die Linien auf eine transparente Bitmap zeichnen.


Kannst du das näher erläutern an einem Beispiel? Ich kann mir grad nicht so recht vorstellen was du meinst.
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon pluto » 23. Jan 2018, 09:39 Re: Programm wie Space Invaders

Ich habe sowas mal für ein Projekt gebraucht und habe nicht immer alles neu gezeichnet sondern nur das was sich geändert hat:
Ich hatte ein Buffer Bitmap.
Ich hatte Objekte/Klassen.

Und im Prinzip kann man jetzt folgendes machen:
1. Du Zeichnest, dann wird einfach zu erst an der "alten" Position der Entsprechende Teil von der Buffer Bitmap gezeichnet.
2. Nun Zeichnest du das "Eigentliche" Objekt.

Problem ist hier bei "nur", wenn sich die Objekte überlagern können, entstehen Grafikfehler....
Also habe ich als letzten Schritt einfach, alle Objekte die in der Nähe waren einfach auch neu gezeichnet....
Das klappte recht gut und ich muss nicht immer alles neu zeichnen sondern nur kleine Teile.
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
 
Beiträge: 6702
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon Mathias » 23. Jan 2018, 13:43 Re: Programm wie Space Invaders

Wen man es ganz profesionel lösen will, dann wäre OpenGL für sowas gut geeignet.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon corpsman » 23. Jan 2018, 16:11 Re: Programm wie Space Invaders

Ich habe zum "einfachen" Lernzweck mal Greenfoot nach Lazarus portiert (oder zumindes Teile)
Den DL gibt es hier: https://corpsman.de/index.php?doc=schule/greenfoot

das ganze nutzt OpenGL und die Original Javadokumentation ist echt gut. Evtl reicht dir das auch schon, ich meine da ist auch ein Space Invaders Sample mit dabei ;).
--
Just try it
corpsman
 
Beiträge: 1055
Registriert: 28. Feb 2009, 08:54
Wohnort: Stuttgart
OS, Lazarus, FPC: Kubuntu 14.04, Lazarus SVN Trunk, FPC 3.0 | 
CPU-Target: 32Bit
Nach oben

Beitragvon navyseabear » 26. Jan 2018, 23:21 Re: Programm wie Space Invaders

Hallo,

ich habe nun ein wenig experimentiert und habe folgendes soweit geschafft.
Ich habe ein Form, auf das ich ein TImage mit Align als alClient gesetzt habe. Dieses lädt zu Programmbeginn ein Bitmap aus einer TImageList
Code: Alles auswählen
ImageList1.GetBitmap(0,ImageHintergrund.Picture.Bitmap);

Ein zweites TImage liegt über dem ersten und wird ebenfalls, hier nur mit Hilfe des Zufallsgenerators, mit einer kleinen Raketengrafik geladen.
Code: Alles auswählen
ImageList2.GetBitmap(Random(ImageList2.Count ),ImageRakete.Picture.Bitmap);

Die Raketengrafik bewegt sich nun mit Hilfe eines Timers über den Bildschirm.
Ich gebe hier zu beachten, dass es sich um ein Lernprogramm für Kinder handelt, bei dem es nicht unbedingt auf super tolle Animationen und dergleichen ankommt.
Leider bewegt sich mein RaketenImage nun extrem langsam über den Bildschirm. Lade ich hingegen das Hintergrundbild nicht ein, bzw. zeige es nicht an, "fliegt" meine Rakete in einem recht ordentlichem Tempo über den Bildschirm.
Wie aber bekomme ich eine flüssige Bewegung der Rakete hin, auch wenn ich ein Hintergrundbild geladen habe?

mfg
Tobias
navyseabear
 
Beiträge: 5
Registriert: 21. Jan 2018, 09:27

Beitragvon Mathias » 27. Jan 2018, 00:01 Re: Programm wie Space Invaders

Da kann ich nur OpenGL empfehlen.
Ein Hintergrundbild und ein paar Sprites sind einfach gemacht.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon navyseabear » 28. Jan 2018, 10:11 Re: Programm wie Space Invaders

Moin moin,

vielen Dank erst einmal für alle Ratschläge und Infos.
Leider bin ich aber immer noch nicht richtig weiter gekommen.
Ich habe versucht mich mit OpenGL zu beschäftigen, aber entweder bin ich zu blöd dazu oder ich kapiere es einfach nicht.
Ich verstehe einfach nicht wie ich
a) ein einfaches Hintergrundbild einlade und anzeige und
b) darauf ein Sprite erzeuge welches ich hin und her bewegen kann
OpenGL ist ja in erster Linie für 3D-Anwendungen gedacht, vielleicht sind mir deswegen die Beispiele die ich gefunden habe einfach zu komplex und und zu kompliziert.
Wenn OPenGL so einfach ist, wo kann ich den dann ein einfaches Beispiel für einen Hintergrund mit einem oder mehreren Sprites finden?

Mein klassischer Ansatz mit TImage funktioniert ganz gut, ist aber halt extrem langsam wenn ich mein zweites TImage auf dem ersten bewege. Solange nur ein einfacher Standardhintergrund da ist, bewegt es sich recht flott.

Brauch echt Hilfe im Moment, da ich wie man so schön sagt: "Lost in Space bin"

mfg
Tobias
navyseabear
 
Beiträge: 5
Registriert: 21. Jan 2018, 09:27

Beitragvon Mathias » 29. Jan 2018, 18:20 Re: Programm wie Space Invaders

Wenn OPenGL so einfach ist, wo kann ich den dann ein einfaches Beispiel für einen Hintergrund mit einem oder mehreren Sprites finden?

Ich habe da ein kleines Musterprogramm
http://mathias1000.bplaced.net/test/Spa ... ers.tar.gz

Von hier wird noch der Ordner Unit gebraucht.
Am besten dort die Pakage installieren.

https://github.com/sechshelme/Lazarus-O ... 3-Tutorial

Ich hoffe, das dir dies als Basis reicht.
Ansonsten weiter fragen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Multimedia



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried