package gui.simulator; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.io.Serializable; import java.util.List; import javax.swing.ImageIcon; public class Visitor implements Serializable { private Point2D positie, target; private double rotation, speed; private WalkingPath currentpath; private int currentpoint; private boolean walkInversed; Images.ImageType image = Images.ImageType.Visitor; public Visitor(Point2D positie, Point2D starttarget) { this.positie = positie; this.rotation = 0; double number = Math.random()*2; if(number < 1){ this.speed = 1; } else { this.speed = number; } this.target = starttarget; } void update(List visitors, List buildings, WalkingPathArrayList walkingpaths) { Point2D difference = new Point2D.Double( target.getX() - positie.getX(), target.getY() - positie.getY() ); double newRotation = Math.atan2(difference.getY(), difference.getX()); double rotDifference = rotation - newRotation; while(rotDifference > Math.PI) rotDifference -= 2 * Math.PI; while(rotDifference < -Math.PI) rotDifference += 2 * Math.PI; if(Math.abs(rotDifference) < 0.1) rotation = newRotation; else if(rotDifference < 0) rotation += 0.1; else if(rotDifference > 0) rotation -= 0.1; Point2D oldPositie = positie; positie = new Point2D.Double( positie.getX() + speed * Math.cos(rotation), positie.getY() + speed * Math.sin(rotation) ); if(hasCollision(visitors) || hasCollisionObject(buildings)) // collision with a riged building or a visitor, rotate { positie = oldPositie; rotation += 0.2; } if(currentpath != null){ if(hasCollision(currentpath.get(currentpoint))){ DrawEngine object = collisionObject(buildings); if(object != null){ if(currentpath.getObject1() == object || currentpath.getObject2() == object){ List connectedWalkingPaths = walkingpaths.getWalkingPadObject(object); if(connectedWalkingPaths.isEmpty()){ }else{ walkRoute(connectedWalkingPaths.get((int)(Math.random()*connectedWalkingPaths.size())), object); } } } if(walkInversed && currentpoint > 0){ currentpoint--; }else if(currentpoint < currentpath.getPath().size()-1){ currentpoint++; } target = currentpath.get(currentpoint); } }else{ //entrance DrawEngine object = collisionObject(buildings); if(object != null){ List connectedWalkingPaths = walkingpaths.getWalkingPadObject(object); if(connectedWalkingPaths.isEmpty()){ // no paths connected to the entrance, what a shame! }else{ walkRoute(connectedWalkingPaths.get((int)(Math.random()*connectedWalkingPaths.size())),object); } } } } void paint(Graphics2D g) { AffineTransform tx = new AffineTransform(); tx.translate(positie.getX()-8, positie.getY()-11); tx.rotate(rotation, 4, 6); g.drawImage(Images.getImage(image), tx ,null); } public boolean hasCollision(List visitors) { for(Visitor b : visitors) { if(b == this) continue; if(b.positie.distance(positie) < 11){ return true; } } return false; } public boolean hasCollisionObject(List objects){ for(DrawEngine o:objects){ if(o.type != SimulatorPane.Objects.WAYPOINT && o.type != SimulatorPane.Objects.EXIT && o.type != SimulatorPane.Objects.ENTRANCE ) if (o.contains(positie)) return true; } return false; } public boolean hasCollision(Point p){ return positie.distance(p) < 11; } public DrawEngine collisionObject(List objects){ for(DrawEngine o:objects){ if (o.contains(positie)) return o; } return null; } public void walkRoute(WalkingPath p, DrawEngine object){ if(p.getObject1() == object){ currentpoint = 0; walkInversed = false; }else{ currentpoint = p.getPath().size()-1; walkInversed= true; } target = p.get(currentpoint); currentpath = p; } }