|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 18.11.2003, 09:25 Titel: Kollisionserkennung |
|
|
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 |
|
|
Mäscht JLI'ler
Anmeldedatum: 22.05.2003 Beiträge: 150 Wohnort: Bad Hofgastein\Österreich Medaillen: Keine
|
Verfasst am: 18.11.2003, 12:19 Titel: |
|
|
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 |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 18.11.2003, 12:22 Titel: |
|
|
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 |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 18.11.2003, 13:23 Titel: |
|
|
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 |
|
|
Mäscht JLI'ler
Anmeldedatum: 22.05.2003 Beiträge: 150 Wohnort: Bad Hofgastein\Österreich Medaillen: Keine
|
Verfasst am: 18.11.2003, 15:24 Titel: |
|
|
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 18.11.2003, 21:11 Titel: |
|
|
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
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 18.11.2003, 21:16 Titel: |
|
|
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 |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 18.11.2003, 21:38 Titel: |
|
|
Bitte
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 18.11.2003, 22:11 Titel: |
|
|
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
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 |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 19.11.2003, 10:18 Titel: |
|
|
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 20.11.2003, 08:51 Titel: |
|
|
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 |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 20.11.2003, 10:36 Titel: |
|
|
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 20.11.2003, 11:46 Titel: |
|
|
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 20.11.2003, 17:23 Titel: |
|
|
Ach Mann. Das mit den Vektoren klappt nicht so ganz. Jetzt läuft der Spieler nämlich durch alles einfach durch
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 |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 20.11.2003, 18:34 Titel: |
|
|
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 )
MFG
Chris _________________ Schau mir in die Augen, Kleines. |
|
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
|