package gui.simulator; import gui.simulator.facilities.*; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.TexturePaint; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.geom.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Terrain extends JPanel { private List entities; private Point2D oldPosition; private Draw dragObject, selectedObject; private BufferedImage background; private Sidebar sidebar; private int festivalheight, festivalwidth; private int sideBarWidth = 200; private SimulatorPane.Terrains terrain; Point2D cameraPoint = new Point2D.Double(festivalwidth/2,festivalheight/2); float cameraScale = 1; private boolean grid; Point2D lastClickPosition; Point lastMousePosition; public Terrain(int length, int width, SimulatorPane.Terrains terrain){ //get values setFestivalHeight(length); setFestivalWidth(width); grid = true; this.terrain = terrain; //initialize sidebar sidebar = new Sidebar(sideBarWidth, getFestivalHeight(), this); //set terrainbackground switch(terrain){ case BEACH: try { background = ImageIO.read(new File("res/sand.jpg")); } catch (IOException e) { e.printStackTrace(); } break; case GRASS: try { background = ImageIO.read(new File("res/grass.jpg")); } catch (IOException e) { e.printStackTrace(); } break; case URBAN: try { background = ImageIO.read(new File("res/street.jpg")); } catch (IOException e) { e.printStackTrace(); } break; } this.dragObject = null; this.entities = new LinkedList(); this.initEntities(); this.listeners(); } private void getFacility(MouseEvent e){ Point2D clickPoint = getClickPoint(e.getPoint()); if(e.getX() < sideBarWidth) { if(e.getY() < 300){ dragObject = new Stage((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10); }else if(e.getY() > 300 && e.getY() < 550){ dragObject = new RestRoom((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10); }else if(e.getY() > 550 && e.getY() < 800){ dragObject = new AccessPoint(this, (int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10); } else if(e.getY() > 800){ dragObject = new ExitPoint(this, (int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10); } entities.add(dragObject); } } private void listeners(){ addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { Point2D clickPoint = getClickPoint(e.getPoint()); lastClickPosition = clickPoint; lastMousePosition = e.getPoint(); //if selected in sidebar getFacility(e); //else selected in terrain if(e.getX() > sideBarWidth){ for(Draw drawObject: entities){ if(drawObject.contains(clickPoint)){ dragObject = drawObject; selectedObject = dragObject; oldPosition = new Point2D.Double(selectedObject.getX(), selectedObject.getY()); } } } repaint(); } @Override public void mouseReleased(MouseEvent e) { if(selectedObject != null){ for(Draw drawObject: entities){ if(drawObject == selectedObject){ continue; } if(intersection(selectedObject, drawObject)){ //move back selectedObject.setX(oldPosition.getX()); selectedObject.setY(oldPosition.getY()); } } } selectedObject = null; dragObject = null; repaint(); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { Point2D clickPoint = getClickPoint(e.getPoint()); if(dragObject != null){ if(SwingUtilities.isLeftMouseButton(e)){ dragObject.setX(dragObject.getX() - (lastClickPosition.getX() - clickPoint.getX())); dragObject.setY(dragObject.getY() - (lastClickPosition.getY() - clickPoint.getY())); }else if(SwingUtilities.isRightMouseButton(e)){ dragObject.rotation += (lastClickPosition.getX() - clickPoint.getX() + lastClickPosition.getY() - clickPoint.getY()); } } else { cameraPoint = new Point2D.Double( cameraPoint.getX() + (lastMousePosition.getX() - e.getX()), cameraPoint.getY() + (lastMousePosition.getY() - e.getY()) ); } repaint(); lastMousePosition = e.getPoint(); lastClickPosition = clickPoint; } }); addMouseWheelListener(new MouseWheelListener() { @Override public void mouseWheelMoved(MouseWheelEvent e) { Point2D clickPoint = getClickPoint(e.getPoint()); for(Draw object: entities){ //if object selected, scale object if(object.contains(clickPoint)){ object.scale *= 1 + (e.getPreciseWheelRotation()/10.0); repaint(); return; } } //scale camera cameraScale *= 1 - (e.getPreciseWheelRotation()/10.0); repaint(); } }); } /* * Add facilities on initializing */ private void initEntities(){ //this.entities.add(new Stage(300, 10, 0.5, 10)); //this.entities.add(new Stage(400, 40, 2, 10)); } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; sidebar.draw(g2); //draw simulation field g2.setClip(new Rectangle2D.Double(sideBarWidth, 0, getWidth()-sideBarWidth, getHeight())); AffineTransform oldTransform = g2.getTransform(); g2.translate(sideBarWidth,0); g2.setTransform(getCamera()); TexturePaint p = new TexturePaint(background, new Rectangle2D.Double(0, 0, 200, 200)); g2.setPaint(p); g2.fill(new Rectangle2D.Double(0,0,festivalwidth,festivalheight)); if(grid){ g2.setColor(new Color(160,160,160,120)); g2.setStroke(new BasicStroke(1)); for(int i = 0; i < (getFestivalWidth()/10)+1; i++){ g2.drawLine(i*10, 0, i*10, getFestivalHeight()); }; for(int i = 0; i < (getFestivalHeight()/10)+1; i++){ g2.drawLine(0, i*10, getFestivalWidth(), i*10); }; } for(Draw drawObject: entities){ drawObject.draw(g2); } //draw collide boxes if(this.selectedObject != null){ Shape shape = this.selectedObject.getRect(); g2.setColor(Color.RED); g2.draw(this.selectedObject.getAffineTransform().createTransformedShape(shape)); boolean collide = false; for(Draw draw: entities){ if(!draw.equals(this.selectedObject)){ if(intersection(this.selectedObject, draw)){ collide = true; } } } if(collide){ g2.setColor(new Color(254, 0, 0, 128)); }else{ g2.setColor(new Color(0, 254, 0, 128)); } g2.fill(this.selectedObject.getAffineTransform().createTransformedShape(this.selectedObject.getRect())); g2.setClip(null); g2.setTransform(oldTransform); } } private Rectangle drawDragRectangle(Draw shape){ Rectangle rectangle = null; 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()))); return rectangle; } private boolean intersection(Draw d1, Draw d2){ Area area = new Area(d1.getAffineTransform().createTransformedShape(d1.getRect())); Area area2 = new Area(d2.getAffineTransform().createTransformedShape(d2.getRect())); area.intersect(area2); return !area.isEmpty(); } public Point2D getClickPoint(Point point) { try { return getCamera().inverseTransform(point, null); } catch (NoninvertibleTransformException e1) { e1.printStackTrace(); } return null; } private AffineTransform getCamera() { AffineTransform tx = new AffineTransform(); tx.translate(-cameraPoint.getX() + getWidth()/2, -cameraPoint.getY() + getHeight()/2); tx.scale(cameraScale, cameraScale); return tx; } public void setFestivalHeight(int height){ this.festivalheight = height; } public void setFestivalWidth(int width){ this.festivalwidth = width; } public int getFestivalHeight(){ return festivalheight; } public int getFestivalWidth(){ return festivalwidth; } //getters and setters for sidebar public void setDragObject(Draw dragObject){ this.dragObject = dragObject; } public Draw getDragObject(){ return dragObject; } public void addEntity(Draw dragObject){ entities.add(dragObject); } }