Version 2.0!
Features
Tutorials
Files
Glossary
Projects
Contact
Links
Message Board
Extras
LuckyCam
Old News
Sign Guestbook
View Guestbook
VB Horoscope
VB Photo Album
.
ATTENTION READERS! Lucky's VB Gaming Site is no longer active. For updated game programming information and tutorials, please visit The Game Programming Wiki!

Pixelgenaue Kollisionsabfrage

Eins kann ich euch jetzt schon sagen, dieses Tutorial wird kurz und schmerzlos... und sehr, sehr fortgeschritten! Ich werde mir nicht die Mühe machen, euch zu erklären, wie die Initialisierung und Terminierung von DirectDraw, das laden von Surfaces, die Rechteckskollisionsabfrage, usw. funktioniert. Falls ihr diese Dinge noch nicht beherrscht, dann glaube ich, dass ihr noch nicht für Pixel-Manipulations-Techniken bereit seid.

Also, los geht's!

Wir werden die DirectDrawSurface7.GetLockedArray-Methode verwenden, um die Farbwerte jedes Pixel unserer Surface zu extrahieren. Natürlich müssen wir zuerst DirectDrawSurface7.Lock aufrufen, und diese Methode akzeptiert eine menge Argumente:

- r as RECT - Das Rechteck, innerhalb einer Surface, welches ich sperren wollt... theoretisch! Denn eigentlich, egal wie groß euer Rechteck ist, werdet ihr eh die ganze Surface sperren! Aber das macht nichts, wie ihr sehen werdet.
- desc As DDSURFACEDESC2 - Nach dem Lock-Aufruf (sichern/sperren) wird diese Variable mit der Beschreibung der gesicherten Surface gefüllt.
- flags As CONST_DDLOCKFLAGS - Wir werden folgende Flags (Argumente) verwenden: DDLOCK_READONLY und DDLOCK_WAIT, da wir nur Daten lesen wollen und keinen Fehler auslösen möchten (durch das Zugreifen auf eine unvorbereitete Surface).
- hnd As Long - Das SDK sagt, dass dieser Parameter nicht benutzt wird, also setzen wir ihn auf null.

Die GetLockedArray-Methode selber nimmt nur ein Argument an, ein Byte-Datenfeld (Beachtet, dass dieses Array DYNAMISCH SEIN MUSS!), dass mit den Surface-Daten gefüllt wird. Ein Beispiel:

Dim bytMoving() As Byte

    msurfMovingObj.GetLockedArray bytMoving

Wenn wir diesen Code ausführen, nachdem wie die Surface gesperrt (engl.: Lock) haben, werden wir ein Array erhalten, dass auf einen Speicherbereich der Surface ZEIGT. Beachtet, dass dies nur ein Zeiger ist... das Datenfeld selber wird diese Daten nicht mehr enthalten, nachdem wir die Surface wieder freigegeben (Unlock) haben! Das mag zwar ziemlich umständlich erscheinen, aber es ist sehr nützlich. Es erlaubt uns nur auf die Pixel zuzugreifen, deren Werte wir benötigen... die restlichen können wir einfach ignorieren. Da das untersuchen der Pixel-Daten eine sehr zeitspielige Angelegenheit ist, können wir gebrauch dieses Vorteils der GetLockedArray-Methode machen, um die Zeit, die für die Kollisionsabfrage benötigt wird, zu minimieren.

Wie? Wir sperren beide Surfaces und gehen Pixel für Pixel durch die sich überschneidenden Flächen der beiden Surfaces und untersuchen die Pixel-Werte. Durch das Auslassen der nicht-überlappenden Flächen sparen wir einiges an Zeit (das überlappende Rechteck (RECT) erhalten wir, durch den Einsatz der IntersectRect API), und durch den gleichzeitigen Vergleich der Pixel der Surfaces, können wir eine Kollision melden, sobald auch nur eine Überlappung entdeckt wurde! Das ist der für euch am effizientesten funktionierende Algorithmus, um Kollisionen zwischen unregelmäßigen Objekten festzustellen (reglemäßige Objekte könnten Eigenschaften aufweisen, die euch eine weitere optimierung ermöglichen).

Ich werde hier nicht weiter auf die Einbindung eingehen, da es sich einfach nur um das Auffinden eines überlappenden Rechtecks (RECT) und einen Pixel-Vergleich handelt. Seht euch den Quellcode an und es wird euch alles klar!

Hoffe ich doch mal :) Viel Glück!