Bounce

<< Sound Stuff | FinalProjectsTrailIndex | Billiards >>

Rather than respond to a action from a user, in this demo, a timer generates an event that makes the ball move. We don't load an image file, but instead draw graphics. We do load a sound file, though, so you'll need to download the sound file boing.wav and Set the default size to 800 by 600 (In Eclipse Properties->Run/Debug Settings->Bounce: Edit ->Parameters).

Ball.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
public class Ball {
	private int x;
	private int y;
	private int radius;
	private int rise;
	private int run;
	private boolean visable; 
	public Ball(int radius){
		x=randInt(350,450);
		y=randInt(250,350);
		this.radius=radius;
		rise=randInt(1,8);
		run=randInt(-8,8);
		setVisable(false);
	}
	public int randInt(int min, int max){
		return min+(int)((max-min)*Math.random());
	}
	public void move(){
		x+=run;
		y+=rise;
	}
	public void bounceVertical(){
		rise*=-1;
	}
	public void bounceHorizontal(){
		run*=-1;
	}
	public void draw(Graphics g){
		if (visable){
			Color c=g.getColor();
			g.setColor(Color.BLUE);
			g.fillOval(x-radius, y-radius, 2*radius, 2*radius);
			g.setColor(c);
		}		
	}
	public void setVisable(boolean visable) {
		this.visable = visable;
	}
	public boolean isVisable() {
		return visable;
	}
	public Rectangle2D area(){
		return new Rectangle2D.Double(x-radius, y-radius, 2*radius, 2*radius);
	}
	public void setRise(int rise){ this.rise=rise;}
	public void setRun(int run){ this.run=run;}
	public int getRise(){return rise;}
	public int getRun(){return run;}
}

Wall.java


import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
public class Wall {
	private Rectangle2D.Double rect;
	private Color color;
	private int x,y,width,height;
	public Wall(int x, int y, int width, int height){
		rect=new Rectangle2D.Double(x, y, width, height);
		this.x=x;
		this.y=y;
		this.width=width;
		this.height=height;
		setColor(Color.BLACK);
	}
	public boolean touches(Ball ball){
		return rect.intersects(ball.area());
	}
	public void draw(Graphics g){
		Color c=g.getColor();
		g.setColor(color);
		g.fillRect(x, y, width, height);
		g.setColor(c);
	}
	public void setColor(Color color) {
		this.color = color;
	}
	public Color getColor() {
		return color;
	}
}

Sound.java

import java.applet.*;
import java.net.URL;

public class Sound{
	private AudioClip clip;
	public Sound(String fileName, Applet a){
		URL soundToPlay = getClass().getResource(fileName);

		clip = a.getAudioClip(soundToPlay);

	}
	public void play(){
		clip.play();
	}
	public void loop(){
		clip.loop();
	}
}

Bounce.java

/**
 * A Sample Animation with a Restart button
 * 
 * @author Fr Chris Thiel, OFMCap
 * @version 12 May 2011
 */

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

import javax.swing.*;

public class Bounce extends Applet implements  ActionListener
{
    Sound boing;
    Timer timer;
    Image virtualMem;
    Graphics gBuffer;
    Ball ball;
    Wall top,bottom,left,right;
    int appletWidth;        
    int appletHeight; 
    int frame;
    int lastFrame;
    Button myButton;
    int count;
    // OUR CLASS IS A SUBCLASS OF APPLET
    /**
     * this init() method will be run at the beginning
     * and where we create the Listeners 
     */
    public void init()
    {
        boing = new Sound("boing.wav",this);
        ball = new Ball(10);
        top = new Wall(0,0,800,10);
        bottom = new Wall(0,590,800,10);
        left = new Wall(0,10,10,590);
        right = new Wall(790,10,10,590);
        appletWidth = getWidth();
        appletHeight = getHeight(); 
        frame=0;
        timer=new Timer(1, this);
        lastFrame=appletWidth;
        virtualMem = createImage(appletWidth,appletHeight);
        gBuffer = virtualMem.getGraphics();
        gBuffer.setColor(Color.white);
        gBuffer.fillRect(0,0,appletWidth,appletHeight);
        count=0;

        myButton= new Button("Do It Again");
        //the class is its own button listener
        myButton.addActionListener (this);
        add(myButton);      
    }

     public void paint(Graphics g)
    {
        //We draw using the object methods of
        // the graphics buffer, not what is
        // currently on the screen
        gBuffer.setColor(Color.white);
        gBuffer.fillRect(0,0,appletWidth,appletHeight);gBuffer.setColor(Color.black);

        gBuffer.setColor(Color.black);
        gBuffer.drawString("Frame "+frame, 20,20);
        gBuffer.drawString(count+" bounces", 20, 35);
        ball.draw(gBuffer); 
        top.draw(gBuffer);
        bottom.draw(gBuffer);
        left.draw(gBuffer);
        right.draw(gBuffer);

        //Now we send the result to the screen
        g.drawImage(virtualMem,0,0,this);
    }
    public void update(Graphics g)
    {
        paint(g); //get rid of flicker with this method
    }
    /**
     * ActionListener is an interface and
     * requires the actionPerformed() method
     * to be defined..in this case we
     * look for a restart button being pressed
     */
    public void actionPerformed(ActionEvent e){
        Object source = e.getSource();
        if (source == timer) {
        		frame++;
        		frame%=100;
        		ball.move();
        		if (top.touches(ball) || bottom.touches(ball)){
        			ball.bounceVertical();
        			boing.play();
        			count++;
        		}
        		if (left.touches(ball) || right.touches(ball)){
        			ball.bounceHorizontal();
        			boing.play();
        			count++;
        		}
        }
        else {//restart button pressed
              frame=0;
              if (timer.isRunning()) {
            	     timer.stop();
                  myButton.setLabel("Start");
                  ball.setVisable(false);
                  count=0;
               } else {
                   timer.start();
                   myButton.setLabel("Stop");
                   ball=new Ball(10);
                   ball.setVisable(true);
                   boing.play();  
               }                 
        }
        repaint();
    }
}