AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Hintergrundbild erstellen

Ein Thema von VkPenguin · begonnen am 13. Feb 2012 · letzter Beitrag vom 26. Feb 2012
Antwort Antwort
Popov
(Gast)

n/a Beiträge
 
#1

AW: Hintergrundbild erstellen

  Alt 17. Feb 2012, 19:40
Als ich DeddyHs Link oben gelesen habe, ist mir noch eine andere Methode eingefallen mit der ich auch leicht experimentiert habe. Sie ist ein Zwischending zwischen dem was ich bereits oben beschrieben habe, also alles zuerst auf eine temporäre Bitmap zeichnen und dann das gesamte Ergebnis auf die Leinwand zeichnen, und eine Lochmaske aus Regionen, was etwas komplexer wäre.

Hier ein Beispiel mit den Hausmitteln von Delphi, anhand eines Balls der sich über einen Hintergrund bewegt. Beim zeichnen wird der alte Bereich vom letzten Schritt als Rect-Bereich gespeichert, der neue Bereich, auch als Rect-Bereich. Dann wird der kleinste gemeinsamer Rect-Bereich berechnet. Alles was gezeichnet wird, wird auf diesem gemeinsamen Bereich auf der Temporärbitmap gezeichnet. Dann wird das Ergebnis übertragen. Der Vorteil hier, es wird nur das gezeichnet was sich verändert hat. Allerdings wird hier grob gearbeitet, d. h. die kleinste gemeinsame Fläche, aber auf dieser eben alles.

Auch wenn das nicht die versprochene Lochmaske ist, so ist es das Prinzip. Zerst den alten Bereich reparieren, dann das Neue zeichnen, Ergebnis übertragen.

Delphi-Quellcode:
    //das Alte merken
    RecAlt := Rect(x, y, x+Bmp.Width, y+Bmp.Height);

    ...

    //das Neue berechnen
    RecNeu := Rect(x, y, x+Bmp.Width, y+Bmp.Height);
    //kleinste gemeinsame Fläche ermitteln
    UnionRect(RecZusammen, RecAlt, RecNeu); //!Bool Funktion, Abfrage?
    //auf Temporärgrafik arbeiten
    TBmp.Canvas.CopyRect(RecZusammen, HBmp.Canvas, RecZusammen);
    TBmp.Canvas.Draw(x, y, Bmp);
    //Ergebnis übertragen
    Canvas.CopyRect(RecZusammen, TBmp.Canvas, RecZusammen);
Das ist auch eine Antwort auf deine Frage, Vergiss das Scannen und die Zwischenablage. Warum Zwischenablage wenn du das, was du kopieren möchtest, in einer Variable speichern kannst. Und warum den alten Bereich scannen, nimm doch gleich die Quelle.
Angehängte Dateien
Dateityp: zip BallTest.zip (293,4 KB, 9x aufgerufen)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#2

AW: Hintergrundbild erstellen

  Alt 18. Feb 2012, 20:20
Hmm, vielen lieben Dank für Deine Mühe, aber irgendwie komme ich mir gerade schrecklich Dumm vor. Verstehe ich das richtig (Auf mein Problem übertragen):

- RecAlt ist die vohrige Position des Gegners bzw. der Rahmen darum (dafür müsste ich doch zuvor einmal den Gegner erst zeichnen oder nicht?)
- RecNeu ist die neue Position
- RecZusammen ist die Mischung aus RecNeu und dem Hintergrund (Aber wie funktioniert das Mischen? Woher weiß das Programm denn was wohin soll? Die Transparenzoptionen gehen doch im BMP-Format verloren, oder nicht? Deswegen benutzt ich ja PNG mit Transparenz)
- x ist die X-Position des Gegners
- Y " " Y- " " "
- BMP ist das Bild des Gegners (ist bei mir PNGImage, das macht aber nichts, oder?)
- TBMP ist das temporäre BMP
- HBMP ist das Hintergrundbild

Und ich müsste das ganze dann also mit *Pseudocode*
Delphi-Quellcode:
For I:=1 to Gegneranzahl Do
Begin
Altes merken
Neue Position berechnen
"verschieben"
End;
machen..? Das kann so doch nicht funktionieren ?! Bin ratlos
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#3

AW: Hintergrundbild erstellen

  Alt 18. Feb 2012, 21:31
Ich glaube PNG ist ganz schlecht für ein Spiel bei dem es um Geschwinigkeit geht, dann egal welches Format man auch Windows anbietet, wenn es auf den Bildschirm kommt, ist es eine Bitmap. D. h. wenn man PNG nutzt, wird sie intern konvertiert. Sind es viele Grafiken, wird viel konvertiert. Und wenn man man 60 Durchläufe pro Sekunde hat, und hier bin ich mir nicht sicher ob das intern nur ein mal konvertiert wird oder bei jedem Aufruf, dann ist es viel Rechenarbeit.

Dabei geht es doch einfach, denn Bmp beherrscht auch die Transparenz. Einfach die transparente Farbe wählen, Transparent auf True setzten und gut ist es. Für ein Spiel ist Bmp immer vorzuziehen.

Nun zu deiner Frage: das was ich dir angeboten habe ist nicht die versprochene Lochmaske. Ich finde die alten Daten nicht mehr. Also habe ich so eine Art Lochmaske light programmiert.

Hier arbeite ich mit Rect-"Regionen" (keinen Windows-Rgn-Regionen). Noch bevor die neue Position berechnet und gezeichnet wird, wird aus den alten Werten, also die alte Region in der sich der Ball zuletzt befand, die Rect-Region als RecAlt gespeichert. Dann folgen die Berechnungen und ich berechne die Position in die gleich gezeichnet wird. Das ist die RecNeu. Nun berechne ich aus den beiden Werten den kleinsten gemeinsamen Rect-Rechteck. Nun wird per CopyRect der Hintergrund an der Stelle gezeichnet, also nicht der ganze Hintergrund, sondern nur das Rechteck. Dann wird der Ball in das Rechteck gezeichnet. Jetzt übertrage ich das Rechteck, wieder über CopyRect auf die entgültige Leinwand.

