📄 trafficcanvas.java
字号:
startingPoint.setLocation(0, (RECT_CORNERS[2].y + CURB_OFFSET)); vehicle = new Vehicle(startingPoint, EAST, _vehicleSpeed, VEHICLE_SIZE, this); // Have the vehicle paint itself on the canvas. vehicle.paint((Graphics2D) getGraphics()); // Put this new vehicle on the list. _vehicleList.add(vehicle); // South-bound starting on north edge. startingPoint.setLocation((RECT_CORNERS[1].x + CURB_OFFSET), 0); vehicle = null; vehicle = new Vehicle(startingPoint, SOUTH, _vehicleSpeed, VEHICLE_SIZE, this); vehicle.paint((Graphics2D) getGraphics()); _vehicleList.add(vehicle); // West-bound starting on east edge. startingPoint.setLocation((RECT_CORNERS[4].x - VEHICLE_SIZE.width), (RECT_CORNERS[1].y + CURB_OFFSET)); vehicle = new Vehicle(startingPoint, WEST, _vehicleSpeed, VEHICLE_SIZE, this); vehicle.paint((Graphics2D) getGraphics()); _vehicleList.add(vehicle); // North-bound starting on south edge. startingPoint.setLocation((RECT_CORNERS[2].x + CURB_OFFSET), (RECT_CORNERS[4].y - VEHICLE_SIZE.height)); vehicle = new Vehicle(startingPoint, NORTH, _vehicleSpeed, VEHICLE_SIZE, this); vehicle.paint((Graphics2D) getGraphics()); _vehicleList.add(vehicle); return; } public synchronized void handleRepaintTimeout() { // Tell each vehicle to move. ListIterator i; Vehicle vehicle; for (i = _vehicleList.listIterator(0); i.hasNext() == true; ) { vehicle = (Vehicle) i.next(); vehicle.move((Graphics2D) getGraphics()); } // Tell the stop light to paint itself only // if it needs to be. if (_lightChanged == true) { _lightChanged = false; _stopLight.paint((Graphics2D) getGraphics()); } // After the move, some vehicles may now be off the // canvas. Go through the "vehicle gone" list and // remove them from the vehicle list. The reason for // the two separate vehicle lists is to avoid // removing items from a list which is being // iterated over. for (i = _removeList.listIterator(0); i.hasNext() == true; ) { _vehicleList.remove((Vehicle) i.next()); } // Clear the remove list as its contents are no // longer needed. _removeList.clear(); return; } public boolean mayKeepGoing(Point location, int speed, Point direction) { boolean retval; Color lightsColor; int distance; // The vehicle may *not* keep going if 1) the light is // not green and 2) it has reached the light's stopping // point. The stopping point is the intersection + // (Number of vehicles already waiting at the light * // vehicle size) + (number of waiting vehicles - 1 * // distance between vehicles). lightsColor = getLightsColor(direction); distance = getDistanceToIntersection(location, direction); if (lightsColor != Color.green && (distance >= 0 && distance <= speed)) { retval = false; } else { retval = true; } return(retval); } public int getDistanceToIntersection(Point location, Point direction) { int retval = 0; int queueSize; int endOfLine; if (direction.x == EAST.x && direction.y == EAST.y) { queueSize = _stoplightQueue[WESTLIGHT].size(); endOfLine = RECT_CORNERS[1].x - ((queueSize + 1) * VEHICLE_SIZE.width) - (queueSize * VEHICLE_SEPARATION); retval = endOfLine - location.x; } else if (direction.x == SOUTH.x && direction.y == SOUTH.y) { queueSize = _stoplightQueue[NORTHLIGHT].size(); endOfLine = RECT_CORNERS[1].y - ((queueSize + 1) * VEHICLE_SIZE.height) - (queueSize * VEHICLE_SEPARATION); retval = endOfLine - location.y; } else if (direction.x == WEST.x && direction.y == WEST.y) { queueSize = _stoplightQueue[EASTLIGHT].size(); endOfLine = RECT_CORNERS[3].x + (queueSize * VEHICLE_SIZE.width) + (queueSize * VEHICLE_SEPARATION); retval = location.x - endOfLine; } else if (direction.x == NORTH.x && direction.y == NORTH.y) { queueSize = _stoplightQueue[SOUTHLIGHT].size(); endOfLine = RECT_CORNERS[3].y + (queueSize * VEHICLE_SIZE.height) + (queueSize * VEHICLE_SEPARATION); retval = location.y - endOfLine; } return(retval); } public Color getLightsColor(Point direction) { Color retval = Color.black; if (direction.x == EAST.x && direction.y == EAST.y) { retval = _stopLight.getLightsColor(Stoplight.WEST); } else if (direction.x == SOUTH.x && direction.y == SOUTH.y) { retval = _stopLight.getLightsColor(Stoplight.NORTH); } else if (direction.x == WEST.x && direction.y == WEST.y) { retval = _stopLight.getLightsColor(Stoplight.EAST); } else if (direction.x == NORTH.x && direction.y == NORTH.y) { retval = _stopLight.getLightsColor(Stoplight.SOUTH); } return(retval); } public void watchingLight(Point direction, Vehicle vehicle) { // If heading east, then watching west light. if (direction.x == EAST.x && direction.y == EAST.y) { _stoplightQueue[WESTLIGHT].add(vehicle); } else if (direction.x == SOUTH.x && direction.y == SOUTH.y) { _stoplightQueue[NORTHLIGHT].add(vehicle); } else if (direction.x == WEST.x && direction.y == WEST.y) { _stoplightQueue[EASTLIGHT].add(vehicle); } else if (direction.x == NORTH.x && direction.y == NORTH.y) { _stoplightQueue[SOUTHLIGHT].add(vehicle); } return; } public synchronized void vehicleGone(Vehicle vehicle) { _removeList.add(vehicle); return; } private void startNewVehicleTimer() { long currTime; // If the timer does not exist, create one. if (_newVehicleTimer == null) { // Use an inner class to receive the timeout. _newVehicleTimer = new javax.swing.Timer(_newVehicleTimerDuration, new NewVehicleTimeoutListener(this)); // Start creating new vehicle right away. _newVehicleTimer.setInitialDelay((int) INITIAL_NEW_VEHICLE_DELAY); currTime = System.currentTimeMillis(); _newVehicleTimer.start(); _nextNewVehicleTimeout = currTime + INITIAL_NEW_VEHICLE_DELAY; } else if (_newVehicleTimer.isRunning() == false) { currTime = System.currentTimeMillis(); _newVehicleTimer.restart(); _nextNewVehicleTimeout = currTime + _newVehicleTimerDuration; } return; } private void startRepaintTimer() { // If the repaint timer does not exist, make one. if (_repaintTimer == null) { // Use an inner class to receive the timeout. _repaintTimer = new javax.swing.Timer(REPAINT_TIME, new RepaintTimeoutListener(this)); } if (_repaintTimer.isRunning() == false) { _repaintTimer.start(); } return; }// Member data. //---------------------------------------- // DYNANMIC DATA // // The stop light at the center of it all. private Stoplight _stopLight; // List of all existing vehicles. LinkedList _vehicleList; // List of all defunct vehicles. LinkedList _removeList; // Timer data. int _newVehicleTimerDuration; long _nextNewVehicleTimeout; javax.swing.Timer _newVehicleTimer; javax.swing.Timer _repaintTimer; // How fast vehicles move. int _vehicleSpeed; // Set to true when the light has changed and // so needs to be repainted. boolean _lightChanged; // For each light, keep a list of vehicles waiting for that // light to turn green. When the light does turn green, tell // the vehicles that it is okay to continue. LinkedList[] _stoplightQueue; //---------------------------------------- // STATIC DATA // // Directions. public static final Point NORTH; public static final Point EAST; public static final Point SOUTH; public static final Point WEST; public static final int YELLOW_LIGHT = 0; public static final int EW_LIGHT = 1; public static final int NS_LIGHT = 2; // The canvas dimensions. private static final Point CANVAS_CORNER; private static final Dimension CANVAS_SIZE; // The "field" dimensions. private static final Point[] RECT_CORNERS; private static final Dimension FIELD_SIZE; // Road dimensions. private static final int ROAD_WIDTH; private static final int LANE_WIDTH; private static final int CURB_OFFSET; // Vehicle dimensions. private static final Dimension VEHICLE_SIZE; // Minimum distance between vehicles. private static final int VEHICLE_SEPARATION = 3; // Lane markings. private static final float DASH1[] = {10.0f}; private static final BasicStroke DASHED; // Timers. private static final int REPAINT_TIME = 16; private static final long INITIAL_NEW_VEHICLE_DELAY = 250; private static final int NORTHLIGHT = 0; private static final int SOUTHLIGHT = 1; private static final int EASTLIGHT = 2; private static final int WESTLIGHT = 3; static { // Speed is built into the direction. NORTH = new Point(0, -1); SOUTH = new Point(0, 1); EAST = new Point(1, 0); WEST = new Point(-1, 0); CANVAS_CORNER = new Point(0, 0); CANVAS_SIZE = new Dimension(250, 250); FIELD_SIZE = new Dimension((int) (CANVAS_SIZE.width * 0.4), (int) (CANVAS_SIZE.height * 0.4)); ROAD_WIDTH = CANVAS_SIZE.width - (FIELD_SIZE.width * 2); LANE_WIDTH = ROAD_WIDTH / 2; VEHICLE_SIZE = new Dimension(6, 6); CURB_OFFSET = (int) ((LANE_WIDTH - VEHICLE_SIZE.width) / 2); RECT_CORNERS = new Point[5]; RECT_CORNERS[0] = new Point(0, 0); RECT_CORNERS[1] = new Point(FIELD_SIZE.width, FIELD_SIZE.height); RECT_CORNERS[2] = new Point((int) (CANVAS_SIZE.width * 0.5), (int) (CANVAS_SIZE.height * 0.5)); RECT_CORNERS[3] = new Point((CANVAS_SIZE.width - FIELD_SIZE.width), (CANVAS_SIZE.height - FIELD_SIZE.height)); RECT_CORNERS[4] = new Point(CANVAS_SIZE.width, CANVAS_SIZE.height); DASHED = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, DASH1, 0.0f); } // Nested classes - implement timer listeners. private final class NewVehicleTimeoutListener implements ActionListener { public NewVehicleTimeoutListener(TrafficCanvas owner) { _owner = owner; } public void actionPerformed(ActionEvent e) { _owner.handleNewVehicleTimeout(); return; } private TrafficCanvas _owner; } private final class RepaintTimeoutListener implements ActionListener { public RepaintTimeoutListener(TrafficCanvas owner) { _owner = owner; } public void actionPerformed(ActionEvent e) { _owner.handleRepaintTimeout(); return; } private TrafficCanvas _owner; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -