I am making a simple game with JavaFX, where a ball bounces around the screen after being released from the bottom (via a button). When the ball is bouncing around the pane, if it hits a Rectangle
it changes its color to blue.
I am attempting to add a method called checkBounds to keep track of when the ball (a Circle
) hits the Rectangle
. As soon as the ball comes into contact with the rectangle, the score should increase by 10. The scoring mechanism works, but it continues to increment with each frame that the ball takes through the Rectangle
, instead of only incrementing once when it enters. (eg. It should only go up by 10 one time, not continue going up by 10 the whole time the ball passes through). I callcheckBounds()
3 times in my timeline loop to check each rectangle on each loop iteration.
checkBounds(ball, gameSquare);
checkBounds(ball, gameSquare2);
checkBounds(ball, gameSquare3);
How would I fix this logic error? I've attempted several different options, but none seem to work.
private void checkBounds(Shape block, Rectangle rect) {
boolean collisionDetected = false;
Shape intersect = Shape.intersect(block, rect);
if (intersect.getBoundsInLocal().getWidth() != -1) {
collisionDetected = true;
}
if (collisionDetected) {
score.setText(Integer.toString(currentScore.getCurrentValue()));
currentScore.incrementBy(10);
rect.setFill(Color.BLUE);
}
}
I believe what you want to detect is the state change of your collisionDetected
from false
to true
. One way to do this is to keep the state of the previous value as a member variable for each collision object. To do this, we need some identifying id for the rectangle, so you may want to pass in the id into the checkBounds
method:
private void checkBounds(Shape block, Rectangle rect, int id) {
we also need to create a member variable to store the states:
private HashMap<Integer,Boolean> previousCollisionStateMap = new HashMap<>();
and then inside your checkBounds
code, you can modify the condition to check for changes
Boolean prevState = previousCollisionStateMap.get(id);
if (prevState == null) { // this is just to initialize value
prevState = false;
previousCollisionStateMap.put(id,false);
}
if (!prevState && collisionDetected) {
score.setText(Integer.toString(currentScore.getCurrentValue()));
currentScore.incrementBy(10);
rect.setFill(Color.BLUE);
}
and don't forget to update the state at the end
previousCollisionStateMap.put(id,collisionDetected);