Terrain.java 14 KB

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