Hi there, thanks for answering! My code is very much similar to casey's around episode 45 to 50 I think it's when he implements it.
TestWall:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | internal b32
TestWall(r32 TestX, r32 TestY, r32 WallX, r32 WallMinY, r32 WallMaxY,
r32 *tMin, r32 TestDeltaX, r32 TestDeltaY)
{
b32 Hit = 0;
if(TestDeltaX != 0.0f)
{
r32 tResult = (WallX - TestX) / TestDeltaX;
r32 Y = TestY + TestDeltaY * tResult;
if(Y >= WallMinY && Y <= WallMaxY)
{
if(tResult >= 0.0f && *tMin > tResult)
{
*tMin = Max(0.0f, tResult - 0.01f);
Hit = 1;
}
}
}
return(Hit);
}
|
Collision detection loop: (It's inside my "game update" function)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 | v2 ddPlayerPos = {};
if(Input->Keys[KEY_LEFT].Down)
ddPlayerPos.x = -1;
if(Input->Keys[KEY_RIGHT].Down)
ddPlayerPos.x = 1;
if(Input->Keys[KEY_UP].Down)
ddPlayerPos.y = -1;
if(Input->Keys[KEY_DOWN].Down)
ddPlayerPos.y = 1;
ddPlayerPos *= 5000;
if(Input->Keys[KEY_LCTRL].Down)
{
ddPlayerPos *= 10;
}
ddPlayerPos += -4.0f*World->Player->dPos;
v2 PlayerDelta = 0.5f * ddPlayerPos * Square(Input->dt)
+ World->Player->dPos * Input->dt;
World->Player->dPos += ddPlayerPos * Input->dt;
// Colision detection PLAYER
r32 tRemaining = 1.0f;
for(u32 k=0; k<4 && tRemaining > 0.0f; ++k)
{
v2 WallNormal = {};
r32 tMin = tRemaining;
r32 PlayerDeltaX = PlayerDelta.x;
r32 PlayerDeltaY = PlayerDelta.y;
r32 PlayerX = World->Player->Pos.x;
r32 PlayerY = World->Player->Pos.y;
v2 WallMinCorner = World->Obstacle->Pos - 0.5f*World->Obstacle->Size - 0.5f*World->Player->Size;
v2 WallMaxCorner = World->Obstacle->Pos + 0.5f*World->Obstacle->Size + 0.5f*World->Player->Size;
// Left Wall
if(TestWall(PlayerX, PlayerY, WallMinCorner.x,
WallMinCorner.y, WallMaxCorner.y,
&tMin, PlayerDeltaX, PlayerDeltaY))
{
WallNormal = V2(-1, 0);
}
// Right Wall
if(TestWall(PlayerX, PlayerY, WallMaxCorner.x,
WallMinCorner.y, WallMaxCorner.y,
&tMin, PlayerDeltaX, PlayerDeltaY))
{
WallNormal = V2(1, 0);
}
// Top Wall
if(TestWall(PlayerY, PlayerX, WallMinCorner.y,
WallMinCorner.x, WallMaxCorner.x,
&tMin, PlayerDeltaY, PlayerDeltaX))
{
WallNormal = V2(0, 1);
}
// Bottom Wall
if(TestWall(PlayerY, PlayerX, WallMaxCorner.y,
WallMinCorner.x, WallMaxCorner.x,
&tMin, PlayerDeltaY, PlayerDeltaX))
{
WallNormal = V2(0, -1);
}
World->Player->Pos += tMin * PlayerDelta;
World->Player->dPos = World->Player->dPos - Inner(World->Player->dPos, WallNormal) * WallNormal;
PlayerDelta = PlayerDelta - Inner(PlayerDelta, WallNormal) * WallNormal;
tRemaining -= tMin;
}
|
This works perfect when World->Obstacle is not moving.
If I make it move with the code below, then I can easily get past it's walls with the Player when it happens that the Player is moving towards the Obstacle at the same time the Obstacle is moving towards the Player.
[code language=c
v2 ObsDelta = V2(sin(GameState->Timer*10) * 1000 * Input->dt, 0);
World->Obstacle->Pos += ObsDelta;
[/code]
The way I went about "solving" this is that after the Player's collision detection I make one for the obstacle:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | // Wall colission detection
v2 ObsDelta = V2(sin(GameState->Timer*10) * 1000 * Input->dt, 0);
v2 ObsPos = World->Obstacle->Pos;
{
r32 tMin = 1.0f;
v2 WallMinCorner = World->Player->Pos - 0.5f*World->Player->Size - 0.5f*World->Obstacle->Size;
v2 WallMaxCorner = World->Player->Pos + 0.5f*World->Player->Size + 0.5f*World->Obstacle->Size;
if(TestWall(ObsPos.x, ObsPos.y, WallMaxCorner.x, WallMinCorner.y, WallMaxCorner.y,
&tMin, ObsDelta.x, ObsDelta.y))
{
World->Player->Pos += ObsDelta;
}
if(TestWall(ObsPos.x, ObsPos.y, WallMinCorner.x, WallMinCorner.y, WallMaxCorner.y,
&tMin, ObsDelta.x, ObsDelta.y))
{
World->Player->Pos += ObsDelta;
}
World->Obstacle->Pos += ObsDelta;
}
|
This seems to be working for what I've tested so far.
So I'm wondering, one thing I could do is loop all entities and for each collision decide if it should glide or push the other entity, is that a good or bad idea? This would be a n^2 if I test all entities against each other so is there a better method?
Thanks for the recommendation, I had forgotten about the gjk thing casey talks about in handmade hero. Will watch the video. I figure that must be a better way of doing it.