• 15
• 15
• 11
• 9
• 10

Collision detection (AABB) and velocity computation (ontouchevent)

This topic is 495 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hey everyone :).

I have found an amazing article about collision detection here on gamedev.net.
http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084
I spent the last few trying to implement the code in android java but I am facing a few difficulties.

So what I basically want to acheive.
I have a player object which is moved around the screen by touch input. You place your finger on the image and when it's placed on the image you can move it around. In Surfaceview ountouchevent I am using action_move and action_down to acheive this.
Then there isa non-movable object, a barrier. When the user moves the image over the barrier, the player-image should stay in front of the barrier and shouldn't move through it.

The aabb collision algorithm needs the following variables to work.
float x, y;
float w, h;
float vx, vy;

x,y are the position of the player, and w,h the width and height. I guess my problems come from computing the velocity vx and vy.
Since I am using ontouchevent I tried to compute the velocity with Android's VelocityTracker in the ontouchevent method. Here is my code.
What this code does: In "down" it checks if the finger was player on the player-image, then its set to "touched=true". If it's set to true and the user moves the finger, the image is moved around the screen in action_move. And then I am computing the velocity in action_move as well. computeCurrentVelocity(1000); gives pixels per second. mVelocityTracker.getXVelocity() gives the velocity. I am not computing the velocity in action_up, because the user could move towards the barrier several times without removing the finger from the screen.
Here is my code from the SurfaceView OnTouchmethod and below it how I use the velocity in AABB-algorithm code.

@Override
public boolean onTouchEvent(MotionEvent event){

int eventaction = event.getAction();
int index = event.getActionIndex();
int pointerId = event.getPointerId(index);

switch(eventaction) {
case MotionEvent.ACTION_MOVE:

// The velocity is computed here
mVelocityTracker.computeCurrentVelocity(1000);
this.vx = mVelocityTracker.getXVelocity();
this.vy = mVelocityTracker.getYVelocity();

x = (int)event.getX();
y = (int)event.getY();

if(touched) {
animation.getPlayer().setPositionx(x - offsetx);
animation.getPlayer().setPositiony(y - offsety);
}

break;
case MotionEvent.ACTION_DOWN:
if(mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
else {
mVelocityTracker.clear();
}

x = (int)event.getX();
y = (int)event.getY();

if( x > animation.getPlayer().getPositionx() &&
x < animation.getPlayer().getPositionx() + animation.getPlayer().getImage().getWidth()
&& y > animation.getPlayer().getPositiony()
&& y < animation.getPlayer().getPositiony() + animation.getPlayer().getImage().getHeight() ) {

offsetx = x - animation.getPlayer().getPositionx();
offsety = y - animation.getPlayer().getPositiony();
touched = true;
}
break;
case MotionEvent.ACTION_UP:
default:
mVelocityTracker.clear();
touched = false;
}

return true;

}


In my gameloop I am using the aabb algorithm http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084

and use the computed velocity there.


while(running) {

Execute AABB-algorithm for each barrier existing:

// Gets the two velocity-variables from the ontouchEvent, they are set in the ontouch-event
float vx = v.getvx();
float vy = v.getvy();

// I also tried another version with my delta-time in seconds, the time that passes
// between each frame (I use it for frame independency)
float vx = v.getvx() * delta;
float vy = v.getvy() * delta;

float xInvEntry, yInvEntry;
float xInvExit, yInvExit;

if (vx > 0.0f)
{
xInvEntry = barrier_current.getPositionx() - (player.getPositionx() + player.getImage().getWidth());
xInvExit = (barrier_current.getPositionx() + barrier_current.getImage().getWidth()) - player.getPositionx();
}

..... Rest of the AABB-Algorithm

}


Important info: For std::numeric_limits<float>::infinity(); I used Float.MAX_VALUE in Java. And for std::max(xEntry, yEntry); I used Float Math.max in Java.

When I move the player over the barrier, my code implementation doesn't show a collision.

The collision is detected at random places. It doesn't go into the collision detected part, if the player-image and barrier collide.

It would be very helpful, if someone could help me thanks.

Share on other sites

I'm not 100% sure about how you're doing things, but it looks like you might not be updating the position properly.

Here is some semi-pseudo code that roughly explains how it all fits together:

// player info
Vector2 currentPosition = position of the player object at the start of the frame
Vector2 newPosition = where the player is trying to move to during this frame
Vector2 boxSize = the size of the player

// collider info
Vector2 colliderPosition = position of the static object
Vector2 colliderSize = size of the static object

for each frame
{
Vector2 velocity = newPosition - currentPosition;

float t = SweptAABB(currentPosition, boxSize, velocity, colliderPosition, colliderSize);

currentPosition = Lerp(currentPosition, currentPosition + velocity, t);
}