Terrain.java 16 KB

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