TmpBitmap dient hier nur zum arbeiten. Ich zeichne alles zuerst TmpBitmap und übertrage den kleinen Teil der geändert wurde auf die entgültige Leinwand.

Wieso der Umstand? Wenn ich zwei Bilder auf die gleiche Stelle (Hintergrund und Ball) nacheinander direkt auf die endgültige Leinwand zeichne, dann merkt man das durch flackern. Es wird zuerst das eine Bild gezeichnet und gleich danach das zweite. Auch wenn das schnell geht, man erkennt es. Also wird beides zuerst auf eine TmpBitmap gezeichnet und nur ein Bild wird kopiert.

Als du paar Posts weiter oben geschrieben hast, dass es immer noch flackert, da habe ich ein Test gemacht. Zuletzt habe ich 2000 Objekte über eine TmpBitmap gezeichnet, geflackert hat es nicht. Das Ganze ist in die Knie gegangen, so dass zuletzt die Leinwand nur noch zwei Bilder pro Sekunde erneuert wurde, also es ruckelte, aber geflackert hat es nicht.

Nun zum Nachteil der oberen Methode. Sie arbeitet immer mir dem kleinsten gemeinsamen Rechteck. Wenn aber auf dem ganzen Bildschirm sich Raumschiffe befinden dann wird schnell die ganze Leinwand zum Rechteck. Dann kann man sich auch das Berechnen sparen. Um die TmpBitmap kommst du aber nicht drumherum.
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#4

AW: Hintergrundbild erstellen

  Alt 18. Feb 2012, 21:52
Zunächst nocheinmal vielen Dank, dass du soviel Geduld mit mir hast, soetwas trifft man selten... Gebe mir auch Mühe

Also eins nach dem anderen: Wenn das so ist, ist BMP natürlich besser, das ist einleuchtend. Aber wenn ich mein *.png-Bild als .bmp speichern will bekomme ich die Warnmeldung: "Beim Speichern geht die Transparenz verloren. Fortfahren?", deshalb bin ich bisher davor zurückgeschreckt. Und wenn ich einfach Transparent:=True sage, woher will die Bitmap dann wissen, welcher Bereich Transparent war, wenn eben das doch verlorengegangen ist? Und - entschuldige die wahrscheinlich Dumme Frage, aber wieso soll ich eine Farbe für etwas Transparentes auswählen? Ich meine, es soll doch durchsichtig sein...?!
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#5

AW: Hintergrundbild erstellen

  Alt 18. Feb 2012, 22:59
Bei der Bitmap funktioniert es mit der Transparenz so: du mußt eine Farbe opfern, die wird dann durchsichtig dargestellt. In der Praxis wird in der Regel clFuchsia genommen, man kann aber beliebige Farbe nehmen. Eingestellt wird die Farbe über Bitmap.TransparentColor := ... , dann noch Bitmap.Transparent := True setzen.

Diese Methode ist vorzuziehen, denn hier hast du die Kontrolle über die Transparente Farbe. Wenn ich mir unsicher bin welche Farbe es ist, dann mache ich es so: Bitmap.TransparentColor := Bitmap.Canvas.Pixels[0, 0]; . Hier wird erste Farbe oben links genommen. Das ist aber fast das Gleiche wie Bitmap.TransparentMode := tmAuto . Hier erkennt das System die Farbe automatisch in dem es die Pixelfarbe unten links als transparent annimmt. Wenn du also mit TransparentMode und tmAuto arbeitest, brauchst du keine Farbe zuweisen. Prüfe aber ob die Farbe korrekt erkannt wurde.
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#6

AW: Hintergrundbild erstellen

  Alt 18. Feb 2012, 23:19
So, habe mal mit der Umstellung auf Bitmaps angefangen, es gibt da aber ein Problem: Das Programm läuft tatsächlich deutlich flüssiger und ohne flackern, aber nur solange ich
Delphi-Quellcode:
// MobPIC.TransparentColor:=MobPiC.Canvas.Pixels[0,0];
//MobPIC.Transparent:=True;
die "//" Zeichen stehen lasse. Wenn ich den Transparenzmodus aktiviere fallen die FPS von über 60 auf 0.5. Weißt Du, woran das liegen könnte?

*Edit* Die Darstellung ist dann aber übrigens richtig, also es ist nur das Gegnerraumschiff sichtbar, der Rest des Rechtecks ist schwarz, wie es erstmal sein soll.
*Edit2* Um genau zu sein ist es die //MobPIC.Transparent:=True; Zeile, die den Unterschied ausmacht, egal, was mit der anderen ist

Geändert von VkPenguin (18. Feb 2012 um 23:23 Uhr)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#7

AW: Hintergrundbild erstellen

  Alt 18. Feb 2012, 23:42
Nun, mit Transparenz ist mehr zu rechnen. Ohne wird zeilenweise kopiert, bei Transparenz muß, auch wenn das nicht viel Leistung in Anspruch nimmt, jeder Pixel überprüft werden.

Aber ich kann mir das kaum vorstellen. Ich habe gerade 500 teil-transparente Objekte getestet, da bin ich auf 21 FPS runter und es ruckelt. Bei 300 Objekten bin ich über 30 und es läuft flüssig. Die Geschwindigkeit ist zwar runter, aber es ist flüssig.

Wie viel Raumschilfe hast du denn?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:17 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