MovingTrain


Your browser is ignoring the <APPLET> tag!

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;
     }
             
}