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

2013/2/25

Pinball: Don't know how I can let the Ball bounce back from the paddle

BradM313 BradM313

2013/2/25

#
Hello y'all, I'm making a Pinball game but I got one problem, I don't know how I can let the Ball bounce back from the paddle. Ball.class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
 
public class Ball extends Actor
{
    double x,y,a=0,b=0,ang,angN,mag,angx,angy,magG;
    int numAng=0;
    
    protected void addedToWorld(World world){
         x=getX();
         y=getY();
         if(x>890 || x<10 || y>600 || y<10){
             getWorld().removeObject(this);
             return;
            }
         for(int f=0;f<360;f=f+5){
             if(!isColor(getX(),getY())){
                 numAng++;
                 angx=angx+getX();
                 angy=angy+getY();
                }
            }
        if(numAng!=0)getWorld().removeObject(this);
    }
   
    public void act()
    {
        x=x+a;
        y=y+b;
       
        if(y>595){
            getWorld().removeObject(this);
            return;
        }
       
        numAng=0;
        angx=0;
        angy=0;
        for(int f=0;f<360;f=f+10){
            if(!isColor((int)(x+5*Math.cos((f/180.0)*Math.PI)),(int)(y+5*Math.sin((f/180.0)*Math.PI)))){
                numAng++;
                angx=angx+Math.cos((f/180.0)*Math.PI);
                angy=angy+Math.sin((f/180.0)*Math.PI);
            }
        }
              
        for(int f=0;f<360;f=f+10){
            Actor actor = getOneIntersectingObject(Versnelling.class);
            if(actor != null){
                numAng++;
                angx=angx+Math.cos((f/180.0)*Math.PI);
                angy=angy+Math.sin((f/180.0)*Math.PI);
            }
        }
                   
        if(numAng>3){
                       
            while(numAng>20 && !Greenfoot.isKeyDown("c")){
                numAng=0;
                x=x-.1*angx;
                y=y-.1*angy;
                angx=0;
                angy=0;
                for(int f=0;f<360;f=f+10){
                    if(!isColor((int)(x+5*Math.cos((f/180.0)*Math.PI)),(int)(y+5*Math.sin((f/180.0)*Math.PI)))){
                        numAng++;
                        angx=angx+Math.cos((f/180.0)*Math.PI);
                        angy=angy+Math.sin((f/180.0)*Math.PI);
                    }
                }
            }
            while(numAng!=0 && !Greenfoot.isKeyDown("c")){
                numAng=0;
                y=y-.1*angy;
                x=x-.1*angx;
                for(int f=0;f<360;f=f+5){
                    if(!isColor((int)(x+5*Math.cos((f/180.0)*Math.PI)),(int)(y+5*Math.sin((f/180.0)*Math.PI)))){
                        numAng++;
                    }
                }
            }
            x=x-.1*a;
            y=y-.1*b;
            angN = Math.PI/2.0 + Math.atan2(angy,angx);
            mag = Math.sqrt(a*a + b*b);
            if(mag>.7)mag=mag-.5;
            ang = Math.atan2(b,a);
            if(Math.abs(angN-ang)<.7){
                angN = angN-.05;
                if(angN<ang)angN=angN+.1;
            }
            ang = -(ang-angN)+angN;
            a = mag*Math.cos(ang)*(.3 + .7*Math.abs(Math.cos(angN)));
            b = mag*Math.sin(ang)*(.3 + .7*Math.abs(Math.sin(angN)));
            magG = Math.sin(angN);
            if(angN>Math.PI/2.0 && angN<3*Math.PI/2.0){
                a = a + magG*Math.cos(angN);
                b = b + magG*Math.sin(angN);
            }
            a= (int)(a*40)/40.0;
            b= (int)(b*40)/40.0;
            if(Math.abs(a)<.01)a=Math.random()/10.0-.05;
           
 
        }else {
            if(Math.sqrt(a*a + (b+.1)*(b+.1)) < 8)b=b+.1;
        }
        setLocation((int)x,(int)y);
    }   
       public boolean isColor(int X,int Y){
        return ((Kast)getWorld()).isColor(X,Y);
    }
}
And a part of the world:
import greenfoot.*;
import java.awt.Color;

/**
 * The BrickWorld
 */
