|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 16.01.2006, 21:38 Titel: Pixelgenaue Kollisionserkennung |
|
|
Hi all
entwickle gerade an einem einfachen Shooter Spiel in 2d.
ich verwende eigentlich 1 zu 1 die Klassen wie sie im Buch angelegt wurden, also die Spriteklasse und den Ressourcen Manager. Jetzt brauche ich irgend eine Möglichkeit pixelgenau kollisionen abzufragen ( das mit der optimierung vorher das man nur naheliegende Frames abfrägt krieg ich schon gebacken ) ich hab nur keine ahnung wie ich auf die frames sprites selbst zugreifen
kann.
kann mir jemand helfen?
RayJunx _________________ Just a Freak |
|
Nach oben |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
Verfasst am: 16.01.2006, 21:41 Titel: |
|
|
Eigentlich ganz einfach, die Surface/Textur locken, jeden Pixel auslesen, damit einen Bitmaskenvergleich durchführen und gucken wo es übereinstimmungen gibt.
Das hier ist noch aus einer Nebel-Nacht Aktion und NICHT Fehlerfrei, aber zeigt die veranschaulichung einfach mal gut: CPP: | bool collision (int x1, int y1, ::RECT &rect1, ::IDirect3DTexture9* texture1,
int x2, int y2, ::RECT &rect2, ::IDirect3DTexture9* texture2)
{
bool collide = false; // Kollision ?
static int breite; // Wie breit muss getestet werden
static int hoehe; // Wie hoch muss getestet werden
static int xg1, yg1, xg2, yg2; // Grössen der Sprite-Ausschnitte
static int pitch1, pitch2; // Pitch-Grösse
static int xOffset1 = 0; // xOffset in Surface1 wenn alle 0 sind,
static int yOffset1 = 0; // yOffset in Surface1 heisst das, dass die
static int xOffset2 = 0; // xOffset in Surface2 Objekte die gleichen
static int yOffset2 = 0; // yOffset in Surface2 Koordinaten haben
static unsigned long *vram1; // Zeiger auf Grafikdaten von Objekt 1
static unsigned long *vram2; // Zeiger auf Grafikdaten von Objekt 2
static D3DLOCKED_RECT d3drect_; // Surface-Beschreibung
// Grösse der Sprite-Ausschnitte festlegen (weil der Wert recht oft vorkommt)
xg1 = rect1.right - rect1.left;
xg2 = rect2.right - rect2.left;
yg1 = rect1.bottom - rect1.top;
yg2 = rect2.bottom - rect2.top;
// Also gut, BoundingBox-Kollision war erfolgreich (separate Funktion),
// jetzt schauen wirs uns genauer an.
// Zuerst müssen wir die Positionen zueinander checken, um die Offsets in den
// einzelnen Surfaces zu errechnen
if (x1<x2) // Objekt1 ist Links von Objekt2
xOffset1 = x2-x1;
else if (x1>x2) // Objekt1 ist Rechts von Objekt2
xOffset2 = x1-x2;
if (y1<y2) // Objekt1 ist oberhalb von Objekt2
yOffset1 = y2-y1;
else if (y1>y2) // Objekt1 ist unterhalb von Objekt2
yOffset2 = y1-y2;
// Die Surfaces der zwei Sprites locken und die Zeiger holen
::ZeroMemory (&d3drect_, sizeof(d3drect_));
// Objekt 1
texture1->LockRect (0, &d3drect_, NULL, 0);
vram1 = reinterpret_cast<unsigned long*>(d3drect_.pBits);
pitch1 = static_cast<int>(d3drect_.Pitch >> 2);
// Objekt 2
texture2->LockRect (0, &d3drect_, NULL, 0);
vram2 = reinterpret_cast<unsigned long*>(d3drect_.pBits);
pitch2 = static_cast<int>(d3drect_.Pitch >> 2);
// Die zu prüfende Grösse des Rechteckes ermittlen, damit wir NUR den Bereich
// prüfen, der auch notwendig ist (klappt noch nich so ganz :-D)
if (xg1<xg2) breite = xg1; else breite = xg2;
if (yg1<yg2) hoehe = yg1; else hoehe = yg2;
// Und dann testen wir endlich die Kollision Pixel für Pixel
for(int i=0; i<breite; i++)
{
for(int j=0; j<hoehe && collide == false; j++)
{
// Noch im Testbaren Bereich?
if ((xOffset2+i < xg2) && (yOffset2+j < yg2)
&&(xOffset1+i < xg1) && (yOffset1+j < yg1))
{
// Pixel genau testen!
if ((vram1[rect1.left + xOffset1 + i +(rect1.top + yOffset1+j)*pitch1] != COLOR_ARGB(0,255,0,255))
&& (vram2[rect2.left + xOffset2 + i +(rect2.top + yOffset2+j)*pitch2] != COLOR_ARGB(0,255,0,255)))
{
collide = true;
break;
}
}
}
}
// Texturen wieder freigeben (egal, ob Kollision oder nicht)
texture2->UnlockRect(0);
texture1->UnlockRect(0);
return (collide);
} |
_________________ 'Wer der Beste sein will muss nach Perfektion streben und jede Gelegenheit nutzen sich zu verbessern.' - KIA
[ German Game Dev | Boardsuche hilft sehr oft | Google rockt | Wie man Fragen richtig stellt | ICQ#: 143040199 ] |
|
Nach oben |
|
|
PeaceKiller JLI Master
Alter: 36 Anmeldedatum: 28.11.2002 Beiträge: 970
Medaillen: Keine
|
Verfasst am: 16.01.2006, 21:43 Titel: |
|
|
Im Fighter-Beispiel wird doch auch pixelgenaue Kollisionserkennung benützt. _________________ »If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine |
|
Nach oben |
|
|
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 16.01.2006, 21:48 Titel: leider nicht |
|
|
beim fighter program ist es nur eine bounding box routine.leider _________________ Just a Freak |
|
Nach oben |
|
|
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 16.01.2006, 21:49 Titel: danke |
|
|
und danke für die promte antwort!
ich werde den code gleich morgen austesten
gruß
rayjunx _________________ Just a Freak |
|
Nach oben |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
Verfasst am: 16.01.2006, 21:50 Titel: |
|
|
Wie schon gesagt, es läuft aber nicht immer richtig. Benutze diese sowieso nicht mehr, aber zu Lernzwecken solte diese ausreichen. _________________ 'Wer der Beste sein will muss nach Perfektion streben und jede Gelegenheit nutzen sich zu verbessern.' - KIA
[ German Game Dev | Boardsuche hilft sehr oft | Google rockt | Wie man Fragen richtig stellt | ICQ#: 143040199 ] |
|
Nach oben |
|
|
Christian Rousselle Site Admin
Alter: 48 Anmeldedatum: 19.07.2002 Beiträge: 1630
Medaillen: Keine
|
Verfasst am: 16.01.2006, 22:08 Titel: Re: leider nicht |
|
|
RayJunx hat Folgendes geschrieben: | beim fighter program ist es nur eine bounding box routine.leider |
JLIFighter ist pixelgenau. |
|
Nach oben |
|
|
philipp_boeing JLI'ler
Alter: 34 Anmeldedatum: 26.07.2003 Beiträge: 188
Medaillen: Keine
|
Verfasst am: 17.01.2006, 06:01 Titel: |
|
|
Patrick hat Folgendes geschrieben: | Wie schon gesagt, es läuft aber nicht immer richtig. |
aus welchem grund sollte es nicht immer richtig laufen? |
|
Nach oben |
|
|
Chriss Senior JLI'ler
Anmeldedatum: 18.08.2004 Beiträge: 267
Medaillen: Keine
|
Verfasst am: 17.01.2006, 07:45 Titel: |
|
|
Christian hat schonmal im Forum sein Beispielprogramm für Pixelgenaue Kollisionserkennung gepostet. Das ist eigentlich leicht zu verstehen und beschränkt sich auf das nötigste. Ich weiß aber nur noch das es im Thread "Fragen und Antworten.." war. |
|
Nach oben |
|
|
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 17.01.2006, 17:14 Titel: antwort |
|
|
also jli fighter verwendet erst eine bounding box und danach eine umriss kollisionsberechnung. Steht auch so im buch beschrieben. dort werden zeile für zeile punkte an der textur markiert und der bereich verglichen. das müßte aber bei mehrfachhinterschneidungen probleme geben ( man stelle sich ein U vor in das von oben ein objekt HINEINFLIEGT ). das programm für die pixelgenaue Kollisionsberechnung wird im buch verwießen fehlt aber
auf der cd. habe bereits nachgefragt, und es existiert, nur keine ahnung wer es hat. Hoffe es wird bald wieder gepostet. Nach "christians" lösung werde
ich auch mal ein auge werfe. Werde jetzt erstmal testen ob ich mit den bisherigen infos schonmal weiterkomme.
vielen dank für die codes und infos!
gruß
Rayjunx _________________ Just a Freak |
|
Nach oben |
|
|
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 17.01.2006, 22:03 Titel: Fast geschafft |
|
|
Hi Patrick,
danke für dein Beispiel,
ich habe es gleich eingebaut und die einbindung ging ohne fehlermeldungen.
habe es direkt in meine sprite in meine direct3d klasse eingebettet.
jetzt hab ich nur ein paar fragen zur verwendung und vorallem zum
ausruf. ich weiß nicht genau wo ich die parameter zur eingabe finde.
also:
x1 x2 y1 y2 stehen für die position der texturen oder? ist es egal wo sie
liegen? ich meine in welchem wertebereich? ob beide irgendwo links
oben bnahe 100,100 liegen oder im anderen eck? denke mal das
spielt keine rolle. Vielleicht am rande, es gibt die linke obere ecke an
oder? nicht die mitte...
wie sieht die eingabe für den ::RECT &rect1 parameter aus? und
was muß ich als ::IDirect3DTexture9* texture1 (und2) angeben.
ich weiß das da die grafiken rein müssen aber in welcher
form? sicher nicht wie über den ressourcen manager über
den dateinamen so ala "raumschiff.png"
ich habe mal hier anbei die wesendlichen auszüge über die klassen
in meinem program, vom resourcen manager und der spriteklasse.
glaubst du du kannst mir nur mal in nem beispiel nen ausruf
für deine collisions funktion schreiben? der zwei texturen in
die in meinem manager gespeichert sind verwendet? bzw
die textur des jeweiligen Spritelements weiterleiten.
apropo soll/kann ich die collisionsfunktion in die sprite
klasse schieben? wäre besser oder?
vielen dank schonmal! und eine gute Nacht,
Rayjunx
<edit>
Hier der Code, hatte ihn vergessen, sorry
CPP: | // Konstruktor - Initialisierungen
CSprite::CSprite(void)
{
m_Rotation = 0;
m_StepX = 0;
m_StepY = 0;
m_Width = 0;
m_Height = 0;
m_AnimationSpeed = 0;
m_CurrentImage = 0.0f;
m_lpDevice = NULL;
m_lpSprite = NULL;
}
// Sprite kreiern
void CSprite::Create(LPDIRECT3DDEVICE9 lpDevice, float AnimationSpeed)
{
m_lpDevice = lpDevice;
m_AnimationSpeed = AnimationSpeed;
D3DXCreateSprite(m_lpDevice, &m_lpSprite);
m_vScale = D3DXVECTOR2(1.0f,1.0f);
m_StepX = 10.0f;
m_StepY = 10.0f;
}
// Textur für das Sprite festlegen
void CSprite::AddTexture(LPDIRECT3DTEXTURE9 lpTexture)
{
// Beschreibung des zu Grunde liegenden Surfaces
D3DSURFACE_DESC desc;
lpTexture->GetLevelDesc(0,&desc);
// Breite und Höhe speichern
m_Width = desc.Width;
m_Height = desc.Height;
m_vRotationCenter = D3DXVECTOR2((float)m_Width/2, (float)m_Height/2);
// Zeiger auf die Textur speichern
m_AnimationVec.push_back(lpTexture);
}
// Sprite zeichnen
void CSprite::Draw(void)
{
// Sprite in der passenden Animationsstufe zeichnen
m_lpSprite->Draw(m_AnimationVec[m_CurrentImage],
0,
&m_vScale,
&m_vRotationCenter,
m_Rotation,
&m_vPosition,
0xFFFFFFFF);
}
///////////////////////////////
// Textur suchen und ggf. zurückgeben
LPDIRECT3DTEXTURE9 CResourceManager::GetTexture(LPCSTR lpTextureName)
{
// Iterator für die Suche in der Map
map<string,LPDIRECT3DTEXTURE9>::iterator result;
// Nach dem Namen der Textur suchen
result = m_MapTextures.find(lpTextureName);
// wenn der Name nicht in der Map vorhanden ist
// NULL zurückgeben
if(result == m_MapTextures.end())
{
return NULL;
}
// sonst den Zeiger auf die Textur zurückgeben
return result->second;
}
// Textur hinzufügen
void CResourceManager::AddTexture(LPCSTR lpFileName)
{
// testen, ob die Textur bereits vorhanden ist
LPDIRECT3DTEXTURE9 lpTexture = GetTexture(lpFileName);
// wenn sie nicht vorhanden ist, wird sie wie
// gewohnt erzeugt
if(!lpTexture)
{
D3DXIMAGE_INFO ImageInfo;
D3DXGetImageInfoFromFile(lpFileName,&ImageInfo);
D3DXCreateTextureFromFileEx(m_lpD3DDevice,
lpFileName,
ImageInfo.Width,
ImageInfo.Height,
1,0,
D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_NONE,
D3DX_FILTER_NONE,
0,0,0,
&lpTexture);
// und in die Map unter ihrem Namen eingefügt
m_MapTextures[lpFileName] = lpTexture;
}
}
|
Edit(Kampfhund): Bitte statt den "code"-Tags die "cpp" Tags verwenden. Ich habs mal geändert.
Edit(TLoP): RayJunx, bitte nächstes mal den -Button verwenden, anstatt einen neuen Beitrag zu schreiben.
</edit> _________________ Just a Freak |
|
Nach oben |
|
|
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 18.01.2006, 18:59 Titel: frage an patrick |
|
|
hey was macht eigentlich "zensiert" II ?
ich mein raptor?
hab mir eben das erste geladen die alpha zum austesten.
und tust du mir nen gefallen und schreibst mir noch was zur anwendung deines kollisionsprogs
wäre mir seeehr wichtig. danach habe ich nämlich alles was ich brauche.
von ein wenig mausgeärgere mal abgesehen und avi abspielen ist aber nicht so wichtig.
gruß
Rayjunx _________________ Just a Freak |
|
Nach oben |
|
|
Patrick Dark JLI Master
Anmeldedatum: 25.10.2004 Beiträge: 1895 Wohnort: Düren Medaillen: Keine
|
Verfasst am: 18.01.2006, 19:10 Titel: |
|
|
RayJunx
Raptor macht nix mehr, musste es ja einstellen. Aber egal
Zur Funktion CPP: | bool collision (int x1, int y1, ::RECT &rect1, ::IDirect3DTexture9* texture1,
int x2, int y2, ::RECT &rect2, ::IDirect3DTexture9* texture2) |
x1 und y1 ist die Position von Objekt 1.
x2 und y2 ist die Position von Objekt 2.
rect1 beschreibt den Ausschnitt auf der Bitmap den Objekt 1 benutzt.
rect2 beschreibt den Ausschnitt auf der Bitmap den Objekt 2 benutzt.
texture1 ist die Textur die für Objekt 1 benutzt wird.
texture2 ist die Textur die für Objekt 2 benutzt wird.
Wie schon gesagt: SEHR verbuggt aber zum Rumtüfteln reicht es. _________________ 'Wer der Beste sein will muss nach Perfektion streben und jede Gelegenheit nutzen sich zu verbessern.' - KIA
[ German Game Dev | Boardsuche hilft sehr oft | Google rockt | Wie man Fragen richtig stellt | ICQ#: 143040199 ] |
|
Nach oben |
|
|
RayJunx JLI'ler
Alter: 43 Anmeldedatum: 16.01.2006 Beiträge: 130 Wohnort: Bayern Medaillen: Keine
|
Verfasst am: 18.01.2006, 20:05 Titel: Danke |
|
|
danke,
ein wenig hat es mir geholfen, ich werde damit rumspielen bis es hinhaut.
hab jetzt auch endlich das mausproblem gelöst, jetzt kann ich mich ganz auf diese letzte große hürde konzentrieren.
gruß
Rayjunx _________________ Just a Freak |
|
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
|