JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=de2edbda1eac7374f4bdf3bef58e3083Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Kollisionserkennung
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 09:25    Titel: Kollisionserkennung Antworten mit Zitat

Hi,

ich rätsle grad ein wenig mit einer 2D Kollisionserkennung.
Ich habe ein Sprite, sagen wir mal der Held eines RPGs, und einen Stein als Kollisionsobjekt.
Die Funktion, die testet, ob eine Kollision stattgefunden hat, habe ich bereits fertig.
Ich frag mich nur grade, wie ich das richtig ins Spiel umsetzen kann. Bisher hab ich überlegt, dass einfach die entsprechende Richtungstaste gesperrt wird, wenn eine Kollision gemeldet wird. Dabei ist letztendlich aber nur rausgekommen, dass ich mich gar nicht mehr bewegen kann, sobald überhaupt eine Kollision stattgefunden hat.

Meine Frage ist, ob die Möglichkeit, die ich genommen hat, schon in Ordnung ist, halt nur noch von Fehlern befreit werden müsste, oder ob es eine einfachere Variation gibt. Wenn dem so sein sollte, kann mir dann einer vielleicht einen Link oder ein Fitzelchen Sourcecode geben bitte?

Thx 4 help
MFG
#C
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Mäscht
JLI'ler



Anmeldedatum: 22.05.2003
Beiträge: 150
Wohnort: Bad Hofgastein\Österreich
Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 12:19    Titel: Antworten mit Zitat

Code:


int s_y, o_y; // Y-Koordinate des Sprites/Objekts
int s_x, o_x; // X-Koordinate des Sprites/Objekts
int s_h, o_h; // Höhe des Sprites/Objekts
int s_w, o_w; // Weite des Sprites/Objekts


if(s_y<o_y+o_h && s_x+s_w>o_x && s_x<o_x+o_w && s_y + s_h > o_y)
{
    Kollision
}



_________________
Motz´z mi net o, i bin ofänga!! AEIOU für immer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 18.11.2003, 12:22    Titel: Antworten mit Zitat

Dein Problem ist (deine Figur bleibt stecken) das du deine Figur nach der Kollision nicht auf die Stelle zurückstellst an dem keine Kollision mehr stattfindet. So wie du es hast prüft er immer die gleiche Stelle wo er sich schon im Stein befindet.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 13:23    Titel: Antworten mit Zitat

Ich würde dir dann immer bevor du den Helden verschiebst prüfen, ob eine Kollision stattfinden würde. Sonst würde die Figur steckenbleiben(s. FallenAngel84).
Nimm einfach eine virtuelle Position, mit der du dann rechnest:
Code:
//global:
int heldx;
int heldy;

//lokal:
int virtualx=heldx+zukuenft_x_versch;
int virtualy=heldy+zukuenft_y_versch;

if(Kollision(virtualx,virtualy,steinx,steiny)==FALSE)
{
    //Held bewegen
}

_________________
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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Mäscht
JLI'ler



Anmeldedatum: 22.05.2003
Beiträge: 150
Wohnort: Bad Hofgastein\Österreich
Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 15:24    Titel: Antworten mit Zitat

Frage:
Passt jetzt meine Funktion, die ich oben geschrieben habe oder nicht! Mir kommt sie sdchon richtig vor! (ich hab halt nicht geschrieben, was passieren soll, wenn eine Kollision stattfindet!!
_________________
Motz´z mi net o, i bin ofänga!! AEIOU für immer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 21:11    Titel: Antworten mit Zitat

Was mein konkretes Problem gewesen ist, war mir klar. Hab ich das nich erwähnt?
*guck nach*
Ach ne, hab ich nich. Tschulligung ^^

Ok. Auf solche einfachen Sachen komm ich ja nich. Ich denk immer viel zu kompliziert, darum geht auch die ein oder andre Mathearbeit von mir inne Hose Confused

Ich hab die Lösung von LoP probiert und es klappt wunderbar. Danke dafür! =)

Falls jemand mal interessiert ist, ich habs so gemacht:

Code:

