Skip to Main Content

Java Programming

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Help with my Bouncing ball?

807589Jul 7 2008 — edited Jul 7 2008
Hey guys,

I really have the basis of my program working and everything however i just had one question. My Animation works by using the Alarm which uses the take notice method. The takeNotice then calls a move method that updates my ball coordinates. I am having trouble slowing down the animation. My question is how could I slow down the animation for the viewer without altering the velocity. My set period is at 25 milliseconds that makes the ball animation very smooth however when I increase the milliseconds the animation becomes sloppy and choppy. Does anyone have any ideas of how I could fix this problem???

Thanks guys

The BingBong class which sets up my environment...

/*
	BingBong.java
   
    
    This class defines and implements the demo itself.
	It also implements all the methods required to implement a "MouseListener".
	
	
*/

import java.awt.*;							
import java.awt.event.*;			
import java.awt.geom.*;




public class BingBong extends Frame
					implements	MouseListener, AlarmListener
						
{
//
//	The instance variables
//
	
	
    private Abutton resetButton,	   // My  Buttons
					throwButton,
					slowButton,
					fastButton;		

	private WindowClose myWindow =			//	A handle on the window
							new WindowClose();

	private int lastX, lastY;		//	To keep the mouse location
	
	private Alarm alarm;			//	We use an alarm to wake us up
	
	private Ball ball;				// Creating my one ball
	
//
//	Constructor
//	===========
//
//	The constructor defines a new frame to accommodate the drawing window.
//	It also sets the scene with the visualization of the element
//	and the buttons to manipulate the value of the element.
//
	public BingBong()
	{
		setTitle("Bing Bong");	//	We set the characteristics of our
		setLocation(50, 50);		//		drawing window
		setSize(420, 450);
		setBackground(Color.pink);
		setVisible(true);					

		addWindowListener(myWindow);		//	To check on the window
		addMouseListener(this);				//		and on the mouse
		
		int x = 53;      // Setting the start points for the button coordiates
		int y = 25;
		resetButton = new Abutton("Reset", Color.red, x, y);
		x += Abutton.BUTTON_WIDTH + 5;
		throwButton = new Abutton("Throw", Color.gray, x, y);
		x += Abutton.BUTTON_WIDTH + 5;
		slowButton = new Abutton("Slower", Color.yellow, x, y);
		x += Abutton.BUTTON_WIDTH + 5;
		fastButton = new Abutton("Faster", Color.green, x, y);
		
		alarm = new Alarm("Beep", this);	//	We "create" an alarm
		alarm.start();						//		and we get it started
		alarm.setPeriod(25);				// The alarm will go off every 35 milliseconds
			
	}	
	
    
	public void action()
	{
		System.out.println("\nClick on one of the buttons!\n");

		repaint();   // When the program is launched we will notify the user to click via the console
	}

//
//	The next method checks where the mouse is been clicked.
//	Each button is associated with its own action.
//
	private void check() 
	{    
		
			if (resetButton.isInside(lastX, lastY)) { 
				ball = null;  // If the reset button is hit the ball will go away
			}
			else if (throwButton.isInside(lastX, lastY)) {
				double randomX = 380*Math.random();    // Creating a random starting spot for the ball
				double randomY = 420*Math.random();
				double randomSpeedX = (9*Math.random()) + 1; //Giving the ball a random speed 
				double randomSpeedY = (7*Math.random()) + 1; // By adding at the end I protect		
															// in case the random creates a zero
				ball = new Ball(randomX, randomY, -randomSpeedX, -randomSpeedY); 
				// Calling the Ball constuctor to create a new ball
			}
			else if (slowButton.isInside(lastX, lastY)) { 
				double currentSpeedX = ball.getSpeedX();  // Getting the current ball's speed
				double currentSpeedY = ball.getSpeedY();
				double newSpeedX = currentSpeedX - (currentSpeedX/4); // Taking 1/4 of the current speed and 
				double newSpeedY = currentSpeedY - (currentSpeedY/4); // and subtracting it from the current speed
				
				ball.setSpeed(newSpeedX, newSpeedY); // Calling the set speed method
				
			}
			else if (fastButton.isInside(lastX, lastY)) { 
				double currentSpeedX = ball.getSpeedX(); // Getting the current ball's speed
				double currentSpeedY = ball.getSpeedY();
				double newSpeedX = (currentSpeedX/4) + currentSpeedX; // Taking 1/4 of the current speed and 
				double newSpeedY = (currentSpeedY/4) + currentSpeedY; // and adding it to the current speed
				
				ball.setSpeed(newSpeedX, newSpeedY); // Calling the set speed method
				
			}
			else  {
				System.out.println("What?"); // I did not understand the action
			}
			repaint();
	}
//
//	In order to use an alarm, we need to provide a takeNotice method.
//	It will be invoked each time the alarm goes off.
//
	public void takeNotice()
	{  
		
		if (ball != null){ // If the ball exists everytime the alarm goes off move the ball
			ball.move();
		}
		repaint();		//	Finally, we force a redrawing
	}


//
//	The only "graphical" method of the class is the paint method.
//
	public void paint(Graphics pane)
	{	
		if (throwButton != null)			//	When instantiated,
			throwButton.paint(pane);		//	we display all the buttons
		if (slowButton != null)				
			slowButton.paint(pane);
		if (fastButton != null)
			fastButton.paint(pane);
		if (resetButton != null)				
			resetButton.paint(pane);
		if (ball != null)					// Drawing the ball
			ball.paint(pane);
		pane.drawLine(10, 60, 10, 440);     // Using pixel coord. to draw the lines of our "box"
		pane.drawLine(10, 440, 410, 440);
		pane.drawLine(410, 440, 410, 60);
		pane.drawLine(10, 60, 70, 60);
		pane.drawLine(410, 60, 350, 60);
	}


	public void mouseClicked(MouseEvent event)
	{
		check();							//	Handle the mouse click
	}

	public void mousePressed(MouseEvent event)
	{
		lastX = event.getX();				//	Update the mouse location
		lastY = event.getY();

		flipWhenInside();					//	Flip any button hit by the mouse
	}

	public void mouseReleased(MouseEvent event)
	{
		flipWhenInside();
	}

	public void mouseEntered(MouseEvent event) {}
	public void mouseExited(MouseEvent event) {}

	private void flipWhenInside()
	{
		if (resetButton.isInside(lastX, lastY))  // Flips the buttons to emulate
			resetButton.flip();                  // a push down effect when clicked.
		else if (throwButton.isInside(lastX, lastY))
			throwButton.flip();
		else if (slowButton.isInside(lastX, lastY))
			slowButton.flip();
		else if (fastButton.isInside(lastX, lastY))
			fastButton.flip();
		    
		repaint();
	}



}	// end BingBong
My Ball Class holds its own unique characteristics.....
/*
 
 	Ball.java
 	Programmer: Jason Martins
 	7/2/08
    
 */

