This program draws a train sitting on tracks when the program starts. The user can drag the train but it always stays on the tracks. When the user clicks the mouse, a puff of smoke is produced.
import java.awt.*;
import objectdraw.*;
/**
Demonstrates the variety of graphical constructs available in objectdraw
by drawing a picture using the shapes.
@author Barbara Lerner
*/
public class MovingTrain extends WindowController
{
// The train in the drawing
private Train train;
// The background
private FilledRect sky;
private FilledRect grass;
// Remember which object is being dragged, if either
private boolean trainGrabbed;
// Location where last drag started
private Location lastPoint;
// Colors for the background
private static final Color GRASS_COLOR = Color.GREEN;
private static final Color DARK_GRASS = GRASS_COLOR.darker();
private static final Color SKY_COLOR = Color.BLUE;
private static final Color DARK_SKY = SKY_COLOR.darker();
// Size of the window
private static final int WINDOW_WIDTH = 600;
private static final int WINDOW_HEIGHT = 400;
// Location of grass
private static final int GRASS_TOP = WINDOW_HEIGHT * 5 / 8;
// Train location
private static final int TRAIN_LEFT = 50;
private static final int TRACK_HEIGHT = WINDOW_HEIGHT * 7 / 8;
/**
* Draws a train of a fixed size at a fixed location when the program starts.
*/
public void begin () {
// Set the size of the window that we want to have. Note that the height includes
// the height of the menu bar above the drawing area. Therefore the drawing area will
// be slightly smaller than what we specify.
resize (WINDOW_WIDTH, WINDOW_HEIGHT);
// grass
grass = new FilledRect (0, GRASS_TOP, getWidth(), getHeight() - GRASS_TOP, canvas);
grass.setColor (GRASS_COLOR);
// sky
sky = new FilledRect (0, 0, getWidth(), GRASS_TOP, canvas);
sky.setColor (SKY_COLOR);
// The complex objects in the scene
train = new Train (TRAIN_LEFT, TRACK_HEIGHT, canvas);
// This is the train track that the car sits on. The parameters for a line are:
// x coordinate of first end point
// y coordinate of first end point
// x coordinate of second end point
// y coordinate of second end point
// canvas
// In this case, we need to be careful to pick coordinates that will draw
// a horizontal line directly beneath the train's wheels. We also want to be
// sure the line stretches the entire width of the window.
new Line (0, TRACK_HEIGHT, getWidth(), TRACK_HEIGHT, canvas);
}
/**
* On each mouse click produce a puff of smoke.
* @param point where the user clicked.
*/
public void onMouseClick (Location point) {
train.produceSmoke();
}
/**
* Begin a drag if the user presses the mouse button over the train or cloud
* @param point where the user pressed the mouse button down
*/
public void onMousePress (Location point) {
// Prepare to drag the train
if (train.contains (point)) {
trainGrabbed = true;
lastPoint = point;
}
}
/**
* Drag the train or cloud if either were selected
* @param point where the mouse is at the end of the drag
*/
public void onMouseDrag (Location point) {
// Drag the train
if (trainGrabbed) {
// The train only moves horizontally, so ignore how far the mouse moved vertically
double dx = point.getX() - lastPoint.getX();
train.move (dx);
lastPoint = point;
}
}
/**
* End the drag
* @param point where the mouse is when the button is released
*/
public void onMouseRelease (Location point) {
trainGrabbed = false;
}
}
import java.awt.*;
import objectdraw.*;
/**
A train consisting of multiple shapes. The train can move and change
color.
@author Barbara Lerner
*/
public class Train
{
// Locations and sizes of parts of the train
private static final int CAR_HEIGHT = 100;
private static final int CAR_WIDTH = 300;
private static final int WHEEL_SIZE = CAR_HEIGHT / 2;
private static final int SMOKESTACK_HEIGHT = CAR_HEIGHT / 2;
private static final int SMOKESTACK_WIDTH = CAR_WIDTH / 6;
private static final int SMOKE_HEIGHT = SMOKESTACK_HEIGHT;
private static final int SMOKE_WIDTH = SMOKESTACK_WIDTH / 2;
// Distance train moves as on each step
private static final int MOVE_AMOUNT = CAR_WIDTH / 10;
// Colors of the train parts
private static final Color CAR_COLOR = Color.RED;
private static final Color DARK_CAR = CAR_COLOR.darker();
private static final Color WHEEL_COLOR = Color.BLACK;
private static final Color DARK_WHEEL = WHEEL_COLOR.darker();
private static final Color SMOKESTACK_COLOR = Color.DARK_GRAY;
private static final Color DARK_SMOKESTACK = SMOKESTACK_COLOR.darker();
private static final Color SMOKE_COLOR = new Color (230, 230, 230);
private static final Color DARK_SMOKE = SMOKE_COLOR.darker();
// The parts of the train
private FilledRect car;
private FilledOval backWheel;
private FilledOval frontWheel;
private FilledRect smokestack;
// Portion of screen to draw in
private DrawingCanvas trainCanvas;
/**
* Draws a train.
* @param left the back of the train car
* @param trackHeight height of the train track the car sits on
* @param canvas where to draw
*/
public Train (double left, double trackHeight, DrawingCanvas canvas) {
car = new FilledRect(left, trackHeight - CAR_HEIGHT - WHEEL_SIZE, CAR_WIDTH, CAR_HEIGHT, canvas);
car.setColor(CAR_COLOR);
backWheel = new FilledOval (left + WHEEL_SIZE, trackHeight - WHEEL_SIZE, WHEEL_SIZE, WHEEL_SIZE, canvas);
backWheel.setColor (WHEEL_COLOR);
frontWheel = new FilledOval (left + CAR_WIDTH - 2 * WHEEL_SIZE, trackHeight - WHEEL_SIZE, WHEEL_SIZE, WHEEL_SIZE, canvas);
frontWheel.setColor (WHEEL_COLOR);
smokestack = new FilledRect (left + CAR_WIDTH - 2 * SMOKESTACK_WIDTH, car.getY() - SMOKESTACK_HEIGHT, SMOKESTACK_WIDTH, SMOKESTACK_HEIGHT, canvas);
smokestack.setColor (SMOKESTACK_COLOR);
trainCanvas = canvas;
}
/**
* @return true if point is on the train. The smoke does not count as part of the train.
* @param point the location to check for containment
*/
public boolean contains (Location point) {
if (car.contains (point)) {
return true;
}
else if (backWheel.contains (point)) {
return true;
}
else if (frontWheel.contains (point)) {
return true;
}
else if (smokestack.contains (point)) {
return true;
}
// The point is not in any of the parts of the train
return false;
}
/**
* Move the train relative to its current location
* @param dx the distance to move right
* @param dy the distance to move down
*/
public void move (double dx) {
car.move (dx, 0);
backWheel.move (dx, 0);
frontWheel.move (dx, 0);
smokestack.move (dx, 0);
}
public FilledOval produceSmoke () {
FilledOval smoke = new FilledOval (smokestack.getX() + (SMOKESTACK_WIDTH - SMOKE_WIDTH) / 2,
smokestack.getY() - 1.5 * SMOKE_HEIGHT, SMOKE_WIDTH, SMOKE_HEIGHT, trainCanvas);
smoke.setColor(SMOKE_COLOR);
return smoke;
}
}