1
\$\begingroup\$

Goal: I am writing a prototype which has as many as 50 (Box2D) colored balls on the screen. I can drag any ball, and what I need to do is test whether the dragging ball has touched a ball of the same color:

My "Balls" are generated as follows:

public static ArrayList<Ball> balls = new ArrayList<Ball>();

//Spawn balls - add them to a list called "balls"
public void spawnBalls() {
    for(int numBalls = 0; numBalls < Constants.MAX_BALLS ; numBalls++) {
        balls.add(new Ball(world,MathUtils.random(0f,3.5f),MathUtils.random(9.0f,9.5f)));
    }
}

They are later rendered as follows:

//Render Balls
public void drawBalls(float delta) {
    for (Ball b : balls) {
        batch.draw(b.getTexture(), b.getX()-Constants.BALL_SIZE/2, b.getY()-Constants.BALL_SIZE/2, Constants.BALL_SIZE, Constants.BALL_SIZE);
        b.update(delta);
    }
}

I'm using MouseJoints to drag the balls around:

private Vector3 tmp = new Vector3();
private Vector2 tmp2 = new Vector2();

private QueryCallback queryCallback = new QueryCallback() {

    @Override
    public boolean reportFixture(Fixture fixture) {
        if(!fixture.testPoint(tmp.x, tmp.y))
            return true;

        jointDef.bodyB = fixture.getBody();
        jointDef.target.set(tmp.x, tmp.y);
        joint = (MouseJoint) world.createJoint(jointDef);
        return false;
    }

};

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    camera.unproject(tmp.set(screenX, screenY, 0));
    world.QueryAABB(queryCallback, tmp.x, tmp.y, tmp.x, tmp.y);
    return true;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    if(joint == null)
        return false;

    camera.unproject(tmp.set(screenX, screenY, 0));
    joint.setTarget(tmp2.set(tmp.x, tmp.y));
    return true;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    if(joint == null)
        return false;

    world.destroyJoint(joint);
    joint = null;
    return true;
}

Here is my Ball class so far:

public class Ball {

private float x, y;
World world;
public Texture img, red, yellow;
Sprite sprite;
Body body;
public static int color;
private Circle boundingCircle;

public float angle;

public Ball(World world, float x, float y) {

    //yellow = new Texture("yellow.png");
    int c = MathUtils.random(0,5);
    if(c == 0) {
        img = new Texture("red.png");
        //this.color = 0;
        this.setColor(0);
    } else if(c == 1) {
        img = new Texture("yellow.png");
        //this.color = 1;
        this.setColor(1);
    } else if(c == 2) {
        img = new Texture("blue.png");
        //this.color = 2;
        this.setColor(2);
    } else if(c == 3) {
        img = new Texture("green.png");
        //this.color = 3;
        this.setColor(3);
    } else if(c == 4) {
        img = new Texture("orange.png");
        //this.color = 4;
        this.setColor(4);
    } else if(c == 5) {
        img = new Texture("purple.png");
        //this.color = 5;
        this.setColor(5);
    }


    //img = new Texture("red.png");
    sprite = new Sprite(img);
    sprite.setPosition(x,y);
    sprite.setSize(1f,1f);
    //sprite.setRotation(90f);

    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    //bodyDef.position.set((sprite.getX() + sprite.getWidth()) / Constants.PIXELS_TO_METERS, (sprite.getY() + sprite.getHeight()) / Constants.PIXELS_TO_METERS);
    bodyDef.position.set((sprite.getX() + sprite.getWidth()), (sprite.getY() + sprite.getHeight()));

    //bodyDef.angularVelocity = 5;
    body = world.createBody(bodyDef);

    CircleShape circle = new CircleShape();
    circle.setRadius(Constants.BALL_SIZE/2);

    boundingCircle = new Circle();
    boundingCircle.set(x, y, Constants.BALL_SIZE/2);

    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = circle;
    fixtureDef.density = 0.9f;
    fixtureDef.restitution = 0.05f;
    fixtureDef.friction = 1f;

    float angle = MathUtils.radiansToDegrees * body.getAngle();
    sprite.setRotation(angle);
    body.createFixture(fixtureDef);
    circle.dispose();
}
}

Let's say that I drag a Yellow ball - I would like to be able to determine if I touch another Yellow ball with the one I'm dragging, and if so, destroy the two balls. I'm not sure whether I can achieve this simply using Box2D, or whether I should use Sprite collision instead.

Does anyone have an ideas about how best to implement these kind of tests. So on each ball collision, the balls (dragging & hit) need to return both of their colors, and if they match they can be destroyed.

Any help or direction would be appreciated greatly.

Thanks

James

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.