public class Kast extends World {
 
    private static int SizeX = 900;
    private static int SizeY = 600;
    
    GreenfootImage background = getBackground(); 
  
    /**
     * Nieuwe Kast
     */
    public Kast() {
       super(SizeX, SizeY, 1);
        GreenfootImage background = getBackground();
        background.setColor(Color.BLACK);
        background.fill();
        
        createStars(500);
        createOvals(15);
        drawLine();
        
        addObject(new Start(), 225, 120);
        addObject(new Ball(), 225, 100);
        addObject(new Links(), 360, 520);
        addObject(new Rechts(), 550, 520);
        addObject(new Versnelling(), 450, 300);
    }
   
    /**
     * sets the background color
     */
    public void setColor (Color color) {
        GreenfootImage background = new GreenfootImage(20,20);
        background.setColor(color);
        background.fill();
        setBackground(background);
    }
    
    private void createStars(int number)
    {
        GreenfootImage background = getBackground();            
        for (int i = 0; i < number; i++)
        {
             int x = Greenfoot.getRandomNumber( getWidth() );
             int y = Greenfoot.getRandomNumber( getHeight() );
             background.setColor(new Color(
                    Greenfoot.getRandomNumber(255),
                    Greenfoot.getRandomNumber(255),
                    Greenfoot.getRandomNumber(255)
             ));
             background.fillOval(x, y, 2, 2);
        }
    }

    /**
     * Crete a given number of stars in space.
     */
    private void createOvals(int number)
    {
        GreenfootImage background = getBackground();            
        for (int i = 0; i < number; i++)
        {
             int x = Greenfoot.getRandomNumber( getWidth() );
             int y = Greenfoot.getRandomNumber( getHeight() );
             background.setColor(new Color(255,255,255));
             background.fillOval(x, y, 25, 10);
        }
    }
   
  //some code
    
    public boolean isColor(int a,int b){
        return background.getColorAt(a,b).equals(Color.BLACK);
    }
}
BradM313 BradM313

2013/2/27

#
Really no one who could help me in the right direction? :(
danpost danpost

2013/2/27

#
Basically, you just use one of the collision detecting methods in the Actor class API and reverse the movement (negate the speed) in the y direction. This will take two conditions: if intersecting paddle and moving downward, then reverse the movement in the y direction.
BradM313 BradM313

2013/3/1

#
Hi, Thanks for you reply, I think I'm nearly there but it still won't work I tried this in the Ball.class:
 for(int f=0;f<360;f=f+10){
            Actor actor = getOneIntersectingObject(Paddle.class);
            if(actor != null){
                while(true){
                numAng++;
                angx=-angx+Math.cos((f/180.0)*Math.PI);
                angy=-angy+Math.sin((f/180.0)*Math.PI);
             }
            }
        }
danpost danpost

2013/3/1

#
This loop appears to be endless:
while(true){
    numAng++;
    angx=-angx+Math.cos((f/180.0)*Math.PI);
    angy=-angy+Math.sin((f/180.0)*Math.PI);
}
I cannot determine the use of the 'for' loop in this case and do not see a need for one, either. Nor, do I see the need for the 'while' loop. If using rotation for the direction of movement, to bounce on a horizontal surface, use:
setRotation(360-getRotation());
danpost danpost

2013/3/1

#
Let us say the paddle is a rectangle that is 80 wide by 6 high and is located in a world at (200, 580). If the x coordinate of the ball is between 160 and 240 (200-80/2 to 200+80/2), then the above rotation change would be used. If the x coordinate of the ball is outside this range but by less than half the width of the ball, then the bounce will use a different calculation; basically the same one as if two balls were colliding, which involves getting the angular direction to the point of contact (the corner of the paddle that is being collided with) from the center of the ball, call it 'angle':
setRotation(2*angle+(540-getRotation()));
Substituting 90 degrees for 'angle' in this statement will, when simplified, produce the previoius statement for horizontal bounce (the point of contact being directly below the center of the ball; or, the angle from the center of the ball to the point of contact is 90 degrees).
trash1000 trash1000

2013/3/1

#
    
    private void checkPaddle() {
        Actor paddle = getOneIntersectingObject(Paddle.class);
        if(paddle != null) { 
            bounce(padlle);
        }            
    }

    private void bounce(Actor a) {
        deltaY = -deltaY;
        int offset = getX()-a.getX();
        deltaX = deltaX+(offset/10);
    }  
Taken (and simplified) from my BreakOut scenario.
BradM313 BradM313

2013/3/1

#
Thanks both of you! I'm going to try it tomorrow, I'll let you know if it works! :)
BradM313 BradM313

