Computer Science 252
Problem Solving with Java

Fall 2015, The College of Saint Rose

ChainReaction Demo

A working demo of ChainReaction will appear below. Click inside the applet to interact with it.



ChainReaction BlueJ Project

Click here to download a BlueJ project for ChainReaction.


ChainReaction Source Code

The Java source code for ChainReaction is below. Click on a file name to download it.


ChainReaction.java

import java.awt.*;
import objectdraw.*;

/*
 * Chain Reaction:
 * 
 * On a mouse press, the user can place balls on the canvas;
 * On exiting the window, a simulation of a "chain reaction" begins:
 * the most recently drawn ball hits into the second most recently drawn,
 * which hits into the next ball, and so on.
 * The canvas is cleared when the mouse enters the window.
 *
 * Example from Williams College CS 134
 * by Andrea Danyluk, from March 2002.
 */

public class ChainReaction extends WindowController
{

    // x and y coordinates of the first ball drawn
    private static final int BALL_X = 300;
    private static final int BALL_Y = 100;

    // ball diameter
    private static final int SIZE = 10;

    // distance between balls
    private static final int DISP = 2*SIZE;

    // x coordinate of the next ball to be drawn
    private int ballX = BALL_X;

    // the list of all balls
    private BallList ballList;

    public void begin()
    {
        // list of balls is empty at first
        ballList = new BallList(null, null);
    }

    // draws a ball
    public void onMousePress(Location point)
    {
        ballList = new BallList(new FilledOval(ballX, BALL_Y, SIZE, SIZE, canvas), ballList);
        // update x coordinate for the next ball to be drawn
        ballX = ballX - DISP;
    }

    // cause the balls to begin hitting into each other in a "chain reaction"
    public void onMouseExit(Location point)
    {
        ballList.react();
    }

    // clears the canvas and empties the ball list
    public void onMouseEnter(Location point)
    {
        canvas.clear();
        ballList = new BallList(null, null);
        ballX = BALL_X;
    }

}

BallList.java

import java.awt.*;
import objectdraw.*;

/* 
 * Data structure to store a collection of balls
 * Andrea Danyluk
 * March 2002
 * 
 * $Id: BallList.java 2230 2013-10-27 02:26:10Z terescoj $
 */
public class BallList {
    // the most recently added ball
    private FilledOval first;

    // the rest of the list
    private BallList rest;

    public BallList(FilledOval aBall, BallList theRest)
    {
        first = aBall;
        rest = theRest;
    }

    // pre:
    // post: returns true iff the list of balls is empty
    public boolean isEmpty()
    {
        return (first == null);
    }

    // pre:
    // post: animates the motion of the ball list
    public void react()
    {
        new ReactiveBallList(this, 10);
    }

    // pre:
    // post: returns first
    public FilledOval getFirst()
    {
        return first;
    }

    // pre:
    // post: returns rest
    public BallList getRest()
    {
        return rest;
    }


}

ReactiveBallList.java

import java.awt.*;
import objectdraw.*;

/* 
 * Animator for a BallList
 * Andrea Danyluk
 * March 2002
 * 
 * Updated by Jim Teresco, The College of Saint Rose, Fall 2013
 * 
 * $Id: ReactiveBallList.java 2230 2013-10-27 02:26:10Z terescoj $
 */

public class ReactiveBallList extends ActiveObject {

    private static final int PAUSETIME = 20;
    private static final double SPEED = 1;

    // the list of balls to animate
    private BallList ballList;

    // distance that each ball should move
    private int distanceToMove;

    // the constructor here just remembers the BallList
    // and how much they're supposed to move, then
    // starts up the ActiveObject
    public ReactiveBallList (BallList aList, int distance) {
        ballList = aList;
        distanceToMove = distance;

        start();
    }

    // do our animation
    public void run() {
        FilledOval nextBall;
        double pixelsMoved;

        // process each ball in the list, animate each a bit
        // before moving on to the next
        while (!ballList.isEmpty()) {
            nextBall = ballList.getFirst();
            pixelsMoved = 0;
            while (pixelsMoved < distanceToMove) {
                nextBall.move(SPEED, 0);
                pause(PAUSETIME);
                pixelsMoved = pixelsMoved + SPEED;
            }
            ballList = ballList.getRest();
        }
    }
}