Here's the "challenge":
Below are two complete Java classes that, when run, paint a never-ending cascade of boxes down the screen ( Yay!
Your mission is to come up with some interesting modifications to it - or simply to use it as a model to come up with something completely different. Indulge your ego! Impress us!
...and, most importantly: Have Fun!
FallingBox class
Spoiler
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class FallingBox extends JComponent{
private Point xy;
private Dimension widHt;
private Color borderColor;
private Color fillColor;
private int speed;
private boolean onScreen;
private Container parent;
private static Random rand = new Random();
private final static int MAX_SPEED = 5;
public FallingBox(Container p){
parent = p;
onScreen = false;
}
public void initialize(){
// this gives each box a unique set of characteristics
speed = rand.nextInt(MAX_SPEED)+1;
int colorShift;
// this makes faster boxes brighter and slower boxes darker
switch(speed){
case 1:
colorShift = 0; break;
case 2:
colorShift = 20; break;
case 3:
colorShift = 40; break;
case 4:
colorShift = 60; break;
case 5:
colorShift = 80; break;
default:
colorShift = 100; break;
}
// define the box's dimensions
widHt = new Dimension(rand.nextInt(200)+1,rand.nextInt(150)+1);
// define the boxes starting position on the screen
// -widHt.height for the y coordinate means the box starts just
// offscreen a bit and then moves into frame
xy = new Point(rand.nextInt(parent.getWidth()),-widHt.height);
// define the box's outline color
borderColor = Color.red;
// define the box's fill color
fillColor = new Color(rand.nextInt(100)+colorShift,0,0);
// now that it exists, make it visible
onScreen = true;
}
public Graphics paintBox(Graphics g){
g.setColor(fillColor);
g.fillRect(xy.x, xy.y, widHt.width, widHt.height);
g.setColor(borderColor);
g.drawRect(xy.x, xy.y, widHt.width, widHt.height);
if(onScreen)
update();
else
initialize();
return g;
}
public int getSpeed(){
return speed;
}
private void update(){
// the box isn't moving sideways - just down - so we only need
// to increment its y value to move it down the screen
xy.y += speed;
// if the box has moved beyond the edge of the screen
// indicate that it's offscreen (which will cause it to
// be re-initialized to the top of the screen)
if(xy.y > parent.getHeight())
onScreen = false;
}
public boolean isOnScreen(){
return onScreen;
}
public static int getMaxSpeed(){
return MAX_SPEED;
}
}
BoxDropper class
Spoiler
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class BoxDropper extends JPanel {
private Timer animation;
private BufferedImage offScrImg;
private Graphics buffer;
private final int NUM_BOXES = 500;
private FallingBox[] arrayOfBoxes;
private int currBox;
private Container parent;
public BoxDropper(Container p){
// we pass in the container so we can know what it's dimensions are
parent = p;
this.setSize(parent.getSize());
offScrImg = new BufferedImage(parent.getWidth(),parent.getHeight(),BufferedImage.TYPE_INT_RGB);
buffer = offScrImg.createGraphics();
// every 16 milliseconds we're going to call go()
animation = new Timer(16, new ActionListener(){
public void actionPerformed(ActionEvent e){
go();
}
});
currBox = 0;
// Now that the container is set up and we defined what we're going
// to do each time animation timer fires an event, lets fill
// the arrayOfBoxes array with boxes!
this.getBoxes();
}
private void go(){
// repaint is what makes this animated
repaint();
// keep adding boxes until we reach the max
// this is just so we don't start with all the boxes
// ... I just think it looks better this way =)
if(currBox < NUM_BOXES-1)
currBox++;
for(int i = 0; i < NUM_BOXES; i++){
if(!arrayOfBoxes[i].isOnScreen()){
arrayOfBoxes[i] = new FallingBox(this);
arrayOfBoxes[i].initialize();
}
}
}
public void getBoxes(){
arrayOfBoxes = new FallingBox[NUM_BOXES];
for(int i = 0; i < arrayOfBoxes.length; i++){
arrayOfBoxes[i] = new FallingBox(this);
arrayOfBoxes[i].initialize();
}
// once we have all the boxes, let's start things up!
animation.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g); // call JPanels paintComponent method
// paint the background black
buffer.setColor(Color.black);
buffer.fillRect(0, 0, this.getWidth(), this.getHeight());
// draw each FallingBox from the array of boxes
// begin with the slow ones so they are in the back
// end with the fast ones so they are in front
for(int s = 1; s <= FallingBox.getMaxSpeed(); s++){
for(int i = 0; i <= currBox; i++){
if(arrayOfBoxes[i].getSpeed() == s)
// paint the box to the graphics context
buffer = arrayOfBoxes[i].paintBox(buffer);
}
}
// this just writes the number of boxes being displayed in the
// top left corner - it's optional
buffer.setColor(Color.red);
buffer.drawString(Integer.toString(currBox), 10, 10);
// draw the off-screen image to the components graphics context
// remember - buffer is the graphics context of offScrImg
// that means we have to then paint offScrImg to the component
g.drawImage(offScrImg, 0, 0, this);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Falling Boxes");
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(dim);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BoxDropper bd = new BoxDropper(frame);
frame.add(bd);
frame.setVisible(true);
}
}

New Topic/Question
Reply



MultiQuote







|