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