2
\$\begingroup\$

I'm making a game in which the objective is to collect the maximum amount of balls(Rectangle) to get the highest score. The balls spawn randomly from the middle of every side of your smartphone, and you use the square in the middle of your screen (the square rotates 90 degrees to the right every time the screen is touched) to get the balls. Here's the square(Rectangle):

What I'm trying to accomplish here is to make so that if a ball hits the yellow side of the square you get one point but if a ball hits the black side of the square, you lose the game.

Here's what I have so far (Already have the collisions, rotation and the balls spawning):

@Override
public void create(){

    batch = new SpriteBatch();

    Ball = new Texture("energyball.png");
    Up = new Texture("up.png");

    upSprite = new Sprite(Up);

    upSprite.setOriginCenter();
    upSprite.setX(615);
    upSprite.setY(340);
    upSprite.setRegionWidth(64);
    upSprite.setRegionHeight(64);

    square = new Rectangle();

    square.set(630, 360, 32, 32);

    cam = new OrthographicCamera();
    cam.setToOrtho(false, 1280, 720);

    upSprite.setPosition(upSprite.getX(), upSprite.getY());

    // calls the functions to spawn balls randomly
    balls1 = new Array<Rectangle>();
    spawnBalls1();

    balls2 = new Array<Rectangle>();
    spawnBalls2();

    balls3 = new Array<Rectangle>();
    spawnBalls3();

    balls4 = new Array<Rectangle>();
    spawnBalls4();

    score();


    //if the screen is touched sprite rotates 90 degrees clockwise
    Gdx.input.setInputProcessor(new InputAdapter() {

        @Override
        public boolean touchDown(int x, int y, int pointer, int button) {

            return true;
        }

        @Override
        public boolean touchUp(int x, int y, int pointer, int button) {

            upSprite.rotate(-90);
            return true;
        }
    });


}


//shows score
private void score() {

    score = 0;
    showScore = "Score: 0";
    scoreFont = new BitmapFont();

}


//creates the balls and sets their position as well as the random timer for each
private void spawnBalls1() {

    ball1.x = MathUtils.random(639, 641);
    ball1.y = 720;
    ball1.width = 32;
    ball1.height = 32;
    balls1.add(ball1);
    lastDropTime = TimeUtils.nanoTime();

}

private void spawnBalls2() {

    ball2.x = 0;
    ball2.y = MathUtils.random(359, 361);
    ball2.width = 32;
    ball2.height = 32;
    balls2.add(ball2);
    lastDropTime = TimeUtils.nanoTime();
}

private void spawnBalls3() {

    ball3.x = MathUtils.random(639, 641);
    ball3.y = 0;
    ball3.width = 32;
    ball3.height = 32;
    balls3.add(ball3);
    lastDropTime = TimeUtils.nanoTime();
}

private void spawnBalls4() {

    ball4.x = 1280;
    ball4.y = MathUtils.random(359, 361);
    ball4.width = 32;
    ball4.height = 32;
    balls4.add(ball4);
    lastDropTime = TimeUtils.nanoTime();
}

@Override
public void render() {

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    cam.update();

    //draws the game itself as well as the balls on the screen
    batch.setProjectionMatrix(cam.combined);
    batch.begin();

    upSprite.draw(batch);

    //draws the balls
    for (Rectangle ball1 : balls1) {

        batch.draw(Ball, ball1.x, ball1.y);
    }

    for (Rectangle ball2 : balls2) {

        batch.draw(Ball, ball2.x, ball2.y);
    }

    for (Rectangle ball3 : balls3) {

        batch.draw(Ball, ball3.x, ball3.y);
    }

    for (Rectangle ball4 : balls4) {

        batch.draw(Ball, ball4.x, ball4.y);
    }

    scoreFont.setColor(1, 1, 1, 1);
    scoreFont.draw(batch, showScore, 25, 100);

    batch.end();

    // if the time minus the time of the last ball spawn is less than x then spawn another ball in a random place

    if (TimeUtils.nanoTime() - lastDropTime > 1000000000) {

        switch (MathUtils.random(4)) {

            case 0:
                spawnBalls1();
                break;

            case 1:
                spawnBalls2();
                break;

            case 2:
                spawnBalls3();
                break;

            case 3:
                spawnBalls4();
                break;
        }
    }

    Iterator<Rectangle> iter1 = balls1.iterator();
    while(iter1.hasNext()) {

        Rectangle balls1 = iter1.next();
        balls1.y -= 350 * Gdx.graphics.getDeltaTime();
        if (balls1.overlaps(square)) {

            score++;
            showScore = "Score: " + score;
            iter1.remove();
        }

    }

    Iterator<Rectangle> iter2 = balls2.iterator();
    while (iter2.hasNext()) {

        Rectangle balls2 = iter2.next();
        balls2.x += 550 * Gdx.graphics.getDeltaTime();
        if (balls2.overlaps(square)) {
            score++;
            showScore = "Score: " + score;
            iter2.remove();
        }

    }


    Iterator<Rectangle> iter3 = balls3.iterator();
    while(iter3.hasNext()) {

        Rectangle balls3 = iter3.next();
        balls3.y += 350 * Gdx.graphics.getDeltaTime();
        if (balls3.overlaps(square)) {

            score++;
            showScore = "Score: " + score;
            iter3.remove();
        }
    }

    Iterator<Rectangle> iter4 = balls4.iterator();
    while(iter4.hasNext()) {

        Rectangle balls4 = iter4.next();
        balls4.x -= 550 * Gdx.graphics.getDeltaTime();
        if (balls4.overlaps(square)) {

            score++;
            showScore = "Score: " + score;
            iter4.remove();
        }

    }

}

