Gameboard.java
import java.awt.*; import java.awt.event.*; import java.util.*; import java.awt.geom.*; import javax.swing.Timer; import javax.swing.*; public class Gameboard extends JPanel { Timer myTimer; int wd, ht; Robot robot; ArrayList<Ball> balls = new ArrayList<Ball>(); ArrayList<Ball> fixedPts = new ArrayList<Ball>(); ArrayList<WallSeg> segs = new ArrayList<WallSeg>(); ArrayList<Collision> collisions = new ArrayList<Collision>(); Scanner sc = new Scanner(System.in); boolean done = false; double simtime = 0.0; Gameboard() { Ball b; robot = new Robot(50,460,24,23,new Color(180,180,255)); robot.theta = -45; int wd = 740; int ht = 500; make_area1(); Color [] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA, Color.YELLOW}; String [] names = {"red","green","blue","magneta","yellow"}; for (int k=0; k<5; k++) { b = new Ball(); b.randomize(20.0,wd,ht); while (intersect_world(b)) b.randomize(10.0,wd,ht); b.color = colors[k]; b.set_name(names[k]); balls.add(b); } } void make_area1() { Ball pt1, pt2, pt3, pt4, pt5; // room boundaries pt1 = new Ball(10, 10); pt2 = new Ball(730, 10); pt3 = new Ball(730, 490); pt4 = new Ball(10, 490); segs.add(new WallSeg(pt1,pt2)); segs.add(new WallSeg(pt2,pt3)); segs.add(new WallSeg(pt3,pt4)); segs.add(new WallSeg(pt4,pt1)); // obstructions pt1 = new Ball(540, 300); fixedPts.add(pt1); pt2 = new Ball(540, 160); fixedPts.add(pt2); pt3 = new Ball(300, 160); fixedPts.add(pt3); pt4 = new Ball(300, 390); fixedPts.add(pt4); pt5 = new Ball(540, 390); fixedPts.add(pt5); segs.add(new WallSeg(pt1,pt2)); segs.add(new WallSeg(pt2,pt3)); segs.add(new WallSeg(pt3,pt4)); segs.add(new WallSeg(pt4,pt5)); pt1 = new Ball(200, 490); pt2 = new Ball(200, 200); segs.add(new WallSeg(pt1,pt2)); pt3 = new Ball(100, 200); segs.add(new WallSeg(pt2,pt3)); fixedPts.add(pt2); fixedPts.add(pt3); } public boolean intersect_world(Ball bt) { for (Ball b: balls) { if (b.dist(bt)<50) return true; } for (WallSeg seg: segs) { if (seg.dist(bt)<0) return true; } return false; } public void update1() { wd = getWidth(); ht = getHeight(); double tstep = 0.05; double tmin = 1.0; robot.updateVelocity(); double t = robot.intersect_window(wd,ht); if (t<tmin) tmin = t; for (WallSeg ws: segs) { t = ws.intersect(robot); if (t<tmin) tmin = t; } for (Ball b: fixedPts) { t = b.intersect(robot); if (t<tmin) tmin = t; } if (tmin<=tstep) { robot.move(tmin); robot.setVelocity(0,0); } else robot.move(tstep); simtime += tstep; repaint(); if (done) { stopAnimation(); System.out.format("Task completed in %g time units%n",simtime); } } public boolean check_distance() { double dist; boolean flag = false; int nballs = balls.size(); for (int i=0; i<nballs-1; i++) { for (int j=i+1; j<nballs; j++) { Ball b1 = balls.get(i); Ball b2 = balls.get(j); dist = b1.dist(b2); if (dist<-0.01) { System.out.println("dist " + dist + " " + b1 + b2); double dx = b2.px-b1.px; double dy = b2.py-b1.py; System.out.println( b1.info()); System.out.println( b2.info()); System.out.println("dx " + dx + " dy " + dy); System.out.println("sep " + Math.hypot(dx,dy) + " radius " + (b1.radius+b2.radius)); flag = true; } } } return flag; } void pause() { stopAnimation(); repaint(); sc.nextLine(); startAnimation(); } private Collision clast = null; public void update2() { wd = getWidth(); ht = getHeight(); double tstep, tmore; tstep = 1.0; tmore = tstep; while (tmore>0.0) { update_collision_list(tmore); if (collisions.size()>0) { java.util.List<Collision> list = collisions; Collections.<Collision>sort(list); Collision c = collisions.get(0); tstep = c.timestep; tmore = tmore - tstep; boolean flag = check_distance(); if (flag) { if (clast!=null) System.out.println("last collision " + clast); for (Collision ct: collisions) System.out.println(ct); pause(); } clast = c; for (Ball ball: balls) ball.move(tstep); c.update_velocity(); } else { tstep = tmore; tmore = 0.0; for (Ball ball: balls) ball.move(tstep); } } simtime += tstep; repaint(); } public void update_collision_list(double tstep) { Collision c; collisions.clear(); double t; for (Ball ball: balls) { t = ball.intersect_window_vertical(wd); if (t>0.0 && t<tstep) collisions.add(new Collision(t,ball,1)); t = ball.intersect_window_horizontal(ht); if (t>0.0 && t<tstep) collisions.add(new Collision(t,ball,2)); for (WallSeg seg: segs) { t = seg.intersect(ball); if (t>0.0 && t<tstep) collisions.add(new Collision(t,ball,seg)); for (Ball pt: fixedPts) { t = ball.intersect(pt); if (t>0.0 && t<tstep) { c = new Collision(t,ball,pt); collisions.add(c); c.ndx = -2; } } } int nballs = balls.size(); for (int i=0; i<nballs-1; i++) { for (int j=i+1; j<nballs; j++) { Ball b1 = balls.get(i); Ball b2 = balls.get(j); t = b1.intersect(b2); if (t>0.0 && t<tstep) collisions.add(new Collision(t,b1,b2)); } } //label.setText(wallseg.str); } } public void paintComponent(Graphics g) { super.paintComponent(g); // draw grid g.setColor(Color.RED); int n; int w = 80; for (n=0; n<7; n++) { g.drawLine(10,10+n*w,10+9*w,10+n*w); } for (n=0; n<10; n++) { g.drawLine(10+n*w,10,10+n*w,10+6*w); } // draw walls for (WallSeg ws: segs) ws.draw(g); for (Ball b: fixedPts) b.draw(g); // draw balls for (Ball b: balls) b.draw(g); // draw robot robot.draw(g); } public void startAnimation() { if (myTimer == null) { myTimer = new Timer(50,new TimerHandler() ); myTimer.start(); } else if (!myTimer.isRunning()) myTimer.restart(); } public void stopAnimation() { myTimer.stop(); } private class TimerHandler implements ActionListener { public void actionPerformed(ActionEvent actionevent) { update2(); } } }
Maintained by John Loomis, updated Thu Jul 10 22:03:33 2014