Terrain.java 12 KB

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