Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

31.05.2011, 16:21

Problem mit Kollision unter Directx

Hallo liebe Community,
Ich bin gerade dabei ein kleines 2D Spiel als Lernprojekt zu schreiben und bin jetzt an der Kollision angelangt. Mein Ziel ist es, ähnlich wie in jedem Jump'n'Run, eine Kollision mit der Welt zu haben. Dazu lade ich die Welt und dazu ein extra "Kollisionsbild" (Schwarz/Weiß Bild der Welt wobei die schwarzen Linien eben Hinternisse kenntzeichnen). Mit diesem Bild wollte ich, beim laden der Welt, ein Array füllen. Mit diesem Array könnte ich dann gucken, ob mein Spielersprite die Grenzen einhält und notfalls korrigieren. Nun habe ich allerdings das Problem, dass mir der Ansatz zum Laden des Bildes (PNG) bzw. das Auslesen der Pixel fehlt. Ist es besser dieses Bild in ein BitMap zu laden und dann irgendwie mit GetPixel zu arbeiten? Oder soll ich das Array vielleicht nicht mit Pixel füllen, sondern mit true für begehbar und false für unpassierbar füllen? Dann bleibe aber immernoch meine Kernfrage, wie man überhaupt das Bild für diesen Zweck läd. Über einen Stubs oder Tritt in die richtige Richtung wäre ich sehr dankbar :)

2

31.05.2011, 18:50

Hi Nuhrethil und Willkommen im Forum! :)

Im Prinzip so:

Bild/Textur einlesen mit DX-Funktionen wie z.B. D3DXCreateTextureFromFile oder D3DXCreateTextureFromFileEx
Textur sperren (mit LockRect, hab grad kein Beispiel parat)
In einer Schleife den Texturpuffer durchlaufen und dein Array füllen
Textur entsperren (UnlockRect)

Fertig! ;)
fka tm

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TrikkieMikkie« (31.05.2011, 18:56)


3

31.05.2011, 20:35

Ersteinmal vielen dank für deine Anwort! Das hat mir schoneinmal ein wenig geholfen. Leider habe ich noch eine weitere kleine Frage:


In einer Schleife den Texturpuffer durchlaufen und dein Array füllen



Wie komm ich daran? Die Informationen in LockRect werden ja scheinbar in D3DLOCKED_RECT gespeichert (laut msdn ?!)
Desweiteren habe ich ein recht vielversprechendes code-stückchen gefunden, wo unteranderem beschrieben wird wie man die Farbe der Pixel erhält:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
unsigned int readPixel(LPDIRECT3DTEXTURE9 pTexture, UINT x, UINT y)
{
D3DLOCKED_RECT rect;
ZeroMemory(&rect, sizeof(D3DLOCKED_RECT));
pTexture->LockRect(0, &rect, NULL, D3DLOCK_READONLY);
unsigned char *bits = (unsigned char *)rect.pBits;
unsigned int pixel = (unsigned int)&bits[rect.Pitch * y + 4 * x];
pTexture->UnlockRect(0);
return pixel;
}


wobei ich nicht ganz verstehe, was das hier macht...bzw eher WIE es das macht.

C-/C++-Quelltext

1
unsigned int pixel = (unsigned int)&bits[rect.Pitch * y + 4 * x];


Pitch ist ja wohl der Abstand, wann die nächste Zeile los geht?! und die 4 bezieht sich auf Bytes? Ich fische wirklich gerade ein wenig im Trüben. Vielleicht kann mir ja jemand erleuchtung verschaffen ;)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Nuhrethil« (31.05.2011, 20:43)


4

31.05.2011, 21:31

Erstmal Infos (Breite, Höhe usw.) über die Textur holen

C-/C++-Quelltext

1
2
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0,&desc);


Textur sperren

C-/C++-Quelltext

1
2
D3DLOCKED_RECT lr;
HRESULT hr = Texture->LockRect(0,&lr,NULL,0);


Zeiger auf das erste Element holen

C-/C++-Quelltext

1
BYTE *bytePointer=(BYTE*)lr.pBits;


Farben ermitteln (32bit Format wird angenommen)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for (DWORD y=0;y<desc.Height;y++)
{
    for (DWORD x=0;x<desc.Width;x++)
    {
       DWORD index=(x*4+(y*(lr.Pitch)));
       
       // Blau
       BYTE b=bytePointer[index];

       // Grün
       BYTE g=bytePointer[index+1];

       // Rot
       BYTE r=bytePointer[index+2];

       // Alpha
       BYTE a=bytePointer[index+3];  

       // Ab ins Array damit
   }
}

texture->UnlockRect(0);
fka tm

5

01.06.2011, 08:47

Ja so ähnlich hab ich das auch gelöst, danke nochmal fürs helfen. Einziger Unterschied, ich hatte mit einer statischen Variable als Hoehe/Breite gerechnet, wobei deine Variante wohl zweckdienlicher ist. Auch verstehe ich jetzt endlich wie die Verwendung der Bytes ist, also nocheinmal vielen dank für die schnelle Hilfe.

Werbeanzeige