2013/3/11

#
Tomorrow became today ;-) So, I tried both of you're solutions but neither work unfortunately. So I tried something else:
Actor actor = getOneIntersectingObject(Paddle.class);  
            if(actor != null){  
                numAng++;  
                angx=angx-Math.cos((f/180.0)*Math.PI);  
                angy=angy-Math.sin((f/180.0)*Math.PI);  
            }  
But the problem with this is that when the Paddle is "up" and the Ball hits the underside of the Paddle it goes straight down, but when it hits the upperside of the Paddle it just sticks there.
BradM313 BradM313

2013/3/16

#
Maybe someone else can help me? I'm a little stressed because we have to send it to the teacher coming monday, I also read this, http://www.greenfoot.org/topics/3232, but I can't use it because he's a classmate. So if someone can help me that'll be great. It's a bit frustating for me because I know I'm almost there :( An updated code of my Ball.class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
 
public class Ball extends Actor
{
    double x,y,a=0,b=0,ang,angN,mag,angx,angy,magG;
    int numAng=0;
    private double fired;
    
    private boolean sticky;
    private int counter;
       
    public Ball()
    {
        counter = 0;
    }
    
    protected void addedToWorld(World world){
         x=getX();
         y=getY();
         if(x>900 || x<10 || y>590 || y<10){
             getWorld().removeObject(this);
             return;
            }
         for(int f=0;f<360;f=f+5){
             if(!isColor(getX(),getY())){
                 numAng++;
                 angx=angx+getX();
                 angy=angy+getY();
                }
            }
         if(numAng!=0)getWorld().removeObject(this);
    }
    
    public void act()
    {            
       Kast theWorld = (Kast) getWorld();  

        if(!theWorld.isPaused)  
        {
        x=x+a;
        y=y+b;
        
        if(y>590){
            getWorld().removeObject(this);
            return;
        }
      
        numAng=0;
        angx=0;
        angy=0;
        for(int f=0;f<360;f=f+10){
            if(!isColor((int)(x+5*Math.cos((f/180.0)*Math.PI)),(int)(y+5*Math.sin((f/180.0)*Math.PI)))){
                numAng++;
                angx=angx+Math.cos((f/180.0)*Math.PI);
                angy=angy+Math.sin((f/180.0)*Math.PI);
            }
        
        
         
        if(numAng>3){

            x=x-.1*a;
            y=y-.1*b;
            angN = Math.PI/2.0 + Math.atan2(angy,angx);
            mag = Math.sqrt(a*a + b*b);
            if(mag>.7)mag=mag-.5;
            ang = Math.atan2(b,a);
            if(Math.abs(angN-ang)<.7){
                angN = angN-.05;
                if(angN<ang)angN=angN+.1;
            }
            ang = -(ang-angN)+angN;
            a = mag*Math.cos(ang)*(.3 + .7*Math.abs(Math.cos(angN)));
            b = mag*Math.sin(ang)*(.3 + .7*Math.abs(Math.sin(angN)));
            magG = Math.sin(angN);
            if(angN>Math.PI/2.0 && angN<3*Math.PI/2.0){
                a = a + magG*Math.cos(angN);
                b = b + magG*Math.sin(angN);
            }
            a= (int)(a*40)/40.0;
            b= (int)(b*40)/40.0;
            if(Math.abs(a)<.01)a=Math.random()/10.0-.05;
        }else {
            if(Math.sqrt(a*a + (b+.1)*(b+.1)) < 8)b=b+.1;
        }
        setLocation((int)x,(int)y);
       }
    } 
   
     public boolean isColor(int X,int Y){
        return ((Kast)getWorld()).isColor(X,Y); 
    }
}
Mamang_Superhero Mamang_Superhero

2013/3/18

#
please vote for my game...
SorrelCeasar SorrelCeasar

2013/3/18

#
mine too
You need to login to post a reply.