int Action = DInput.GetInput(); // Tastatureingaben checken
         int virtualX,virtualY;         // zukünftige Schritte des Player

         if(Action & MOVE_LEFT) // wenn man nach links drückt
           {
            
            virtualX = Schatten.GetX() - 2; // zuk. Position errechnen
            Schatten.Set(virtualX, Schatten.GetY()); // Schatten probeweise hinsetzen
            if(Schatten.TestCollision(&Stein) == FALSE) // Kollision da?
            {
               Schatten.Set(virtualX, Schatten.GetY()+2); // wenn nich, dann bewegen
               
               Hero.SetSurface(SManager.GetSurface(HERO_LINKS)); // Surface zuweisen
               Hero.SetAnim(TRUE); // Bewegung einschalten wenn er läuft
               Hero.Move(-2,0);    // Veränderung der Position um -2 des x-Wertes
            }
            Hero.SetSurface(SManager.GetSurface(HERO_LINKS)); // Surface zuweisen

         
         }          

           if(Action & MOVE_RIGHT)
          {
            virtualX = Schatten.GetX() + 2;
            Schatten.Set(virtualX, Schatten.GetY());

            if(Schatten.TestCollision(&Stein) == FALSE)
            {
               Schatten.Set(virtualX, Schatten.GetY()-2);
                  
               Hero.SetSurface(SManager.GetSurface(HERO_RECHTS));   
               Hero.SetAnim(TRUE);
               Hero.Move(2,0);
            }
            Hero.SetSurface(SManager.GetSurface(HERO_RECHTS));
            
         
         }
         if(Action & MOVE_UP)
         {
            virtualY = Schatten.GetY() - 2;
            Schatten.Set(Schatten.GetX(), virtualY);
            if(Schatten.TestCollision(&Stein) == FALSE)
            {
               Schatten.Set(Schatten.GetX(), virtualY+2);

               Hero.SetSurface(SManager.GetSurface(HERO_OBEN));
               Hero.SetAnim(TRUE);
               Hero.Move(0,-2);
            }
            Hero.SetSurface(SManager.GetSurface(HERO_OBEN));
         }
         if(Action & MOVE_DOWN)
         {
            virtualY = Schatten.GetY() + 2;
            Schatten.Set(Schatten.GetX(), virtualY);
            if(Schatten.TestCollision(&Stein) == FALSE)
            {
               Schatten.Set(Schatten.GetX(), virtualY-2);

               Hero.SetSurface(SManager.GetSurface(HERO_UNTEN));
               Hero.SetAnim(TRUE);
               Hero.Move(0,2);
            }
            Hero.SetSurface(SManager.GetSurface(HERO_UNTEN));

                           
         }
         

         Render();
         Hero.SetAnim(FALSE); // Animation nach dem Zeichnen wieder ausschalten


kA ob das nich auch einfacher gehen würde. Jedenfalls scheinst zu klappen =D

Das ist jetzt allerdings nur ein Test für nen Stein. Ich kann ja schlecht für jedes einzelne Objekt eine Prüfung bei der Eingabeverarbeitung durchnehmen.
Kann man das auch allgemeiner machen, z.B. TestCollision(&keinBestimmtesSprite)? Also dass kein bestimmtes Sprite übergeben wird, sondern einfach ein Typ, der für alle Sprites gilt?

MFG
#C
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 21:16    Titel: Antworten mit Zitat

Als Ergänzung will ich noch sagen, dass ich mit dem Schatten die Position des Players berechne. Der Schatten ist bei mir eine Ellipse um den Player herum.
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 21:38    Titel: Antworten mit Zitat

Bitte Smile
Wenn du mehrere Objekte hast, setzt du eben an die Stelle(, an der die Kolision überprüft wird) anstatt den Koordinaten eines Hindernisses eine Schleife, die ein Array(oder auch ein vector/liste) mit allen Hindernissen durchläuft.
_________________
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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 18.11.2003, 22:11    Titel: Antworten mit Zitat

Soll heißen, ich muss bei der Erstellung der Sprites, die Dinger noch zusätzlich innem Vektor/Liste/Array speichern?
Ich denk, ich werf mal schnell nen Blick in den C++ Primer, weil ich auch gern mal mit Vektoren arbeiten wollte. Is doch auch mal was neues Wink

Ich hab da noch eine kurze Frage zum Schluss:
Wann lohnt es sich, eine DLL zu erstellen und was man dann da reinpacken könnte/sollte?

MFG
#C
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
AFE-GmdG
JLI MVP
JLI MVP


Alter: 45
Anmeldedatum: 19.07.2002
Beiträge: 1374
Wohnort: Irgendwo im Universum...
Medaillen: Keine

BeitragVerfasst am: 19.11.2003, 10:18    Titel: Antworten mit Zitat

Dll's lohnen sich, wenn du eine Funktionalität als Bibliothek in mehreren Programmen einbinden kannst. Das kann unter umständen auch schon ab einer einzigen Funktion sein.
Reinpacken kann man in eine Dll so zimlich alles, vorallem aber Funktionen und Resourcen (z.B. Bilder, Dialoge, Texte oder auch ganze Sound- und Mididateien)
_________________
CPP:
float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 20.11.2003, 08:51    Titel: Antworten mit Zitat

Ich hatte nämlich vor, die Dateien, die DDraw, DXAudio und DInput initialisieren da reinzupacken. Vor allem wegen der Übersichtlichkeit, da in meinen Projekt schon sehr viele Dateien sind und ich gerne etwas aufräumen wollte.
Gibt es eigentlich Performanceeinbrüche, wenn ich viele DLLs zu meiner exe linke? Bietet es sich an, eher wenige große als viele kleine DLLs zu haben?

MFG
#C
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
AFE-GmdG
JLI MVP
JLI MVP


