Hello all,
I am currently experimenting collision detection of sprites in Urho2D. To do that, I have create a wall and a tennis ball as shown on the picture below:
I can control the ball movement using the key pad (left, right, down and up) and I move the ball until it collides with the wall. I do not want to rely on any physics for ball movement (like gravity for example).
In my code, I have connected the events E_PHYSICSBEGINCONTACT2D and E_PHYSICSENDCONTACT2D to detect when the collision begins and when it ends.
I do not want the ball to go through the wall, consequently this means that when I press the down key to move the ball toward the wall, the first thing I do before actually moving it is to store its current position. Then I apply the ball movement like this:
void TestSprite::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
using namespace Update;
float time_step = eventData[P_TIMESTEP].GetFloat();
mPreviousPosition = mBallNode->GetPosition2D();
switch(mDirection)
{
case DOWN:
mBallNode->SetPosition2D(mPreviousPosition + Vector2(0.0f, -mSpeed * time_step));
break;
case UP:
mBallNode->SetPosition2D(mPreviousPosition + Vector2(0.0f, mSpeed * time_step));
break;
case LEFT:
mBallNode->SetPosition2D(mPreviousPosition + Vector2(-mSpeed * time_step, 0.0f));
break;
case RIGHT:
mBallNode->SetPosition2D(mPreviousPosition + Vector2(mSpeed * time_step, 0.0f));
break;
}
}
I apply an offset to the stored position (the current one) using a specific speed and this gives the new ball position.
Then, when I detect the start of a collision (event E_PHYSICSBEGINCONTACT2D), this means that obviously the ball has hit the wall. In that case, I move the ball back to the previously stored position.
void TestSprite::BeginCollision(StringHash eventType, VariantMap& eventData)
{
mBallNode->SetPosition2D(mPreviousPosition);
}
The ball is moved back so it cannot “enter” into the wall.
However, from that point, if I move the ball down again, then no more E_PHYSICSBEGINCONTACT2D event is triggered and the ball can cross the wall.
I have observed that I do not have any E_PHYSICSENDCONTACT2D event meaning that the engine did not detect the end of the collision. I assume this is why it does not detect any new collision.
My question is if it is possible to reset the collision state or something like that in such a way that when I move the ball back to its previous position (just before the collision), then the engine is able to detect a new collision.
Or is there any other way or algorithm to avoid having the ball going through the wall ?
Maybe someone has already implemented that behavior and can give me some tips, that will be greatly appreciated
Thanks!
Charles