I start from the BigBang:

import javax.swing.*; 
import java.awt.event.*; 
import java.awt.*; 

class BigBang extends JComponent implements KeyListener, ActionListener {
  Timer timer; 
  World world; 
  BigBang(int delay, World world) {
    timer = new Timer(delay, this); 
    this.world = world;
  } 
  public void start() {
    timer.start();  
  }
  BigBang(World world) {
    this(1000, world);  
  }
  public void paintComponent(Graphics g) {
    world.draw(g);  
  }
  public void actionPerformed(ActionEvent e) {
    world.update(); 
    if (world.hasEnded())
      timer.stop(); 
    this.repaint(); 
  }
  public void keyPressed(KeyEvent e) { 
    world.keyPressed(e); 
    this.repaint(); // took this from Lecture 16 added this line 
  } 
  public void keyTyped(KeyEvent e) { } 
  public void keyReleased(KeyEvent e) { } 
}

We also need the World interface:

import java.awt.*; 
import java.awt.event.*; 

interface World {
  public void draw(Graphics g);
  public void update(); 
  public boolean hasEnded();
  public void keyPressed(KeyEvent e); 
}

What else do I need? 

What does our World look like? 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

class StageTwo implements World {
  public void draw(Graphics g) { 
    System.out.println("World being drawn."); 
  } 
  public void update() { 
    System.out.println("World getting older."); 
  }
  public boolean hasEnded() { 
    return false; 
  } 
  public void keyPressed(KeyEvent e) { 
    System.out.println("Ouch."); 
  } 
  public static void main(String[] args) {
    BigBang game = new BigBang(100, new StageTwo()); 
    JFrame frame = new JFrame("Stage Two of Semester Project"); 
    frame.getContentPane().add( game ); 
    frame.addKeyListener( game ); 
    frame.setVisible(true); 
    frame.setSize(400, 400); 
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
    game.start(); 
  }
}

I can run this program already. 

What do we have in our world? 

(a) a bunch of dead circles

(b) a launcher of new circles one at a time 

(c) a bullet (may be moving) 

public class Launcher {
  
}

public class Circle {
  
}

class StageTwo implements World {
  Circle bullet; 
  Launcher launcher; 
  ArrayList<Circle> circles;
  public void draw(Graphics g) { 
...

So now that I know what the world looks like I should create an initial world.

  public StageTwo() {
    this.bullet = new Circle(); 
    this.launcher = new Launcher(); 
    this.circles = new ArrayList<Circle>(); 
  }

Next I have to draw the world so here's what I do: 

import java.awt.*;

...
  public void draw(Graphics g) {
    
  }  
...

These changes in both Launcher.java and Circle.java

  ... 
    for (Circle c : this.circles) 
      c.draw(g); 
    this.launcher.draw(g); 
    this.bullet.draw(g); 
    // System.out.println("World being drawn."); 
  ... 

This is in StageTwo.java 

Next I make the following changes in Circle.java:

...
  // all my circles will have a radius of 20 
  int radius = 20; 
  double x, y; // location of the center 
  Color color = Color.YELLOW;
  public Circle(int x, int y) {
     this.x = x;
     this.y = y; 
  }
...
    g.setColor(this.color);
    g.fillOval((int)(x - 20), (int)(y - 20), 40, 40); 
    g.setColor(Color.BLACK); 
    g.drawOval((int)(x - 20), (int)(y - 20), 40, 40); 
...

This means I modify one line in StageTwo.java accordingly: 

    this.bullet = new Circle(200, 200); 

Next I create the launcher and here are some changes

    frame.setSize(410, 440); // in StageTwo.java somewhere in main 

    this.bullet = new Circle(200, 400); // also in StageTwo.java elsewhere 

Also in Launcher.java:

  // not an option for customization 
  ... 
    g.drawOval(200 - 60, 400 - 60, 120, 120); // 60 is radius 
  ... 

Now I want the launcher to react to key events: 

...
  int angle = 90; // degrees 
...
    g.drawOval(200 - 60, 400 - 60, 120, 120); // 60 is radius 
    int x = (int) (200 + Math.cos(Math.PI * angle / 180) * 60); 
    int y = (int) (400 - Math.sin(Math.PI * angle / 180) * 60); 
    g.fillOval(x - 5, y - 5, 10, 10); // little circle is 10 pixels wide 
...

In StageTwo.java we have this new snippet of code:

    int keyCode = e.getKeyCode(); 
    if (keyCode == 37) { // left arrow key 
      this.launcher.turnLeft();  
    } else if (keyCode == 39) { // right arrow key
      this.launcher.turnRight();  
    } else if (keyCode == 38) { // up arrow key
      
    } else {
      
    }

This needs to be supported by

  public void turnLeft() {
    this.angle += 1;  
  }
  public void turnRight() {
    this.angle -= 1;  
  }

The code above in Launcher.java

So next time we reconstruct quickly this stage and finish it. 

--