Hallo zusammen,
Ich habe ein recht einfaches rechteck-basiertes System zur Kollisionserkennung das es ermöglicht bei diagonaler Bewegung die Kante "entlang zu rutschen".
Funktioniert soweit ganz gut, allerdings ist es Möglich, dass zB. der Spieler in das Kollisionsobjekt rein glitcht. Es scheint als ob es nur dann passieren kann, wenn man sich um die Ecken des Kollsionsobjektes bewegt.
Ich habe die Vermutung, dass das dann passiert, wenn die Bewegung die Ecke des Kollisionsobjektes abschneidet und so irgendwie dazu führt, dass die Rechtecke des Spielers und des Objektes ineinander rutschen.
Die relevanten Codestellen dazu sehen so aus:
Der UpdateCall erhält playerMovement aus der Tastatureingabe
|
C#-Quelltext
|
1
2
3
4
5
6
7
8
|
public void UpdatePlayer(GameTime gameTime, Vector2 playerMovement)
{
//...
playerMovement = CalculatePlayerMovement(Vector2.Normalize(playerMovement) * movementspeed);
if (playerMovement.Length() != 0)
MoveBy(playerMovement);
//...
}
|
Die CalculatePlayerMovement-Method checkt den Kartenrand, Kollisionsobjekte usw. Abhängig von der Richtung der Kollsion wird dann die x- or y-Bewegung auf 0 gesetzt.
|
C#-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
private Vector2 CalculatePlayerMovement(Vector2 movement)
{
Rectangle destRect = new Rectangle(BoundingBox.X + (int)movement.X, BoundingBox.Y + (int)movement.Y, Width, Height);
Vector2 returnValue = movement;
//...
foreach (Rectangle r in TileMap.collisionObjects)
{
if (destRect.Intersects(r))
{
string collsionSide = GetCollisionSide(destRect, r);
if (collsionSide == "top" || collsionSide == "bottom")
returnValue.Y = 0;
if (collsionSide == "left" || collsionSide == "right")
returnValue.X = 0;
}
}
//...
}
|
Die Erkennung der Kollsionsseite habe ich von
HIER.
|
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
24
25
26
27
28
|
private string GetCollisionSide(Rectangle destRect, Rectangle r)
{
float w = (destRect.Width + r.Width) / 2;
float h = (destRect.Height + r.Height) / 2;
float dx = destRect.Center.X - r.Center.X;
float dy = destRect.Center.Y - r.Center.Y;
if (Math.Abs(dx) <= w && Math.Abs(dy) <= h)
{
float wy = w * dy;
float hx = h * dx;
if (wy > hx)
{
if (wy > -hx)
return "top";
else
return "right";
}
else if (wy < hx)
{
if (wy > -hx)
return "left";
else
return "bottom";
}
}
return "";
}
|
Ich weis nicht so recht an welcher Stelle das Problem liegt. Wahrscheinlich übersehe ich nur eine Kleinigkeit, komme allerdings nicht drauf.
Die Erkennung der Kollsionsseite funktioniert soweit eigentlich tadellos, zumindest laut debug-Anzeige