|
You last visited: Today at 18:51
Advertisement
C++ Problem mit Kollisionsabfrage
Discussion on C++ Problem mit Kollisionsabfrage within the C/C++ forum part of the Coders Den category.
01/25/2015, 12:32
|
#1
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
C++ Problem mit Kollisionsabfrage
Guten Tag an die Community,
Im Sinne meines Abschlussprojektes programmiere ich ein 2D-Platformer mit Microsoft Visual Studio 2010, C++, Der Bibliothek "Allegro 4". Das ganze natürlich objektorientiert.
Ich habe folgendes Problem:
mit dieser Methode:
Code:
void Collision::LoadCollisionMap(const char *filename)
{
ifstream openfile(filename);
if(openfile.is_open())
{
openfile >> mapSizeX >> mapSizeY;
while (!openfile.eof())
{
openfile >> ColMapFile[loadCounterX][loadCounterY];
loadCounterX++;
if(loadCounterX >= mapSizeX)
{
loadCounterX = 0;
loadCounterY ++;
}
}
loadCounterX = loadCounterY = 0;
}
}
lade ich meine Map:
10 8
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
in das zweidimensionale Array "ColMapFile[loadCounterX][loadCounterY]"
die ersten zwei Werte sollen inr mapSizeX und mapSizeY geladen werden.
Das funktioniert auch, da ich genau die selbe Logik angewandt habe, um meine Map mittels Tiles zu gestalten.
Nun zu dem Problem:
mit folgender Methode:
Code:
void Collision:: PlatformCollision(BITMAP *buffer, Player &player)
{
for (int i = 0; i < mapSizeX; i++)
{
for (int j = 0; j < mapSizeY; j++)
{
if(ColMapFile[i][j] != 0)
{
if(player.y+player.animation->h<j*BlockSize || player.x > i*BlockSize+BlockSize || player.y > j*BlockSize+BlockSize || player.x+player.animation->w < i* BlockSize)
{
player.Platform = false;
}
else
{
player.Platform = true;
}
}
}
}
}
prüfe ich das o.g. Array auf einsen, wenn eine gefunden wird, soll die oben zusehende if-Abfrage durchgeführt werden usw.
Auch das funktioniert soweit, ich habe aus Testzwecken erstmals ein einziges Tile, also eine einzige 1, geladen, die Kollisions-Erkennung funktionierte dann auch einwandfrei, aber sobald ich eine zweite eins in die Map packe, wird nur eine eins erkannt und auf Kollision überprüft. Es scheint mir so als würde sich mein Code immer auf die eins festlegen, welche am nächsten zum Spieler spawn ist.
Syntaktischer oder logischer Fehler?
schonmal vielen lieben Dank im Vorraus,
mit freundlichen Grüßen,
Verteidiger
|
|
|
01/25/2015, 15:18
|
#2
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Wenn die Map richtig geladen wurde, wie du sagst, wird es wohl an der fetten if-Abfrage liegen.
Ich hab da mal eine Stelle markiert.
Dort würde ich ansetzen:
-Hast du 2 Ausgaben für die 2 Einsen liegts am if darunter (oder der Weiterverarbeitung?)
-Hast du 1 Ausgabe für eine von zwei Einsen sollte es wohl doch die Map sein
PHP Code:
if(ColMapFile[i][j] != 0)
{
// <--- Ausgabe?
if(player.y+player.animation->h<j*BlockSize || player.x > i*BlockSize+BlockSize || player.y > j*BlockSize+BlockSize || player.x+player.animation->w < i* BlockSize)
{
...
|
|
|
01/25/2015, 15:29
|
#3
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
Tut mir leid, kann dir nicht ganz folgen, was meinst du mit Ausgaben?
|
|
|
01/25/2015, 15:31
|
#4
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Entweder dir dort was ausgeben lassen oder breakpoint setzen um zu sehen wie oft du an der Stelle landest
|
|
|
01/25/2015, 15:34
|
#5
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
Aber rein theoretisch müsste die if-Abfrage jedes Mal durchgeführt werden, da sie, als ich zu testzwecken die Map mit nur einer eins modeliert habe, immer die Variable player.Platform in den richtigen Zustand versetzt hat, also wenn ich die eins berührt habe, wurde die Variable true, und sobald ich sie nicht mehr berührt habe, wurde sie auch wieder auf false gesetzt.
Edit: hab mir mal ne Ausgabe rein gemacht, die rattert immer durch, ich komm also jedes mal an die stelle "//Ausgabe"
Edit_2: Und zur Weiterverarbeitung, zurzeit wird nur die Variable Platform in der Klasse Player true bzw. false gesetzt und wenn ich das ganze Debugge wird mir der Zustand von Platform angezeigt ( durch ausgeben von 1 = true und 0 = false)
|
|
|
01/25/2015, 15:41
|
#6
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Und bei der zweiten 1 passiert nichts wenn du sie berührst aber du bist 100% sicher sie ist in der map?
|
|
|
01/25/2015, 15:45
|
#7
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
Ja ich habe es so gemacht, das die Tile map, also das was sichtbar ist, die selbe .txt Datei ist wie die, die ich für die Kollision benutze.
Ich sehe die zwei Blöcke, da die Kollision die selbe Datei nutzt sind also auch die zwei einsen da und müssten abgefragt werden, es wird aber immer nur ein Block abgefragt, die restlichen werden garnicht beachtet, da bleibt player.Platform bei berührung immer false.
|
|
|
01/25/2015, 16:04
|
#8
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Dann würde ich stark darauf setzen, dass bei der Logik der if-Abfrage irgendwas nicht hinhaut.
Ich weiß halt nicht was animation.h und .w oder BlockSize für Werte haben und was Platform aussagen soll deswegen ist das schwierig nachzurechnen für mich
|
|
|
01/25/2015, 16:12
|
#9
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
also animation ist das BITMAP in der das jeweilige Bild des Spielercharakters geladen wird, die sind aber alle gleich groß. animation->h steht für die Höhe des Bildes in pixel, und und animation->w für die Breite...BlockSize ist 64 da ich Tiles der Größe 64x64 nutze. Und Platform soll nur aussagen ob sich eine Tile direkt vor bzw unter dem Spielercharakter befindet(=player.platform = true) oder ob nicht(=player.platform = false)
|
|
|
01/25/2015, 17:04
|
#10
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Bewegt sich der Spieler pixelweise oder koordinatenweise also player.x zwischen 0 und 10?
und wie groß ist das Spielerbild auch 64x64?
|
|
|
01/25/2015, 17:07
|
#11
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
also player.x gibt die x Koordinate an, an der das Spieler BITMAP geblittet werden soll, somit bewegt der Spieler sich koordinatenweise. das Spielerbild ist 64 pixel breit und 80 pixel hoch
EDIT: Was ich einfach nicht verstehen will, ist, warum es bei dem einen Block wunderbar klappt, aber bei dem Block(1) darüber, nicht
|
|
|
01/25/2015, 17:47
|
#12
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Hmm also was ich sehe:
Code:
if(
player.y+player.animation->h < j*BlockSize // ein + zwischen der koordinate und der höhe in pixeln?
|| player.x > i*BlockSize+BlockSize // kann nie true sein: x maximal 9 und +BlockSize immer mindestens 64
|| player.y > j*BlockSize+BlockSize // kann auch nie true sein: selber grund
|| player.x+player.animation->w < i* BlockSize // ein + zwischen der koordinate und der breite in pixeln?
)
|
|
|
01/25/2015, 17:55
|
#13
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
Die if-Abfrage an sich ist korrekt, ich habe sie getestet, sie funktioniert, denn wenn man zu einer koordinate die höhe des bildes addiert, so erhält man eine ganz normal Zahl.beispiel:
der spieler ist auf der y koordinate 100, addiere ich nun die höhe von animation dazu, lande ich bei 180, und weil von oben nach unten y größer wird, muss player.y+player.animation->h kleiner als j*BlockSize sein, damit der spieler sich über dem geprüftem Block befindet.
Das hat schon alles seine richtigkeit, sonst würde es ja nicht bei dem einen Block einwandfrei funktionieren, meine Vermutung ist, dass wenn (ifColMapFile[i][j] != 0) ist, dass er zwar den Block usw prüft, aber dann nicht mehr rauskommt, also keine weiteren Stellen im Array überprüft...könnte mich aber auch irren :/
|
|
|
01/25/2015, 18:00
|
#14
|
elite*gold: 0
Join Date: Jul 2012
Posts: 37
Received Thanks: 50
|
Also ist der Wertebereich von player.x nun 0-9 oder 0-(9*64)?
Vllt hatte ich mich falsch ausgedrückt, bewegt der Spieler sich immer 1 Pixel oder immer 64?
|
|
|
01/25/2015, 18:14
|
#15
|
elite*gold: 0
Join Date: Mar 2011
Posts: 57
Received Thanks: 4
|
während beispielsweise die "D" taste gedrückt ist erhöht sich die x-koordinate an der das Spieler BITMAp geblittet wird um 2. Der Spieler kann sich also "stufenlos" bewegen.
Code:
void Collision:: PlatformCollision(BITMAP *buffer, Player &player)
{
player.Platform = false;
for (int i = 0; i < mapSizeX; i++)
{
for (int j = 0; j < mapSizeY; j++)
{
if(ColMapFile[i][j] != 0)
{
if(!(player.y+player.animation->h<j*BlockSize || player.x > i*BlockSize+BlockSize || player.y > j*BlockSize+BlockSize || player.x+player.animation->w < i* BlockSize))
{
player.Platform = true;
}
}
}
}
}
tada die lösung 
Danke für deine Hilfe
|
|
|
Similar Threads
|
Ist die Kollisionsabfrage Serverside?
10/25/2013 - Minecraft - 2 Replies
Hey,
Ich frage mich grade ob die Kollisionsabfragen der BoundingBoxes Clientside oder Serverside passieren? Es gibt ja auch Mods womit man dann zum Beispiel auf dem Wasser laufen kann, und dabei wird ja eine BoundingBox auf das Wasser gelegt, so das man darauf laufen kann. Das funktioniert nun ja auch Auf Online Servern..
Wäre es nun nicht Theoretisch möglich sich Clientside Blöcke zu Spawnen, z.b in Form einer Treppe, und dann die Treppe hochzulaufen? Um zum Beispiel über Zäune von...
|
[Problem]Habe ein Problem und zwar spinnt mein VPC etwas(ohne Grund)?!
07/28/2011 - Metin2 Private Server - 10 Replies
Also wie schon gesagt meins Server spinnt wodurch kiks usw. kommen :(
ich lade euch die Screens in den Anhang, mit der Hoffnung, dass ihr mir helfen könnt :) wäre echt sehr nice :)
|
All times are GMT +1. The time now is 18:51.
|
|