-1
\$\begingroup\$

I'm currently trying to program a breakout game to distribute it as an example game for my own game engine. http://game-engine-for-java.googlecode.com/

But the problem here is that I can't get the bouncing condition working properly. Here's what I'm using.

public void collision(GObject other){
    if (other instanceof Bat || other instanceof Block){
        bounce();
    } else if (other instanceof Stone){
        other.destroy();
        bounce();
    }
    //Breakout.HIT.play();
}

And here's by bounce() method

public void bounce(){
    boolean left = false;
    boolean right = false;
    boolean up = false;
    boolean down = false;
    if (dx < 0) {
        left = true;
    } else if (dx > 0) {
        right = true;
    }
    if (dy < 0) {
        up = true;
    } else if (dy > 0) {
        down = true;
    }
    if (left && up) {
        dx = -dx;
    }
    if (left && down) {
        dy = -dy;
    }
    if (right && up) {
        dx = -dx;
    }
    if (right && down) {
        dy = -dy;
    }
}

The ball bounces the bat and blocks but when the block is on top of the ball, it won't bounce and moves upwards out of the game.

What I'm missing? Is there anything to implement? Please help me..

Thanks

EDIT:

Have changed the bounce method.

public void bounce(GObject other){
    //System.out.println("y : " + getY() + "     other.y + other.height - 2 : " + (other.getY() + other.getHeight() - 2));
    if (getX()+getWidth()>other.getX()+2){
        setHorizontalDirection(Direction.DIRECTION_RIGHT);
    } else if (getX()<(other.getX()+other.getWidth()-2)){
        setHorizontalDirection(Direction.DIRECTION_LEFT);
    }
    if (getY()+getHeight()>other.getY()+2){
        setVerticalDirection(Direction.DIRECTION_UP);
    } else if (getY()<(other.getY()+other.getHeight()-2)){
        setVerticalDirection(Direction.DIRECTION_DOWN);
    }
}

EDIT:

Solved now. See the changed method in my answer.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Had solved this problem by changing the bounce method to the following

public void bounce(GObject other){
    // The right most point
    float rightx = getX()+getWidth()+1;
    float righty = getY();
    // The left most point
    float leftx = getX()-1;
    float lefty = getY();
    // The top most point
    float topx = getX();
    float topy = getY()-1;
    // The bottom most point
    float bottomx = getX();
    float bottomy = getY()+getHeight()+1;
    if (other.getBounds().contains(rightx, righty)){
        // The right point intersects. So move left
        setHorizontalDirection(Direction.DIRECTION_LEFT);
    } else if (other.getBounds().contains(leftx, lefty)){
        // The left point intersects. So move right
        setHorizontalDirection(Direction.DIRECTION_RIGHT);
    }
    if (other.getBounds().contains(topx, topy)){
        // The top point intersects. So move down
        setVerticalDirection(Direction.DIRECTION_DOWN);
    } else if (other.getBounds().contains(bottomx, bottomy)){
        // The bottom point intersects. So move up
        setVerticalDirection(Direction.DIRECTION_UP);
    }
}

Found the solution here.

http://zetcode.com/tutorials/javagamestutorial/breakout/

Changed the solution ( This works perfectly )

/**
 * This object bounces back from the other object in a natural way. Please
 * realize that the bounce is not completely accurate because this depends
 * on many properties. But in many situations the effect is good enough. Had
 * some bugs in pixel perfect detection mode if the image has a larger area
 * of complete alpha. If using PPCD, make the object fit the image size by
 * removing the alpha and resizing the image.
 */
public void bounce(GObject other){
    int xd = (int) ((other.x + other.getWidth() / 2) - (x + getWidth() / 2));
    int yd = (int) ((other.y + other.getHeight() / 2) - (y + getHeight() / 2));
    if (xd < 0) {
        xd = -xd;
    }
    if (yd < 0) {
        yd = -yd;
    }
    if (xd > yd) {
        dx = -dx;
    } else {
        dy = -dy;
    }
}
\$\endgroup\$
0
\$\begingroup\$

I would start with a very low resolution collision detection for example if you imagined everything had a rectangle around it (even the ball) you could store a Rectangle shape (keep it updated as the ball etc moves) then use

ballRect.intersects(blockRect)

From there if you check it returns true you can do a more detailed detect to determine the balls reaction to the hit for example sending it off at a different angle.

As for the walls you simply have a constant that is your left wall for example and then check

if(ball.x > LEFTWALL) {
  //bounce off wall logic here.
}

A simple way to redirect the ball is to flip an direction for example

if(ball.x > LEFTWALL) {
      dx *= -1; //will reverse the direction with no affect to speed of the x-axis
}

The only thing you need to know is what axis the bounce will affect if not both

Hope this helps :)

\$\endgroup\$
5
  • \$\begingroup\$ The collision detection is automatic. The engine uses pixel-perfect collision detection. Should I disable the collision detection? or should I implement the axis detection in the collision() method? \$\endgroup\$ Jul 7, 2012 at 1:29
  • 1
    \$\begingroup\$ Pixel Detection is the best method but it is also the slowest as it has to compare pixel to pixel, having a more basic detection like rectangle intersects would be faster and only need to use the pixel perfect after that if you can imagine the engine is checking every sprite pixel by pixel against every other pixel by pixel that could be slow :) \$\endgroup\$ Jul 7, 2012 at 14:27
  • \$\begingroup\$ Its giving me 90-120 fps with 512 mb ram installed \$\endgroup\$ Jul 7, 2012 at 15:35
  • \$\begingroup\$ And again, how to create the leftwall or something else? \$\endgroup\$ Jul 8, 2012 at 0:33
  • \$\begingroup\$ LEFTWALL could simply be a constant that has the position value of the left wall of the boundary. \$\endgroup\$ Jul 8, 2012 at 16:43

You must log in to answer this question.

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