This site requires JavaScript, please enable it in your browser!
Greenfoot back
Tommy99
Tommy99 wrote ...

2015/5/12

Problem With Bouncing

Tommy99 Tommy99

2015/5/12

#
Hello. I am having a problem with bouncing. When the MainBall contacts the Ball, the MainBall is supposed to bounce off and the Ball is supposed to disappear. At the moment, the bounce does not occur and the only thing that happens is the ball disappearing. Here is the code for MainBall:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class MainBall extends SmoothMover
{
    private static final int RADIUS = 12;
    //Colliding balls and gravity. I can make a game where the ball breaks blocks.
    //Fill up a water container, the paddle hits balls.
    //More than one level.
    //Make a pinball game.
    //Round objects bouncing off round objects.
    
    //Make powerups.
    
    //If bullets is more than 0, I can shoot.
    //REMEMBER TO ADD GRAVITY.
    
    public MainBall()
    {
        int angle = Greenfoot.getRandomNumber(360);
        double velocity = Greenfoot.getRandomNumber(100) / 10.0 + 10.0;
        addForce(new Vector(angle, velocity));
    }
    
    public void act() 
    {
        move();
        accelerate(0.99);
        bounceOffWall();
        bounceOffBalls();
        bounceOffPaddle();
    }    
    
    public void bounceOffBalls()
    {
        Ball ball = (Ball)getOneIntersectingObject(Ball.class);
        if(ball != null){
            if(touching(ball)){
                doCollision(ball);
            }
        }
        getWorld().removeObject(ball);
    }
    
    
    
    
    public void bounceOffPaddle()
    {
        Paddle paddle = (Paddle)getOneIntersectingObject(Paddle.class);
        if(paddle != null){
            if(touching(paddle)){
                doCollision(paddle);
            }
        }
    }
    

    

    
    public boolean touching(SmoothMover other)
    {
        double dx = other.getExactX()-this.getExactX();
        double dy = other.getExactY()-this.getExactY();
        return Math.sqrt(dx*dx+dy*dy)<=RADIUS*2;
        
    }
    
    
    public void doCollision(SmoothMover other)
    {
        double dx = other.getExactX()-this.getExactX();
        double dy = other.getExactY()-this.getExactY();
        int angle = (int) Math.toDegrees(Math.atan2(dy,dx));
        double force = Math. abs(this.getSpeed()-other.getSpeed());
        other.addForce(new Vector(angle,force));
        this.addForce(new Vector(angle +180, force));
    }
    
    public void bounceOffWall()
    {
        if(getExactX() <= RADIUS || getExactX() >= getWorld().getWidth()-RADIUS){
            getMovement().revertHorizontal();
            move();
        }
        if(getExactY() <= RADIUS || getExactY() >= getWorld().getHeight()-RADIUS){
            getMovement().revertVertical();
            move();
        }
    }
}
davmac davmac

2015/5/12

#
Lines 75-77 look like they could be the culprit:
        double force = Math. abs(this.getSpeed()-other.getSpeed());
        other.addForce(new Vector(angle,force));
        this.addForce(new Vector(angle +180, force));
The 'force' it calculates will be the difference in speed between the two balls, not taking their angular velocity into account at all. So, If the balls are moving at the same speed, the force applied will be 0. If the other ball is not moving, the force applied will be exactly equal to the MainBall speed, which might stop the MainBall from moving (and will certainly slow it down to some degree). So, what do you want to happen - what exactly do you mean by "bounce"?
Tommy99 Tommy99

2015/5/12

#
I want the MainBall to bounce off the other balls, just like bouncing a basketball. The only problem is the part where I remove the other ball. I took that code out to test it, and it bounced off perfectly. When I put that code in (so it goes away when it's hit by the MainBall), the other balls just disappear when they contact MainBall.
danpost danpost

2015/5/13

#
Tommy99 wrote...
I want the MainBall to bounce off the other balls, just like bouncing a basketball. The only problem is the part where I remove the other ball. I took that code out to test it, and it bounced off perfectly. When I put that code in (so it goes away when it's hit by the MainBall), the other balls just disappear when they contact MainBall.
The entire post is so general that it is a bit confusing. The example for the bounce is vague. What part where you remove the other ball? What code did you take out for testing? Does 'disappear' mean they are removed from the world, hiding behind other actors, outside the bounds of the world, or something else? What code do you have for the 'other' balls?
Tommy99 Tommy99

2015/5/13

#
The code that I took out for testing is line 41, as I wanted to see if the MainBall bounces off the other balls if they don't get removed from the world. The other ball is removed in line 41 as well. Disappear means they are removed from the world. Other Balls code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
public class Ball extends SmoothMover
{

    Color color1;
    public void act() 
    {
        touchBullet();
        

    }    
    
    public void touchBullet()
    {
        Actor b = getOneIntersectingObject(Bullet.class);
        if(b!=null){
            BreakerWorld bw = (BreakerWorld)getWorld();
            bw.changeScoreNormal();
            getWorld().removeObject(b);
            getWorld().removeObject(this);
        }
    }
    
    
    
    
    

    public Ball()
    {
        GreenfootImage img = new GreenfootImage(30,30);

        int red = Greenfoot.getRandomNumber(256);
        int green = Greenfoot.getRandomNumber(256);
        int blue = Greenfoot.getRandomNumber(256);
        Color c = new Color(red,green,blue);
        color1=c;
        //Assigning values: not c=color1.
        img.setColor( c);
        img.fillOval(0,0,30,30);
        setImage(img);
        
    }

}



danpost danpost

2015/5/13

#
It looks like line 41 is misplaced. It should be up inside the 'if' code-block above it and then up inside the inner 'if' code-block of that one (again).
public void bounceOffBalls()
{
    Ball ball = (Ball)getOneIntersectingObject(Ball.class);
    if(ball != null && touching(ball)){
        doCollision(ball);
        getWorld().removeObject(ball);
    }
}
danpost danpost

2015/5/13

#
You may run into unwanted behavior if more than one ball intersects the MainBall object. It probably will not happen very often, but if the MainBall object was closely matched by speed and direction with another ball which cause the corner of the images to intersect for a short while, that intersecting time may be long enough to have another ball, head-on colliding with the MainBall object, to pass through without being detected. In other words, while 'getOneIntersectingObject' is concentrating on one ball, another may be able to slip by, undetected.
public void bounceOffBalls()
{
    for (Object obj : getIntersectingObjects(Ball.class)){
        Ball ball = (Ball)obj;
        if (touching(ball)){
            doCollision(ball);
            getWorld().removeObject(ball);
            break;
        }
    }
}
This would find one that is actually touching and deal with that one on this act cycle.
Tommy99 Tommy99

2015/5/14

#
I made a few changes and it now works perfectly. Thanks for the help, danpost and davmac.
You need to login to post a reply.