|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Cyberprince Mini JLI'ler
Anmeldedatum: 14.01.2009 Beiträge: 7
Medaillen: Keine
|
Verfasst am: 14.01.2009, 14:26 Titel: Kollision per Farbe? |
|
|
Hi,
ich bin gerade dabei ein kleines Spiel (2D)zu programmieren (mit Direct3D).
Bei diesem Spiel fliegt ein Helikopter(ein geladenes Sprite) durch eine Höhle. Was heißt, nicht der Helikopter fliegt, sondern der Hintergrund scrollt weiter. Der Hintergrund ist ein Bild mit 6144px*768px. Der Aktuelle Teil des Bildes wird in einem Surface gespeichert und auf den Backbuffer kopiert. Aus dem Boden ragen schwarze Felsbrocken, und ich wollte wissen ob es irgendeine Methode gibt, zu erkennen, ob der Helikopter diese schwarzen Steine berührt hat. So etwas habe ich noch nie gemacht, weil ich bis jetzt immer nur Kollisionen zwischen zwei Sprites gemacht habe. Da im Bild nichts anderes schwarz ist, als die Steine reicht es zu erkennen, ob der Helikopter einen schwarzen Pixel berührt hat. Geht so etwas?
Wenn ja, wie funktioniert es?
Hier einmal ein Ausschnitt des Bildes:
Ich habe gedacht es gibt vielleicht eine Methode die Farbe der Pixel des aktuellen Frontbuffers zu erfragen, und dann zu überprüfen ob das Sprite (der Helikopter) einen schwarzen Pixel berührt. Allerding weiß ich noch nicht so ganz wie ich das umsetzen könnte. Vielleicht geht es auch einfacher. Was sollte ich am besten machen?
MfG Cyberprince
Zuletzt bearbeitet von Cyberprince am 17.01.2009, 09:20, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
|
Nach oben |
|
|
Cyberprince Mini JLI'ler
Anmeldedatum: 14.01.2009 Beiträge: 7
Medaillen: Keine
|
Verfasst am: 16.01.2009, 15:49 Titel: |
|
|
Nun ja,
zwei von den Forumbeiträgen hatte ich auch schon gefunden, aber irgendwie
hat mir das nicht übermäßig wietergeholfen...
Aber lassen wir die Kollision mal beiseite. Was ich noch gern wissen würde, ist ob es eine Methode gibt, die die Pixelfarben des aktuellen Frontbuffers ausliest? Ich kenne die Funktion GetPixel aber es hieß die funktioniert nicht
mit DirectX und nicht im fullscreen-modus. Wie kann ich so was machen?
Cyberprince |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 16.01.2009, 16:49 Titel: |
|
|
Cyberprince hat Folgendes geschrieben: | Nun ja,
zwei von den Forumbeiträgen hatte ich auch schon gefunden, aber irgendwie
hat mir das nicht übermäßig wietergeholfen... |
Dann musst du deine Frage genauer stellen.
Cyberprince hat Folgendes geschrieben: | Ich kenne die Funktion GetPixel aber es hieß die funktioniert nicht
mit DirectX und nicht im fullscreen-modus. Wie kann ich so was machen |
Ich glaub, die funktioniert schon, aber für eine pixelgenaue Kollisionserkennung ist das viel zu lahm. Im dritten Thread ist die Methode beschrieben, mit der es schneller geht. Du musst dafür die Textur(en) locken und kannst dann direkt drauf rumschreiben/-lesen.
Falls du das Buch hast, stehts da auch irgendwo drin. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
Cyberprince Mini JLI'ler
Anmeldedatum: 14.01.2009 Beiträge: 7
Medaillen: Keine
|
Verfasst am: 16.01.2009, 17:59 Titel: |
|
|
Ich hab das Buch, aber soweit ich es verstehe wird dort nur die Kollision zwischen zwei sprites und nicht zwischen einem Surface und einem Sprite beschrieben. Mein Problem ist also dasselbe wie im 2. Forumbeitrag, auf den du verlinkt hast. Der Helikopter fliegt und wenn er auf etwas schwarzes im Surface(siehe Bild) trifft fliegt er hindurch. Allerdings sollte er daran zerschellen. Allerdingskann ich mit der Lösung aus diesem Beitrag nicht viel anfangen. Ich wollte es so machen das ich um das Sprite (den Helikopter) eine BoundingBox zeichne und dann teste ob sich die BoundingBox mit einem schwarzen pixel überschneidet. Nun das klappt nicht. Ich hab den gesamten Code gelöscht und schreibs von neuem, aber ich weiß net wie
Hoffentlich ist das genau genug
Cyberprince |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 16.01.2009, 18:24 Titel: |
|
|
Es wäre auch eine gute Idee, die Landschaft aus Polygonen zu basteln, statt aus Bitmaps. Zumindest für die Kollisionsabfrage. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Cyberprince Mini JLI'ler
Anmeldedatum: 14.01.2009 Beiträge: 7
Medaillen: Keine
|
Verfasst am: 16.01.2009, 18:49 Titel: |
|
|
Das ist glaube ich aufwendiger und außerdem habe ich das noch nie gemacht, d.h. ich müsste mich noch in solche Sachen vertiefen und ich hätte eher Lust ein Spiel fertig zu bekommen anstatt noch etwas zu lernen.
Aber dazu brauch ich halt noch eine Lösung des Problems.
Hat noch niemand von euch dieses Problem gehabt und es "gescheit" gelöst?? |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 17.01.2009, 13:14 Titel: |
|
|
Zeig mal etwas Code.
Ich kann mir im Moment nicht vorstellen, was nicht funktionieren soll. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
Cyberprince Mini JLI'ler
Anmeldedatum: 14.01.2009 Beiträge: 7
Medaillen: Keine
|
Verfasst am: 17.01.2009, 17:00 Titel: |
|
|
Hmm... den Code hab ich leider schon wieder gelöscht. Ich wollte ihn neu schreiben aber ich weiß nur nicht wie. Aber an das Prinzip erinnere ich mich noch:
CPP: | // BoundingBox um das Sprite (Helikopter) zeichnen
BOOL collision = FALSE;
if (BoundingBox überschneidet scih mit einem schwarzen Pixel)
{
collision = TRUE;
}
if (collision)
{
//zerstöre Helikopter
}
|
Aber wie ich herauskriegen soll, ob es sich um ein schwarzen pixel handel, weiß ich nicht. Im Buch wird dies auf S.342 erwähnt. Mann sollte LockRect() aufrufen, als letzten Parameter D3DLOCK_READONLY übergeben. Dann könne man irgendwie die Farbe der pixel auslesen. |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 17.01.2009, 18:16 Titel: |
|
|
Hi, es gibt im Buch ein Kapitel das eine screenshot()-Methode defininiert, das könntest du dir mal ansehen. ansonsten ist auch Google Codesearch und für c++ speziell C++ Codesearch eine gute Anlaufstelle. Da findet man unter Eingabe ein paar Schlagwörter z.B. dies hier, das ist ein gutes (und umfangreiches) Beispiel zu der Thematik. Das Buch hat übr auch ein Kapitel zu Pitch und Bits, die beiden Hauptelemente die du dabei benötigst. Auch die MSDN hilft bei sowas sehr oft weiter. (einfach mal LockRect oder andere Methodennamen eingeben)
Ist zwar bei mir schon was her als ich das ma gemacht hab aber ich glaube man kann das ganze ungf so zusammenfassen:
- Du rufst die Methode LockRect() eines Surfaces auf und übergibst versch. Argumente (readonly z.b. macht das ganze schneller wenn du nur lesen willst), dabei ist ein Zeiger auf die LOCKRECT-Struktur.
- Die LockRect-Struktur bekommt danach gültige Member wie den Pitch des Bildes (das ist die Breite im Speicher, sollte man versuchen genau zu verstehen) und einen Zeiger auf die eigentlichen Pixel-Werte
- nachdem man mit Bits und Pitch deine nötigen Werte abgefragt hat, ruft man noch UnlockRect vom Surface aus um den Buffer wieder freizugeben.
Surface kann übr auch Front- oder Backbuffer sein, aber dabei muss man einige besondere sachen beachten und ein bisschen Performanceverlust in Kauf nehmen, dazu dann einfach mal googlen, gibt genug Beispiele und Tutorials im Net.
gruß dxer |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 18.01.2009, 14:29 Titel: |
|
|
Cyberprince hat Folgendes geschrieben: | Aber wie ich herauskriegen soll, ob es sich um ein schwarzen pixel handel, weiß ich nicht. Im Buch wird dies auf S.342 erwähnt. Mann sollte LockRect() aufrufen, als letzten Parameter D3DLOCK_READONLY übergeben. Dann könne man irgendwie die Farbe der pixel auslesen. |
Genau diesen Code mein ich aber.
Der Code im Buch zeigt dir, wie man so die Farbe eines Pixels auslesen oder schreiben kann.
Was davon "klappt nicht"?
Wir können dir nicht sagen, was nicht klappt und was du daher ändern musst, weil der Code im Normalfall klappt.
Zeig einfach mal deine Umsetzung davon. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
Cyberprince Mini JLI'ler
Anmeldedatum: 14.01.2009 Beiträge: 7
Medaillen: Keine
|
Verfasst am: 18.01.2009, 16:19 Titel: |
|
|
Nun, das auslesen der Farbe hab ich jetzt hinbekommen. Der Fehler liegt galube ich beim testen auf die Farbe schwarz. Ich hatte es so versucht:
CPP: | BOOL BlackPixel;
for( int i=0;i<1024)
{
for(int j=0;j<768)
{
if( Pixels[i * nPitch + j] == D3DCOLOR_ARGB(0,0,0,0) )
{
BlackPixel = TRUE;
}
}
} |
Vlt. klappt es ja, wenn ich einfach ein bissel rumprobiere. Aber ehrlich gesagt hab ich langsam keine Lust mehr auf dieses Projekt. Ich sollte lieber mal etwas einfacheres anfangen, und nicht sofort so etwas schweres probieren. |
|
Nach oben |
|
|
=]Mid[=]Night[= Super JLI'ler
Anmeldedatum: 20.11.2002 Beiträge: 380 Wohnort: Aachen Medaillen: Keine
|
Verfasst am: 18.01.2009, 23:03 Titel: |
|
|
Also mit dem Code gehst du ja anscheinend den ganzen Bildschirm durch (1024 * 768). Um die Kollisioin für den Helikopter zu machen musst du ja eigentlich nur Pixel überprüfen, die in seiner Bounding Box liegen.. |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 19.01.2009, 11:16 Titel: |
|
|
Vor allem gehst du all diese Pixel durch, ohne was mit den zwischenzeitlichen Ergebnissen anzufangen. Du hast eine einzelne Variable, die das Testergebnis speichert. Bei jedem neuen Pixel wird das vorherige Ergebnis immer überschrieben. Ist also der letzte Pixel rechts unten nicht schwarz, schlägt der Test sowieso immer fehl.
Sinnvoller wäre so eine Funktion wie:
CPP: | bool Collides(RECT Bounding1, RECT Bounding2) |
Bei der du die Schnittmenge der beiden Rects durchläufst. Ist im Prinzip die gleiche Schleife, nur die Start- und Endwerte ändern sich.
Werden zwei sich überlagernde Pixel gefunden, gibst du per "return true;" zurück, dass eine Collision stattfindet.
Durchläuft das Programm die Schleife bis zum Ende, ohne igendwas zu finden, gibst du false zurück. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 19.01.2009, 11:35 Titel: |
|
|
The Lord of Programming hat Folgendes geschrieben: | Vor allem gehst du all diese Pixel durch, ohne was mit den zwischenzeitlichen Ergebnissen anzufangen. Du hast eine einzelne Variable, die das Testergebnis speichert. Bei jedem neuen Pixel wird das vorherige Ergebnis immer überschrieben. Ist also der letzte Pixel rechts unten nicht schwarz, schlägt der Test sowieso immer fehl.
|
Da er das Ergebniss aber immer mit TRUE überschreibt ändert das nichts
Es sollte übrigens BlackPixel initialisiert werden bevor du es benutzt, sonst können im Release Build sehr ungewöhnliche Effekte auftreten da dann BlackPixel jeden beliebigen Wert haben könnte (Im Debug Build werden solche Variablen mit 0 initialisiert), ausserdem können sonst Exceptions auftreten da du eine nicht initialisierte Variable benutzt (wenn du BlackPixel testest).
CPP: | BOOL BlackPixel = TRUE; // wieso überhaupt BOOL anstatt bool? |
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|