package gui.simulator; import gui.simulator.facilities.SimulatorStage; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.io.Serializable; import java.util.List; public class Visitor implements Serializable { private Point2D positie, target; private double rotation, speed; private WalkingPath currentpath; private int currentpoint; private boolean walkInversed; private double food, drink, pis; 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; this.food = (int)(Math.random()*100); this.drink = (int)(Math.random()*100); this.pis = (int)(Math.random()*100); } void update(List visitors, List buildings, WalkingPathArrayList walkingpaths) { Point2D difference = new Point2D.Double( target.getX() - positie.getX(), target.getY() - positie.getY() ); rotation %= 360; 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) ); this.food = (int)(Math.random()*100); this.drink = (int)(Math.random()*100); this.pis = (int)(Math.random()*100); if(hasCollision(visitors) || hasCollisionObject(buildings)) // collision with a ridged building or a visitor, rotate { positie = oldPositie; rotation += 0.5*Math.random(); } if(currentpath != null){ DrawEngine object = collisionObject(buildings); if(object != null){ if((currentpath.getObject1() == object && walkInversed) || (currentpath.getObject2() == object && !walkInversed)){ //end point reached, what to do? if(object.type == SimulatorPane.Objects.STAGE){ if(((SimulatorStage) object).getPlayingact() == null){ walkNewRoute(walkingpaths, object); } }else if(object.type == SimulatorPane.Objects.DRINK){ drink += 50; walkNewRoute(walkingpaths, object); }else if(object.type == SimulatorPane.Objects.SNACKBAR){ food += 50; walkNewRoute(walkingpaths, object); }else if(object.type == SimulatorPane.Objects.RESTROOM){ pis = 100; walkNewRoute(walkingpaths, object); }else if(object.type == SimulatorPane.Objects.WAYPOINT){ walkNewRoute(walkingpaths, object); } } } if(positie.distance(currentpath.get(currentpoint)) < 11){ //collision with a path-point 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){ walkNewRoute(walkingpaths,object); } } } public 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); } private boolean hasCollision(List visitors) { // check collision with other visitors for(Visitor b : visitors) { if(b != this && b.positie.distance(positie) < 11){ double rotdifference = Math.toDegrees(Math.abs(rotation-b.rotation)); if(!(rotdifference > 160 && rotdifference < 210)){ return true; } } } return false; } private boolean hasCollisionObject(List objects){ // check collision with rigid 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; } private DrawEngine collisionObject(List objects){ for(DrawEngine o:objects){ if (o.containsWalkArea(positie) || o.contains(positie) ) return o; } return null; } private void walkRoute(WalkingPath p, DrawEngine object){ if(p.getObject1() == object){ currentpoint = 1; walkInversed = false; }else{ currentpoint = p.getPath().size()-2; walkInversed= true; } target = p.get(currentpoint); currentpath = p; } private void walkNewRoute(WalkingPathArrayList walkingpaths, DrawEngine object){ WalkingPathArrayList connectedWalkingPaths = walkingpaths.getWalkingPadObject(object); connectedWalkingPaths.removeType(object, SimulatorPane.Objects.ENTRANCE); if(food > 25) connectedWalkingPaths.removeType(object, SimulatorPane.Objects.SNACKBAR); if(drink > 25) connectedWalkingPaths.removeType(object, SimulatorPane.Objects.DRINK); if(pis > 25) connectedWalkingPaths.removeType(object, SimulatorPane.Objects.RESTROOM); if(!connectedWalkingPaths.isEmpty()){ walkRoute(connectedWalkingPaths.get((int)(Math.random()*connectedWalkingPaths.size())), object); } } public double getFood() { return food; } public void setFood(double food) { if(food >= 0 && food <= 100) this.food = food; } public double getDrink() { return drink; } public void setDrink(double drink) { if(drink >= 0 && drink <= 100) this.drink = drink; } public double getPis() { return pis; } public void setPis(double pis) { if(pis >= 0 && pis <= 100) this.pis = pis; } }