package awb; import java.awt.*; import java.net.*; import java.io.*; public class RaceTrack extends Canvas { public final static int MS_PER_UPDATE = 100; private Segment mySegs[][]; private Segment myOrdered[]; private Segment myLastSegment; private int myCurrentSegment; private RaceCar myCar; private Race myRace; private int myRows=3,myCols=3,myLength; private int myStartX, myStartY; private Image myBuffer; private Graphics myBufferG, myRealG; public RaceTrack(Race r, RaceCar rc, URL u, String f) { myRace = r; myCar = rc; readFile(u,f); setBackground(Color.green); myCar.putOnTrack(this); myCar.setLocation(myStartX, myStartY); myLastSegment = myOrdered[0]; myCurrentSegment = 0; } public void update() { // check for a crash if (! onTrack(myCar.getX(), myCar.getY())) { myCar.crash(); myRace.stopRace(); } // move car (if not crashed) myCar.setAcceleration(0); myCar.setTurn(0); myCar.update(); myCar.internalUpdate(); // check to see if completed lap Segment current = mySegs[myCar.getY() / Segment.SIZE] [myCar.getX() / Segment.SIZE]; if (current != myLastSegment) { myCurrentSegment = (myCurrentSegment + 1) % myLength; if (current == myOrdered[0]) myRace.incrementLap(); } myLastSegment = current; repaint(); } public URL getCodeBase() { return myRace.getCodeBase(); } public int getDistanceToLeft() { int r = myCar.getY() / Segment.getSize(); int c = myCar.getX() / Segment.getSize(); // System.out.println(" RaceTrack.getD2L(): " + r + ", " + c); return (mySegs[r][c].getLeftDist(myCar.getX() % Segment.getSize(), myCar.getY() % Segment.getSize())); } public int getDistanceToRight() { int x = myCar.getX(); int y = myCar.getY(); int r = y / Segment.getSize(); int c = x / Segment.getSize(); // System.out.println(" RaceTrack.getD2R(): " + r + ", " + c); return (mySegs[r][c].getRightDist(x % Segment.getSize(), y % Segment.getSize())); } public boolean onStraightaway() { int r = myCar.getY() / Segment.getSize(); int c = myCar.getX() / Segment.getSize(); return mySegs[r][c].isStraight(); } public int getTrackDirection() { int r = myCar.getY() / Segment.getSize(); int c = myCar.getX() / Segment.getSize(); // System.out.println(" RT.getTrackDir() checking " + r + ", " + c); return mySegs[r][c].getDir(myCar.getX() % Segment.getSize(), myCar.getY() % Segment.getSize()); } public int getDistanceToStraightaway() { int cs = myCurrentSegment; int dist = myOrdered[cs].getDistanceToEnd(myCar.getX() % Segment.getSize(), myCar.getY() % Segment.getSize()); // if on a straightaway, find end of it first if (myOrdered[cs].isStraight()) { cs = bump(cs,myLength); while (myOrdered[cs].isStraight()) { dist += myOrdered[cs].getLength(); cs = bump(cs,myLength); } } else cs = bump(cs,myLength); // if orig was curve, go to next // now look for next straightaway while (myOrdered[cs].isTurn()) { dist += myOrdered[cs].getLength(); cs = bump(cs,myLength); } return dist; } public int getDistanceToTurn() { int cs = myCurrentSegment; int dist = myOrdered[cs].getDistanceToEnd(myCar.getX() % Segment.getSize(), myCar.getY() % Segment.getSize()); cs = bump(cs,myLength); // start after current segment // add up all the straightaways until the next curve while (myOrdered[cs].isStraight()) { dist += myOrdered[cs].getLength(); cs = bump(cs,myLength); } return dist; } public boolean inTurn() { return myOrdered[myCurrentSegment].isTurn(); } public boolean inLeftTurn() { return myOrdered[myCurrentSegment].isLTurn(); } public boolean inRightTurn() { return myOrdered[myCurrentSegment].isRTurn(); } public boolean isNextTurnLeft() { int cs = myCurrentSegment + 1; // find next curve while (myOrdered[cs].isStraight()) cs = bump(cs,myLength); return myOrdered[cs].isLTurn(); } public boolean isNextTurnRight() { return (! isNextTurnLeft()); } public void repaint() { if (myCar == null) { super.repaint(); return; } if (myBuffer == null) { // System.out.println("had to create new Image"); myBuffer = createImage(size().width,size().height); myBufferG = myBuffer.getGraphics(); paint(myBufferG); // paint it all first time } else { myBufferG = myBuffer.getGraphics(); myBufferG.clipRect(myCar.getX()-20,myCar.getY()-20,40,40); paint(myBufferG); } myRealG = getGraphics(); myRealG.clipRect(myCar.getX()-20,myCar.getY()-20,40,40); myRealG.drawImage(myBuffer,0,0,this); } public void paint(Graphics g) { for (int row = 0; row < myRows; row++) { for (int col = 0; col < myCols; col++) { mySegs[row][col].draw(g); } } if (myCar != null) myCar.draw(g); } public Dimension preferredSize() { return new Dimension(Segment.getSize() * myCols, Segment.getSize() * myRows); } private void readFile(URL url, String f) { try { System.out.print("initializing track"); System.out.flush(); URL u = new URL(url,f); URLConnection uc = u.openConnection(); DataInputStream in = new DataInputStream(uc.getInputStream()); Segment.setSize(Integer.parseInt(getLine(in))); myRows = Integer.parseInt(getLine(in)); myCols = Integer.parseInt(getLine(in)); myLength = Integer.parseInt(getLine(in)); myStartX = Integer.parseInt(getLine(in)); myStartY = Integer.parseInt(getLine(in)); mySegs = new Segment[myRows][myCols]; myOrdered = new Segment[myLength]; String line="", enter, exit; int index; for (int row = 0; row < myRows; row++) { for (int col = 0; col < myCols; col++) { System.out.print("."); System.out.flush(); line = getLine(in); enter = line.substring(0,1); if (enter.equals("X")) { mySegs[row][col] = new Segment(col * Segment.SIZE, row * Segment.SIZE); } else { exit = line.substring(2,3); index = Integer.parseInt(line.substring(4, line.length())); mySegs[row][col] = new Segment(col*Segment.SIZE, row*Segment.SIZE,getCode(enter), getCode(exit)); myOrdered[index-1] = mySegs[row][col]; } } } System.out.println("done"); } catch (MalformedURLException ex) { System.out.println("error!\n"+ex); } catch (IOException ex) { System.out.println("error!\n"+ex); } catch (NumberFormatException ex) { System.out.println("error!\n"+ex); } } private String getLine(DataInputStream in) throws IOException { String line = in.readLine(); while ((line.startsWith("//")) || (line.equals(""))) line = in.readLine(); // System.out.println("returning " + line); return line; } private int getCode(String letter) throws IOException { if (letter.equals("T")) return Segment.TOP; if (letter.equals("R")) return Segment.RIGHT; if (letter.equals("B")) return Segment.BOTTOM; if (letter.equals("L")) return Segment.LEFT; throw new IOException(); } private boolean onTrack(int x, int y) { int r = y / Segment.getSize(); int c = x / Segment.getSize(); return (mySegs[r][c].onTrack(x % Segment.getSize(), y % Segment.getSize())); } private int bump(int num, int limit) { return (num + 1) % limit; } }