Terrain.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. package gui.simulator;
  2. import gui.simulator.Images.ImageType;
  3. import gui.simulator.facilities.RestRoom;
  4. import gui.simulator.facilities.SimulatorStage;
  5. import gui.simulator.facilities.SnackBar;
  6. import java.awt.BasicStroke;
  7. import java.awt.Color;
  8. import java.awt.Cursor;
  9. import java.awt.Dimension;
  10. import java.awt.Graphics;
  11. import java.awt.Graphics2D;
  12. import java.awt.Point;
  13. import java.awt.Rectangle;
  14. import java.awt.Shape;
  15. import java.awt.TexturePaint;
  16. import java.awt.Toolkit;
  17. import java.awt.event.MouseAdapter;
  18. import java.awt.event.MouseEvent;
  19. import java.awt.event.MouseMotionAdapter;
  20. import java.awt.event.MouseWheelEvent;
  21. import java.awt.event.MouseWheelListener;
  22. import java.awt.geom.AffineTransform;
  23. import java.awt.geom.Area;
  24. import java.awt.geom.NoninvertibleTransformException;
  25. import java.awt.geom.Point2D;
  26. import java.awt.geom.Rectangle2D;
  27. import java.util.ArrayList;
  28. import java.util.LinkedList;
  29. import java.util.List;
  30. import javax.swing.JDialog;
  31. import javax.swing.JPanel;
  32. import javax.swing.SwingUtilities;
  33. import agenda.Agenda;
  34. public class Terrain extends JPanel {
  35. private List<DrawEngine> entities;
  36. private Point2D oldPosition;
  37. private double oldRotation, oldScale;
  38. private DrawEngine dragObject, selectedObject;
  39. private ImageType background;
  40. private Sidebar sidebar;
  41. private int festivalheight, festivalwidth;
  42. private int sideBarWidth = 200;
  43. private int pathgenerate = 1;
  44. private WalkingPath currentpath;
  45. private SimulatorPane.Terrains terrain;
  46. Point2D cameraPoint = new Point2D.Double(festivalwidth/2,festivalheight/2);
  47. float cameraScale = 1;
  48. private boolean grid;
  49. private ArrayList<Visitor> visitors;
  50. private ArrayList<WalkingPath> paths;
  51. Cursor rotate, pathpoint;
  52. Point2D lastClickPosition;
  53. Point lastMousePosition;
  54. Point2D lastMovedMousePosition;
  55. private Agenda agenda;
  56. public Terrain(int length, int width, SimulatorPane.Terrains terrain, Agenda agenda){
  57. //get values
  58. setFestivalHeight(length);
  59. setFestivalWidth(width);
  60. grid = true;
  61. this.terrain = terrain;
  62. visitors = new ArrayList<Visitor>();
  63. paths = new ArrayList<WalkingPath>();
  64. createCustomCursors();
  65. //initialize sidebar
  66. sidebar = new Sidebar(sideBarWidth, 3000, this);
  67. //set terrainbackground
  68. switch(terrain){
  69. case BEACH:
  70. background = Images.ImageType.Sand;
  71. break;
  72. case GRASS:
  73. background = Images.ImageType.Grass;
  74. break;
  75. case URBAN:
  76. background = Images.ImageType.Street;
  77. break;
  78. }
  79. this.dragObject = null;
  80. this.entities = new LinkedList();
  81. this.initEntities();
  82. this.listeners();
  83. //agenda
  84. this.agenda = agenda;
  85. }
  86. private void getFacility(MouseEvent e){
  87. Point2D clickPoint = getClickPoint(e.getPoint());
  88. DrawEngine dragObject = null;
  89. if(e.getX() < sideBarWidth)
  90. {
  91. if(e.getY() > 100 && e.getY() < 260){
  92. dragObject = new SimulatorStage((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
  93. setDragObject(dragObject);
  94. }else if(e.getY() >= 260 && e.getY() < 425){
  95. dragObject = new RestRoom((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
  96. setDragObject(dragObject);
  97. }else if(e.getY() >= 430 && e.getY() < 510){
  98. dragObject = new AccessPoint(this, (int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
  99. setDragObject(dragObject);
  100. }
  101. else if(e.getY() >= 510 && e.getY() < 610){
  102. dragObject = new ExitPoint(this, (int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
  103. setDragObject(dragObject);
  104. }
  105. else if(e.getY() > 610 && e.getY() < getFestivalHeight()){
  106. dragObject = new SnackBar((int)clickPoint.getX(),(int)clickPoint.getY(), 0.3, 10);
  107. setDragObject(dragObject);
  108. }
  109. entities.add(dragObject);
  110. }
  111. }
  112. private void listeners(){
  113. addMouseListener(new MouseAdapter() {
  114. @Override
  115. public void mousePressed(MouseEvent e) {
  116. Point2D clickPoint = getClickPoint(e.getPoint());
  117. lastClickPosition = clickPoint;
  118. lastMousePosition = e.getPoint();
  119. //if selected in sidebar
  120. getFacility(e);
  121. //else selected in terrain
  122. if(e.getX() > sideBarWidth){
  123. for(DrawEngine drawObject: entities){
  124. if(drawObject.contains(clickPoint)){
  125. if(pathgenerate == 1){
  126. currentpath = new WalkingPath();
  127. currentpath.addPoint(new Point((int)drawObject.getCenter().getX(), (int)drawObject.getCenter().getY()));
  128. currentpath.setObject1(drawObject);
  129. pathgenerate = 2;
  130. return;
  131. }else if(pathgenerate > 1){
  132. currentpath.addPoint(new Point((int)drawObject.getCenter().getX(), (int)drawObject.getCenter().getY()));
  133. currentpath.setObject2(drawObject);
  134. paths.add(currentpath);
  135. for(int i=0; i< 200; i++){
  136. visitors.add(new Visitor(new Point(100+(i*15),100)));
  137. visitors.get(i).walkRoute(paths.get(0));
  138. }
  139. pathgenerate = 0;
  140. return;
  141. }else{
  142. setCursor(new Cursor(Cursor.MOVE_CURSOR));
  143. dragObject = drawObject;
  144. selectedObject = dragObject;
  145. oldPosition = new Point2D.Double(selectedObject.getX(), selectedObject.getY());
  146. oldRotation = selectedObject.getScale();
  147. oldScale = selectedObject.getScale();
  148. //double click
  149. if(e.getClickCount() == 2){
  150. //TODO open dialog
  151. JDialog dialog = new StageDialog(drawObject, agenda);
  152. //position
  153. Toolkit toolkit = Toolkit.getDefaultToolkit();
  154. Dimension screenSize = toolkit.getScreenSize();
  155. int x = (int) ((screenSize.getWidth() - dialog.getWidth()) / 2);
  156. int y = (int) ((screenSize.getHeight() - dialog.getHeight()) / 2);
  157. Point center = new Point(x, y);
  158. dialog.setLocation(center);
  159. dialog.pack();
  160. dialog.setVisible(true);
  161. }
  162. return;
  163. }
  164. }
  165. }
  166. if(pathgenerate > 1){
  167. currentpath.addPoint(new Point((int)getClickPoint(e.getPoint()).getX(), (int)getClickPoint(e.getPoint()).getY()));
  168. }
  169. }
  170. repaint();
  171. }
  172. @Override
  173. public void mouseReleased(MouseEvent e) {
  174. if(selectedObject != null){
  175. for(DrawEngine drawObject: entities){
  176. if(drawObject == selectedObject){
  177. continue;
  178. }
  179. if(intersection(selectedObject, drawObject)){
  180. //move back
  181. selectedObject.setX(oldPosition.getX());
  182. selectedObject.setY(oldPosition.getY());
  183. selectedObject.setRotation(oldRotation);
  184. selectedObject.setScale(oldScale);
  185. }
  186. }
  187. }
  188. setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
  189. selectedObject = null;
  190. dragObject = null;
  191. repaint();
  192. }
  193. });
  194. addMouseMotionListener(new MouseMotionAdapter() {
  195. public void mouseMoved(MouseEvent e){
  196. lastMovedMousePosition = getClickPoint(e.getPoint());
  197. if(pathgenerate >0){
  198. setCursor(pathpoint);
  199. }else{
  200. for(DrawEngine drawObject: entities){
  201. if(drawObject.contains(lastMovedMousePosition)){
  202. setCursor(new Cursor(Cursor.HAND_CURSOR));
  203. return;
  204. }
  205. }
  206. setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
  207. }
  208. }
  209. @Override
  210. public void mouseDragged(MouseEvent e) {
  211. Point2D clickPoint = getClickPoint(e.getPoint());
  212. if(dragObject != null){
  213. if(SwingUtilities.isLeftMouseButton(e) && dragObject instanceof AccessPoint){
  214. dragObject.setX(-25);
  215. dragObject.setRotation(90);
  216. if(dragObject.getY()<80){
  217. dragObject.setY(80);
  218. } else if(dragObject.getY()>getFestivalHeight()-150){
  219. dragObject.setY(getFestivalHeight()-150);
  220. } else {
  221. dragObject.setY(dragObject.getY() - (lastClickPosition.getY() - clickPoint.getY()));
  222. }
  223. }else if(SwingUtilities.isLeftMouseButton(e) && dragObject instanceof ExitPoint){
  224. dragObject.setX(getFestivalWidth()-200);
  225. dragObject.setRotation(90);
  226. if(dragObject.getY()<80){
  227. dragObject.setY(80);
  228. } else if(dragObject.getY()>getFestivalHeight()-150){
  229. dragObject.setY(getFestivalHeight()-150);
  230. } else {
  231. dragObject.setY(dragObject.getY() - (lastClickPosition.getY() - clickPoint.getY()));
  232. }
  233. }else if(SwingUtilities.isLeftMouseButton(e)){
  234. setCursor(new Cursor(Cursor.MOVE_CURSOR));
  235. dragObject.setX(dragObject.getX() - (lastClickPosition.getX() - clickPoint.getX()));
  236. dragObject.setY(dragObject.getY() - (lastClickPosition.getY() - clickPoint.getY()));
  237. }else if(SwingUtilities.isRightMouseButton(e)){
  238. setCursor(rotate);
  239. dragObject.setRotation(dragObject.getRotation() + (lastClickPosition.getX() - clickPoint.getX() + lastClickPosition.getY() - clickPoint.getY()));
  240. }
  241. }
  242. else
  243. {
  244. setCursor(new Cursor(Cursor.MOVE_CURSOR));
  245. cameraPoint = new Point2D.Double(
  246. cameraPoint.getX() + (lastMousePosition.getX() - e.getX()),
  247. cameraPoint.getY() + (lastMousePosition.getY() - e.getY())
  248. );
  249. }
  250. repaint();
  251. lastMousePosition = e.getPoint();
  252. lastClickPosition = clickPoint;
  253. }
  254. });
  255. addMouseWheelListener(new MouseWheelListener() {
  256. @Override
  257. public void mouseWheelMoved(MouseWheelEvent e) {
  258. Point2D clickPoint = getClickPoint(e.getPoint());
  259. for(DrawEngine object: entities){
  260. //if object selected, scale object
  261. if(object.contains(clickPoint)){
  262. double oldscale = object.getScale();
  263. if(oldscale < 0.3){
  264. if((e.getPreciseWheelRotation()/10.0) > 0){
  265. object.setScale(object.getScale() * 1 + (e.getPreciseWheelRotation()/10.0));
  266. }
  267. } else {
  268. object.setScale(object.getScale() * 1 + (e.getPreciseWheelRotation()/10.0));
  269. }
  270. //intersect
  271. for(DrawEngine draw: entities){
  272. if(draw != object){
  273. if(intersection(draw, object)){
  274. object.setScale(oldscale);
  275. }
  276. }
  277. }
  278. repaint();
  279. return;
  280. }
  281. }
  282. //scale camera
  283. cameraScale *= 1 - (e.getPreciseWheelRotation()/10.0);
  284. repaint();
  285. }
  286. });
  287. }
  288. /*
  289. * Add facilities on initializing
  290. */
  291. private void initEntities(){
  292. //this.entities.add(new Stage(300, 10, 0.5, 10));
  293. //this.entities.add(new Stage(400, 40, 2, 10));
  294. }
  295. @Override
  296. public void paint(Graphics g) {
  297. super.paint(g);
  298. Graphics2D g2 = (Graphics2D) g;
  299. sidebar.draw(g2);
  300. //draw simulation field
  301. g2.setClip(new Rectangle2D.Double(sideBarWidth, 0, getWidth()-sideBarWidth, getHeight()));
  302. AffineTransform oldTransform = g2.getTransform();
  303. g2.translate(sideBarWidth,0);
  304. g2.setTransform(getCamera());
  305. TexturePaint p = new TexturePaint(Images.getImage(background), new Rectangle2D.Double(0, 0, 200, 200));
  306. g2.setPaint(p);
  307. g2.fill(new Rectangle2D.Double(0,0,festivalwidth,festivalheight));
  308. if(grid){
  309. g2.setColor(new Color(160,160,160,120));
  310. g2.setStroke(new BasicStroke(1));
  311. for(int i = 0; i < (getFestivalWidth()/10)+1; i++){
  312. g2.drawLine(i*10, 0, i*10, getFestivalHeight());
  313. };
  314. for(int i = 0; i < (getFestivalHeight()/10)+1; i++){
  315. g2.drawLine(0, i*10, getFestivalWidth(), i*10);
  316. };
  317. }
  318. if(pathgenerate > 1){
  319. g2.setStroke(new BasicStroke(10));
  320. currentpath.paint(g2);
  321. g2.drawLine((int)currentpath.get(currentpath.getPath().size()-1).getX(),(int)currentpath.get(currentpath.getPath().size()-1).getY(), (int)lastMovedMousePosition.getX(), (int)lastMovedMousePosition.getY());
  322. }else{
  323. for(WalkingPath path:paths){
  324. path.paint(g2);
  325. }
  326. }
  327. for(Visitor v:visitors){
  328. v.paint(g2);
  329. }
  330. for(DrawEngine drawObject: entities){
  331. drawObject.draw(g2);
  332. if(pathgenerate > 0){
  333. g2.fill(drawObject.getAffineTransform().createTransformedShape(new Rectangle((int)(drawObject.getX()-(drawObject.getWidth()/2)-10),(int)(drawObject.getY()-(drawObject.getHeight()/2)-10), 20, 20)));
  334. }
  335. }
  336. //draw collide boxes
  337. if(this.selectedObject != null){
  338. Shape shape = this.selectedObject.getRect();
  339. g2.setColor(Color.RED);
  340. g2.draw(this.selectedObject.getAffineTransform().createTransformedShape(shape));
  341. boolean collide = false;
  342. for(DrawEngine drawEngine : entities){
  343. if(!drawEngine.equals(this.selectedObject)){
  344. if(intersection(this.selectedObject, drawEngine)){
  345. collide = true;
  346. }
  347. }
  348. }
  349. if(collide){
  350. g2.setColor(new Color(254, 0, 0, 128));
  351. }else{
  352. g2.setColor(new Color(0, 254, 0, 128));
  353. }
  354. g2.fill(this.selectedObject.getAffineTransform().createTransformedShape(this.selectedObject.getRect()));
  355. g2.setClip(null);
  356. g2.setTransform(oldTransform);
  357. }
  358. }
  359. private Rectangle drawDragRectangle(DrawEngine shape){
  360. Rectangle rectangle = null;
  361. rectangle = new Rectangle((int) (shape.getX() - shape.getDistanceToOtherObjects()), (int) (shape.getY() - shape.getDistanceToOtherObjects()), (int) (shape.getWidth() * shape.getScale() + (2 * shape.getDistanceToOtherObjects())), (int) (shape.getHeight() * shape.getScale() + (2 * shape.getDistanceToOtherObjects())));
  362. return rectangle;
  363. }
  364. private boolean intersection(DrawEngine d1, DrawEngine d2){
  365. Area area = new Area(d1.getAffineTransform().createTransformedShape(d1.getRect()));
  366. Area area2 = new Area(d2.getAffineTransform().createTransformedShape(d2.getRect()));
  367. area.intersect(area2);
  368. return !area.isEmpty();
  369. }
  370. public Point2D getClickPoint(Point point) {
  371. try {
  372. return getCamera().inverseTransform(point, null);
  373. } catch (NoninvertibleTransformException e1) {
  374. e1.printStackTrace();
  375. }
  376. return null;
  377. }
  378. private AffineTransform getCamera() {
  379. AffineTransform tx = new AffineTransform();
  380. //start field in top left corner, next to sidebar
  381. tx.translate(-cameraPoint.getX() + sideBarWidth, -cameraPoint.getY());
  382. //start field in middle of screen
  383. //tx.translate(-cameraPoint.getX() + getWidth()/2, -cameraPoint.getY() + getHeight()/2);
  384. tx.scale(cameraScale, cameraScale);
  385. return tx;
  386. }
  387. public void calculate(){
  388. for(Visitor v:visitors){
  389. v.update(visitors, entities);
  390. }
  391. for(WalkingPath p:paths){
  392. p.reCalculate();
  393. }
  394. }
  395. public void setFestivalHeight(int height){
  396. this.festivalheight = height;
  397. }
  398. public void setFestivalWidth(int width){
  399. this.festivalwidth = width;
  400. }
  401. public int getFestivalHeight(){
  402. return festivalheight;
  403. }
  404. public int getFestivalWidth(){
  405. return festivalwidth;
  406. }
  407. //getters and setters for sidebar
  408. public void setDragObject(DrawEngine dragObject){
  409. this.dragObject = dragObject;
  410. }
  411. public DrawEngine getDragObject(){
  412. return dragObject;
  413. }
  414. public void addEntity(DrawEngine dragObject){
  415. entities.add(dragObject);
  416. }
  417. public void createCustomCursors(){
  418. Toolkit toolkit = Toolkit.getDefaultToolkit();
  419. Images.ImageType image;
  420. image = Images.ImageType.RotateCursor;
  421. rotate = toolkit.createCustomCursor(Images.getImage(image), new Point(14,14), "Rotate");
  422. image = Images.ImageType.PathCursor;
  423. pathpoint = toolkit.createCustomCursor(Images.getImage(image), new Point(14,14), "Pathpoint");
  424. }
  425. }