Gameboard.javaimport 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