Will be really glad if anyone could help me out. Thanks!!

\$\endgroup\$
1
  • \$\begingroup\$ What is the issue? I've read this question twice and still can't make sense of what you actually need help with. \$\endgroup\$
    – eclmist
    Commented Oct 1, 2016 at 4:44

2 Answers 2

1
\$\begingroup\$

For important performance and clearly code you have to use Box2D.

If you create those rectangles in box2d world you can add them a fixture. So, your all rectangles will earn a unique fixture. Then you should give them a sensor to where your rectangles top side and set category bits/ mask bits (this is for understand which rectangle colliding which object). So, you no longer have to calculate the rotation,colliding and position factors.

Finally, you should add the ContactListener to your project for catch the collidings events.

I leave an example;

CircleObj.java

BodyDef bdef = new BodyDef();
        bdef.type = BodyDef.BodyType.DynamicBody;
        bdef.position.set(50 / PPM, 150 / PPM);
        body = world.createBody(bdef);

        CircleShape circleShape = new CircleShape();
        circleShape.setRadius(25 / PPM);

        FixtureDef fdef = new FixtureDef();
        fdef.shape = circleShape;
        fdef.filter.categoryBits = CIRCLE_BIT; //We told box2d that it's a circle
        fdef.filter.maskBits = TOP_SIDE_BIT; //will collide just TOP SIDE of the rectangle, if you want to collide with rectangle just add " | RECTANGLE_BIT 
        body.createFixture(fdef).setUserData(this);

RectangleObj.java

BodyDef bdef = new BodyDef();
        bdef.type = BodyDef.BodyType.DynamicBody;
        bdef.position.set(200 / PPM, 150 / PPM);
        body = world.createBody(bdef);


        PolygonShape pShape = new PolygonShape();
        pShape.setAsBox(20 / PPM, 25 / PPM);

        fdef = new FixtureDef();
        fdef.shape = pShape;
        fdef.filter.categoryBits = RECTANGLE_BIT; // It's a rectangle !
        fdef.filter.maskBits = CIRCLE_BIT; // Collide with circles
        body.createFixture(fdef).setUserData(this);

        //Defining the top side

        Vector2[] vertices = new Vector2[3];
        vertices[0] = new Vector2(25f / PPM, 25f / PPM);
        vertices[1] = new Vector2(25f / PPM, -25f / PPM);
        vertices[2] = new Vector2(55f / PPM, 0f / PPM);
        //Note : The values are almost the what should be.


        PolygonShape topShape = new PolygonShape(); 
        topShape.set(vertices);

        fdef.shape = topShape;
        fdef.isSensor = true;
        fdef.filter.categoryBits = TOP_SIDE_BIT;
        fdef.filter.maskBits = CIRCLE_BIT;
        b2body.createFixture(fdef);
        topShape.dispose();
\$\endgroup\$
0
\$\begingroup\$

You can solve it easy by making additional rectangle above the rectangle attached with it, and respond differently for each rectangle, by this way you can control the collision

\$\endgroup\$
1
  • \$\begingroup\$ yeah I've thought of that and tried doing but I can't seem to know how to properly do it, can you give me some help? Gladly appreciate it \$\endgroup\$
    – gafflx
    Commented Jun 21, 2016 at 15:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .