Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm developing a simple game by andengine. I have 10 balls which are moving randomly on screen.i'm importing the balls as picture in sprites.if they move at the same coordinate , they pass though their own insides.but i want: if they move at the same coodirnates ,they should change their directions.so they cannot pass through their insides.how can i do that?

 private Runnable mStartCircle = new Runnable() {
  public void run() {
    int i = circleNumber++;
    Scene scene = Level1Activity.this.mEngine.getScene();
    float startY = -64.0f;
    float startX = randomNumber.nextFloat()*(CAMERA_WIDTH-70.0f);
    float a= randomNumber.nextFloat()*(CAMERA_WIDTH-70.0f);
    circles[i] = new Sprite(startX, startY, textRegCircle[i]);
    circles[i].registerEntityModifier(
            (IEntityModifier) new SequenceEntityModifier (
                        new MoveModifier(10.0f, circles[i].getX(),  a, 
                                circles[i].getY(),CAMERA_HEIGHT+64.0f)));
    }
    scene.getLastChild().attachChild(circles[i]);
    if (circleNumber < 10){
        mHandler.postDelayed(mStartCircle,1000);
    }
}

};

share|improve this question
add comment

2 Answers

Sounds like you need collision detection.

If you have sprites then its most likely you balls are on a tile of width X height dimensions. You probably want to create a 2D circle struct/class which is orientated at the origin of your sprite and moves about with the sprites when you update their position. Then you can do a simple square distance check between all your balls, if the distance is less than the sum of the radii then you've got a collision. Then, you could make them bounce by inverting their trajectory.

share|improve this answer
    
i updated the code above.can you tell me how it will be in code? –  Kadir Apr 24 '12 at 19:36
add comment

You use a sphere with sphere collision response.

The first requirement is that you separate velocity from position. What this means is that your balls will have a position they are at currently and they have a velocity (direction they want to travel in times speed). In the Update function of your GameObject, you only change velocity and don't touch position.

I will be using C++ throughout, because I am not familiar enough with Android's Java. The math can be easily ported though, once you understand the concepts behind them.

void Ball::Update(float a_DT)
{
    m_Velocity = m_Direction * m_Speed;
    m_Collision->SetPosition(m_Position);
    m_Collision->SetVelocity(m_Velocity);
}

Your collision handle consists of a class with the following members:

  • m_Position - 2D position
  • m_Velocity - Direction in which it is traveling times speed
  • m_Radius - Radius (half width) of the bounding sphere
  • m_Weight - Weight determines how unmovable an object is

You can determine whether two spheres collide by checking if the distance between their center points is smaller than their combined radii. In code:

bool CollisionSphere::CheckCollision(CollisionSphere* a_Other)
{
    if (m_Position.GetDistanceBetween(a_Other->m_Position) < m_Radius + a_Other->m_Radius) { return true; }

    return false;
}

So, how do you move the balls apart? Well, for my own game, I looked at this implementation:

http://gamasutra.com/view/feature/131424/pool_hall_lessons_fast_accurate_.php?page=3

And here's how I wrote it:

void CollisionSphere::CollisionResponse(CollisionSphere* a_Other)
{
    tb::Vec2 delta = m_Position - a_Other->m_Position;
    float d = delta.GetLength();
    tb::Vec2 mtd = delta * (((m_Radius + a_Other->m_Radius) - d) / d);

    float m1 = m_Weight;
    float m2 = a_Other->m_Weight;

    float im1 = 1.f / m_Weight;
    float im2 = 1.f / a_Other->m_Weight;

    // fix position

    m_Position += mtd * (im1 / (im1 + im2));
    a_Other->m_Position -= mtd * (im2 / (im1 + im2));

    tb::Vec2 v1 = m_Velocity;
    tb::Vec2 v2 = a_Other->m_Velocity;
    tb::Vec2 v = v1 - v2;
    float vn = v.GetDotProduct(mtd.GetNormalized());

    // check if moving apart
    if (vn > 0.f)
    {
        return;
    }

    // calculate the impulse for a new velocity vector

    tb::Vec2 impulse = m_Position.GetDirectionTo(a_Other->m_Position);

    float a1 = impulse.GetDotProduct(v1);
    float a2 = impulse.GetDotProduct(v2);

    float optimizedP = (2.f * (a1 - a2)) / (m1 + m2);

    // fix velocity

    m_Velocity = v1 - (impulse * optimizedP * m2);
    a_Other->m_Velocity = v2 + (impulse * optimizedP * m1);
}

Then, finally, you have a PostUpdate function for your objects:

void Ball::PostUpdate(float a_DT)
{
    if (m_Collision) 
    { 
        m_Position = m_Collision->GetPosition();
        m_Velocity = m_Collision->GetVelocity(); 
    }

    m_Position += m_Velocity * a_DT;
}

And this will fix balls colliding with each other.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.