Solved

Bouncing Ball

Posted on 1997-08-27
10
1,024 Views
Last Modified: 2008-03-04
Hi,

I'm going through the book "Java 1.1 Programming in 24 Hours," and I'm stuck on an exercise.  I've entered the code for a bouncing ball applet from the book, and for additional practice we've been told to "Change the...applet so the ball loses 10% of its bouncing strength each time it hits the ground.  You can do this by changing the height variable at a certain tile within the run() method."

Here's the run() method:

public void run() {
      while (true) {
            repaint();
            current += (float) 0.1;
            if (current > 3)
                  current = (float) 0;
            xPosition += xMove;
            if (xPosition > (getSize().width - 111))
                  xMove *= -1;
            if (xPosition < 1)
                  xMove *= -1;
            double bounce = Math.sin(current) * height;
            yPosition = (int) (height - bounce);
            try { Thread.sleep(200); }
            catch (InterruptedException e){ }
      }
}

I've tried at least a dozen different solutions, most of them involving reducing the height variable by 10% at various points in the run() method, but nothing's worked yet.  I even wrote another program to allow me to trace the values of the bounce height, but nothing's worked.  I'm not so sure I see the way in which the sin curve defines the movement of the ball.  Can someone point me in the right direction?

Thanks!
0
Comment
Question by:Raydot
  • 3
  • 3
  • 2
  • +2
10 Comments
 
LVL 10

Expert Comment

by:kollegov
ID: 1225881
you should add
height=0.9*height;

before this row:
double bounce = Math.sin(current) * height;

0
 
LVL 3

Author Comment

by:Raydot
ID: 1225882
No, something's wrong.  First of all I ran into a "incompatible type for =.  Explicit cast needed to convert double to float."  Error.  So I changed the line to "height = (float) 0.9 * height" (could I just have written "height *= (float) 0.9"?) and the error disappeared, but the ball bounces just like it did before.  Actually, this was one of the first things I tried when solving this problem for myself.  Can you think of something else I might be doing wrong?
0
 
LVL 10

Expert Comment

by:kollegov
ID: 1225883
you should use:
height=(float)(0.9*height);
if height is float type.

0
 
LVL 10

Expert Comment

by:kollegov
ID: 1225884
Oh well, how you browse this applet?
You should completly restart browser!
Close ALL windows and start it again to
restart applet, otherwise cached copy will  be
used, reload do not actually work.
You NEED to restart browser completly to get new one.


0
 
LVL 3

Author Comment

by:Raydot
ID: 1225885
OK:  Height was an int, I converted it to float so that it could be multiplied by 0.9.  I added the (float)(0.9 * height); line like you said.  I view the applet by using appletviewer, creating a new instance each and every time.  The ball still isn't losing any height.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 4

Expert Comment

by:rembo
ID: 1225886


Could you post the whole app?  I'm sure we can get it
pretty quickly if we can play with it.

-Tony

0
 
LVL 3

Author Comment

by:Raydot
ID: 1225887
Here it is.  The ball graphic is available at http://prefect.com/java24/hour18.html

import java.awt.*;

public class Bounce extends java.applet.Applet implements Runnable {

      Image ball;
      float current = (float) 0;
      Thread runner;
      int xPosition = 10;
      int xMove = 1;
      float yPosition = -1;
      int ballHeight = 102;
      int ballWidth = 111;
      float height;
      Image workspace;
      Graphics offscreen;

      public void init() {
            workspace = createImage(getSize().width, getSize().height);
            offscreen = workspace.getGraphics();
            setBackground(Color.white);
            ball = getImage(getCodeBase(), "tennis.jpg");
      }

      public void paint(Graphics screen) {
            height = getSize().height - ballHeight;
            if (yPosition == -1)
                  yPosition = height;
            offscreen.setColor(Color.white);
            offscreen.fillRect(0,0,getSize().width,getSize().height);
            offscreen.drawImage(ball, (int) xPosition, (int) yPosition, this);
            screen.drawImage(workspace,0,0,this);
      }

      public void start() {
            if(runner == null) {
                  runner = new Thread(this);
                  runner.start();
            }
      }

