Amazing Shapes

Your task is to create a frame of amazing shapes! Each shape has its own unique characteristics which is outlined below:

  • FallingShape - This shape falls to the bottom of the frame, and once there, it expands in width by 1px and shrinks in height by 1px until its width equals the sum of its original width plus its original height. It should fall at a rate of 20px per time cycle.
  • BouncingShape - This shape moves either horizontally or vertically (configurable through a constructor parameter) and bounces off the sides of the frame. Each time it bounces off a side, its speed doubles until it reaches its max speed of 80px. The initial speed should be set at 20px per time cycle in the constructor.
  • ColoringShape - This shape remains stationary, but changes its fill color each time cycle by reducing its Red, Green, and Blue values by 1 until each value equals zero. This shape should eventually turn black if ran long enough.

All of the above concrete classes should inherit from an abstract class called AmazingShape which was started below:

public abstract class AmazingShape
{
    private RectangularShape shape;
    private Color fillColor;
    private JComponent parentComponent;
 
    public abstract void act();
 
    public AmazingShape(RectangularShape inShape, Color inColor, JComponent inComponent)
    {
        . . .
    }
 
    public void draw(Graphics2D g2)
    {
        //Set the color on the graphics
        //Fill the shape on the graphics
    }
 
    //Add get methods for all the instance fields
}

Now we need a way to actually draw these AmazingShapes. In order to accomplish this task, we can create a class called DrawingComponent which will be responsible for storing all the AmazingShapes in an ArrayList, then in its paintComponent() method, we can instruct each AmazingShape to act() and draw() itself. Below is starter code to help you with this class:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import javax.swing.JComponent;
 
public class DrawingComponent extends JComponent
{
   private ArrayList<AmazingShape> shapes;
 
   public void setShapeList(ArrayList<AmazingShape> shapeList)
   {
      shapes = shapeList;
   }
 
   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
 
      //For all the shapes
         //Instruct the shape to act and draw
   }
 
}

Finally, we need a Driver class to create the frame, generate some random AmazingShape's, and execute a timer which triggers the DrawingComponent above to repaint itself every X milliseconds. Below is starter code to help you with this class:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;
 
public class Driver
{
 
   private static final int FRAME_WIDTH = 500;
   private static final int FRAME_HEIGHT = 500;
 
   public static void main(String[] args)
   {
      JFrame frame = new JFrame();
 
      frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
      frame.setTitle("The Amazing Shapes");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
      final DrawingComponent component = new DrawingComponent();
 
      ArrayList<AmazingShape> shapeList = randomShapeGenerator(20, component);
      component.setShapeList(shapeList);
 
      frame.add(component);
      frame.setVisible(true);
 
      class TimerListener implements ActionListener
      {
         public void actionPerformed(ActionEvent event)
         {
            component.repaint();
         }
      }
 
      ActionListener listener = new TimerListener();
 
      final int DELAY = 100; // Milliseconds between timer ticks
      Timer t = new Timer(DELAY, listener);
      t.start();
   }
 
   private static ArrayList<AmazingShape> randomShapeGenerator(int numShapes, JComponent parentComponent)
   {
    /*    
        Returns an ArrayList of random AmazingShape's. 
        An AmazingShape can either represent a Rectangle or Ellipse2D.Double (randomly chosen).
        Its upper left hand corner starting point must be within the frame's boundary. 
        FallingShape, BouncingShape, and ColoringShape should be randomly selected. 
        For BouncingShape, its direction should be randomly selected.
        For ColoringShape, its RGB values should be randomly selected.
    */
   }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License