Alter: 45
Anmeldedatum: 19.07.2002
Beiträge: 1374
Wohnort: Irgendwo im Universum...
Medaillen: Keine

BeitragVerfasst am: 20.11.2003, 10:36    Titel: Antworten mit Zitat

Diese Performanceeinbrüche entstehen nur, wenn die DLL geladen werden muß, danach nicht mehr. Wenn du nicht spätes Linken nutzt, werden die DLL's beim Start des Programmes geladen und man macht einfach eine "Ladeleiste" - so einfach ist das.
(Spätes Linken ist, wenn du die DLL-Dateinamen und Funktionen nicht kennst und erst zur Programmlaufzeit herausfinden mußt, wie welche Funktionen heißen und sie dann aufrufst, Ich nehme an, dass du frühes Linken für deine DLL's verwendest)
_________________
CPP:
float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 20.11.2003, 11:46    Titel: Antworten mit Zitat

Na gut, ist bei mir ja nicht der Fall.

Ich werd das mit den DLLs einfach mal ausprobieren, wenn dann aber das Laden zu lange dauert (aus welchen Gründen auch immer) lass ichs erst mal bleiben.
Würd sich aber imho während der Entwicklungszeit nich lohnen, DLLs zu machen, da man das Programm ja aus Testgründen unendlich viele Male ausführt und das schnell gehn soll.
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 20.11.2003, 17:23    Titel: Antworten mit Zitat

Ach Mann. Das mit den Vektoren klappt nicht so ganz. Jetzt läuft der Spieler nämlich durch alles einfach durch Sad

Der Funktion TestCollision hab ich einen Vektor mit Sprites übergeben:

Code:

BOOL Sprite::TestCollision(vector <Sprite> vecSprite)
{
   
   for(int i = 0; i < vecSprite.size(); ++i)
   {
      // Radius der BoundingBox berechnen
      int rx  = FrameWidth  / 2;
      int ry  = FrameHeight / 2;

      // Radius der BoundingBox des Sprites brechnen
      // Bounding Box verkleinern
      int Sp_rx = vecSprite[i].GetWidth()  / 2 - vecSprite[i].GetWidth()  / 8;
      int Sp_ry = vecSprite[i].GetHeight() / 2 - vecSprite[i].GetHeight() / 8;

      // die Mitte der Bounding Boxes berechnen
      int crx = x + rx;
      int cry = y + ry;
      int Sp_crx = vecSprite[i].GetX() + Sp_rx;
      int Sp_cry = vecSprite[i].GetY() + Sp_ry;


      // Abstand berechnen
      int dx = abs(Sp_crx - crx);
      int dy = abs(Sp_cry - cry);

      // Kollisionserkennung
      if(dx < rx + Sp_rx && dy < ry + Sp_ry)
      {
         // Kollision aufgetreten
         return TRUE;
      }
   }
   // keine Kollision aufgetreten
   return FALSE;
}


In der Initialiserungsfunktion, wo die Sprites erstellt werden, hab ich dies geschrieben:

Code:

   Stein.Create(SManager.GetSurface(STEIN),36,28,1,1,0,FALSE);
   Stein2.Create(SManager.GetSurface(STEIN),36,28,1,1,0,FALSE);

   SpriteVec.push_back(Stein);
   SpriteVec.push_back(Stein2);


Und bei der Eingabeverarbeitung das hier:
Code:

         if(Action & MOVE_LEFT) // wenn man nach links drückt
           {
            
            virtualX = Schatten.GetX() - 2; // zuk. Position errechnen
            Schatten.Set(virtualX, Schatten.GetY()); // Schatten probeweise hinsetzen
            
            if(Schatten.TestCollision(SpriteVec) == FALSE) // Kollision da?
            {
               Schatten.Set(virtualX, Schatten.GetY()+2); // wenn nich, dann bewegen
               
               Hero.SetSurface(SManager.GetSurface(HERO_LINKS)); // Surface zuweisen
               Hero.SetAnim(TRUE); // Bewegung einschalten wenn er läuft
               Hero.Move(-2,0);    // Veränderung der Position um -2 des x-Wertes
            }
            Hero.SetSurface(SManager.GetSurface(HERO_LINKS)); // Surface zuweisen

         
         }          

_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Zyrian
Super JLI'ler



Anmeldedatum: 30.08.2003
Beiträge: 321
Wohnort: Essen
Medaillen: Keine

BeitragVerfasst am: 20.11.2003, 18:34    Titel: Antworten mit Zitat

Schon gut, Problem gelöst =)

Lag daran, dass ich die Sprites zu früh in den Vektor gebracht habe.
Ich habe sie als Test mal erst NACHDEM ich sie gezeichnet habe, eingefügt und schon funzt es ^^

Danke für alle, die mir geholfen haben (und mir hoffentlich auch weiter helfen Wink)

MFG
Chris
_________________
Schau mir in die Augen, Kleines.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
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

Impressum