      public void run() {
            while (true) {
                  repaint();
                  current += (float) 0.1;
                  if (current > 3)
                        current = (float) 0;
                  xPosition += xMove;
                  if (xPosition > (getSize().width - 111))
                        xMove *= -1;
                  if (xPosition < 1)
                        xMove *= -1;
                  height = (float) (0.9 * height);
                  double bounce = Math.sin(current) * height;
                  yPosition = (int) (height - bounce);
                  try { Thread.sleep(200); }
                  catch (InterruptedException e){ }
            }
      }

      public void stop() {
            if (runner != null) {
                  runner.stop();
                  runner = null;
            }
      }

      public void update(Graphics screen) {
            paint(screen);
      }
}
            
0
 
LVL 1

Accepted Solution

by:
vmanocha earned 100 total points
ID: 1225888
The following program does what you are looking for. To look a the the changes that I made, search for "CHANGE" without quotes. Alsi I had to change the getSize() function call to size() function call. getSize() is not a valid Java function. And one more thing, the bounce decreases from the bottom. This is because the Y-axis increases form top to bottom and not from bottom to top (you will see what I mean when you run this program).

//=================================================
import java.awt.*;

public class Bounce extends java.applet.Applet implements Runnable {

      Image ball;
      float current = (float) 0;
      Thread runner;
      int xPosition = 10;
      int xMove = 1;
      float yPosition = -1;
      int ballHeight = 102;
      int ballWidth = 111;
      float height;
      Image workspace;
      Graphics offscreen;

      public void init() {
            workspace = createImage(size().width, size().height);
            offscreen = workspace.getGraphics();
            setBackground(Color.white);
            ball = getImage(getCodeBase(), "tennis.jpg");

            // CHANGE - height is initialize here instead of in paint method
            height = size().height - ballHeight;
      }

      public void paint(Graphics screen) {
            // CHANGE - moved reinitializtion of height everytime here
            // to the init method
            if (yPosition == -1)
                  yPosition = height;
            offscreen.setColor(Color.white);
            offscreen.fillRect(0,0,size().width,size().height);
            offscreen.drawImage(ball, (int) xPosition, (int) yPosition, this);
            screen.drawImage(workspace,0,0,this);
      }

      public void start() {
            if(runner == null) {
                  runner = new Thread(this);
                  runner.start();
            }
      }

      public void run() {
            while (true) {
                  repaint();
                  current += (float) 0.1;
                  if (current > 3)
                        current = (float) 0;
                  xPosition += xMove;
                  if (xPosition > (size().width - 111))
                        xMove *= -1;
                  if (xPosition < 1)
                        xMove *= -1;
                  double bounce = Math.sin(current) * height;
                  yPosition = (int) (height - bounce);

                  // CHANGE - change height only when the ball bounces and not everytime
                  // we move the ball
                  if (yPosition <= 0)
                  {
                        height = (float) (0.9 * height);
                  }

                  try { Thread.sleep(200); }
                  catch (InterruptedException e){ }
            }
      }

      public void stop() {
            if (runner != null) {
                  runner.stop();
                  runner = null;
            }
      }

      public void update(Graphics screen) {
            paint(screen);
      }
}
//=============================================
0
 
LVL 1

Expert Comment

by:vmanocha
ID: 1225889
And If you use the following paint function, the ball's bouncing decreases from the top:

//===============================================
      public void paint(Graphics screen) {
            // CHANGE - moved reinitializtion of height everytime here
            // to the init method
            if (yPosition == -1)
                  yPosition = height;
            offscreen.setColor(Color.white);
            offscreen.fillRect(0,0,size().width,size().height);
            offscreen.drawImage(ball, (int) xPosition, size().height - (int)yPosition - ballHeight, this);
            screen.drawImage(workspace,0,0,this);
      }
//==============================================

0
 
LVL 1

Expert Comment

by:gnawed
ID: 1225890
Good answer vman.  gnawed's comments helped me a lot too.  Everything's working fine.  FYI, size() is deprecated in JDK 1.1.3, the language I was using (stated in the question.)  That's why I was using getSize()...

Thanks!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now