import java.awt.*;
import java.awt.event.*;

public class Ball
{   
	// My private variables:
	
	private double x = 0;    // The location of the ball.
	private double y = 0;   
	private Color color = Color.BLUE;
	private double speedX, speedY;  // The speed of my ball.
	private double gravity = 0.098; // The gravity effect (9.8 m per s).
	private double bounceFactor  = 0.97; // The bouncy ness of my ball.
	private final 
			double 
				DIAMETER = 21,	 // The size of my ball.
				LEFT_SIDE = 10,
				RIGHT_SIDE = 410,
				BOTTOM_BOX = 440;
	
	// The default constructor for the Ball.
	public Ball(){
		
	}
	// The Ball constructor will create an 
	// ball due its own unique x and y coordinate as well as its speed.
	public Ball(double x, double y, double speedX, double speedY){
		
		this.x = x;				// When a new ball is created,
		this.y = y;				// it will have 4 critical
		this.speedX = speedX;	// doubles. The x and y coordinate and its speed 
		this.speedY = speedY;   // horizontally and vertically.
	
	}
	//
	//	Drawing a ball
	//
	public void paint(Graphics pane)
	{
		pane.fillOval((int) x, (int)y, (int) DIAMETER, (int) DIAMETER);
		// The fillOval method will start from the specfied x and y and draw a oval based on size and height.
	}
	
	// Will set the color of the given ball, by the specific color passed.
	public void setColor(Color color){ 
		this.color = color;				// Sets the color of the ball.
		
	}
	// Returns the x coordinate the ball is current at.
	public double getX(){
		return x;
	}
	// Returns the y coordinate the ball is current at.
	public double getY(){
		return y;
	}
	// Returns the horizontal velocity of the ball. 
	public double getSpeedX(){
		return speedX;
	}
	// Returns the vertical velocity of the ball.
	public double getSpeedY(){
		return speedY;
	}
	// Sets the speed of the ball by the horizontal and vertical velocity passed.
	public void setSpeed(double newSpeedX, double newSpeedY){
		speedX = newSpeedX;
		speedY = newSpeedY;
	}
	// Will move the ball inside the frame depending on numerous factors.
	public void move(){
		
		x += speedX; // Add horizontal speed to the x location and update the location.
		y += speedY; // Add vertical speed to the y location and update the location.
		speedY += gravity; // Add gravity to the vertical speed and update the vertical speed.
		
		if(x <= LEFT_SIDE){ // If my x coordinate is equal to the boundry on the left.
			x = LEFT_SIDE;  // The ball bounces reversing the horizontal velocity.
			speedX = -speedX;  
		}	
		if(x + DIAMETER >= RIGHT_SIDE){ // If my x coordinate is equal to the boundry on the right.
			x = RIGHT_SIDE - DIAMETER; // The ball bounces reversing the horizontal velocity.
			speedX = -speedX;
		}
		/*if(y <= 60 && x <= 70){
			y = 60;
			x = 70;
			speedY = -speedY;
		}
		if(y <= 60 && x >= 350){
			y = 60;
			x = 350 - DIAMETER;
			speedY = -speedY;
		}*/
		if(y + DIAMETER >= BOTTOM_BOX){  // If my y coordinate is equal to the boundry on the bottom.
			y = BOTTOM_BOX - DIAMETER;   // The ball bounces reversing the vertical velocity times
			speedY = -speedY *  bounceFactor; // the bouncyness of the ball.
		}
		
			
		
		
	}
	
	
	
}
My Alarm Class.... given to us by our professor
/*
	
	Alarm.java
									A l a r m
									=========
	
	This class defines a basic timer, which "beeps" after a resetable delay.
	On each "beep," the alarm will notify the object registered when the timer
		is instantiated..
*/

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class Alarm
				extends Thread
{
	private AlarmListener whoWantsToKnow;	//	The object to notify
											//		in case of emergency

	private int delay = 0;					//	The first beep will occur
											//		without any delay

//
//	C o n s t r u c t o r s
//
	public Alarm()
	{
		super("Alarm");						//	With the default constructor,
		whoWantsToKnow = null;				//		nobody will be notified
	}

	public Alarm(AlarmListener someBody)
	{
		super("Alarm");						//	In general,  we expect to know who
		whoWantsToKnow = someBody;			//		(i.e., which object) to notify
	}

	public Alarm(String name, AlarmListener someBody)
	{
		super(name);						//	We can also give a name to the alarm
		whoWantsToKnow = someBody;
	}

//
//	The setPeriod method will set or reset the period by which beeps will occur.
//	Note that the new period will be used after reception of the following beep.
//
	public void setPeriod(int someDelay)
	{										//	Note:  The period should be expressed
		delay = someDelay;					//				in milliseconds
	}

//
//	The setPeriodicBeep method will keep on notifying the "object in charge"
//		at set time intervals.
//	Note that the time interval can be changed at any time through setPeriod.
//
	private void setPeriodicBeep(int someDelay)
	{
		delay = someDelay;

		try {
			while (true){						//	For as long as we have energy,
				Thread.sleep(delay);			//		first we wait
				if (whoWantsToKnow != null)		//		then we notify the
					whoWantsToKnow.takeNotice();//		responsible party
			}									//		(if anybody wants to hear)
		}
		catch(InterruptedException e) {
			System.err.println("Oh, oh ... " + e.getMessage());
		}
	}

//
//	The alarm is a Thread, and the run method gets the thread started, and running.
//
	public void run()
	{
		System.out.println("The alarm is now running.");
		setPeriodicBeep(delay);
	}

}	//	end of class Alarm
Thanks guys again
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Aug 4 2008
Added on Jul 7 2008
3 comments
87 views