package gui.simulator; import gui.simulator.facilities.Stage; import java.awt.Color; 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.MouseWheelEvent; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; 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 offset; private Draw dragObject, selectedObject; private BufferedImage background; private int length; private int width; private int terrain; Point2D cameraPoint = new Point2D.Double(1920/2,1080/2); float cameraScale = 1; Point2D lastClickPosition; Point lastMousePosition; public Terrain(int length, int width, int terrain){ this.length = length; this.width = width; this.terrain = terrain; switch(terrain){ case 1: try { background = ImageIO.read(new File("res/sand.jpg")); } catch (IOException e) { e.printStackTrace(); } break; case 2: try { background = ImageIO.read(new File("res/grass.jpg")); } catch (IOException e) { e.printStackTrace(); } break; case 3: 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 listeners(){ addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { boolean newObject = false; for(Draw drawObject: entities){ if(drawObject.contains(e.getPoint())){ dragObject = drawObject; offset = new Point2D.Double(e.getX() - drawObject.getX(), e.getY() - drawObject.getY()); selectedObject = dragObject; newObject = true; } } if(!newObject){ selectedObject = null; } repaint(); } @Override public void mouseReleased(MouseEvent e) { dragObject = null; } }); addMouseMotionListener(new MouseAdapter() { @Override public void mouseDragged(MouseEvent e) { Point2D clickPoint = getClickPoint(e.getPoint()); if(dragObject != null){ if(SwingUtilities.isLeftMouseButton(e)){ dragObject.setX(e.getX() - offset.getX()); dragObject.setY(e.getY() - offset.getY()); }else if(SwingUtilities.isRightMouseButton(e)){ dragObject.setRotation(e.getX() * -1); } } else { cameraPoint = new Point2D.Double( cameraPoint.getX() + (lastMousePosition.getX() - e.getX()), cameraPoint.getY() + (lastMousePosition.getY() - e.getY()) ); repaint(); } lastMousePosition = e.getPoint(); lastClickPosition = clickPoint; repaint(); } }); addMouseWheelListener(new MouseAdapter() { @Override public void mouseWheelMoved(MouseWheelEvent e) { for(Draw object: entities){ if(object.contains(e.getPoint())){ double scale = object.getScale(); scale *= 1 + (e.getPreciseWheelRotation() / 10); object.setScale(scale); } } repaint(); } }); } private void initEntities(){ this.entities.add(new Stage(10, 10, 0.5, 10)); this.entities.add(new Stage(200, 40, 2, 10)); } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; TexturePaint p = new TexturePaint(background, new Rectangle2D.Double(0, 0, 500, 500)); g2.setPaint(p); g2.fill(new Rectangle2D.Double(0,0,width,length)); for(Draw drawObject: entities){ drawObject.draw(g2); } if(this.selectedObject != null){ Shape shape = new Rectangle2D.Double(this.selectedObject.getX(), this.selectedObject.getY() , this.selectedObject.getWidth() * this.selectedObject.getScale(), this.selectedObject.getHeight() * this.selectedObject.getScale()); AffineTransform backup = g2.getTransform(); AffineTransform trans = new AffineTransform(); trans.rotate(Math.toRadians(this.selectedObject.getRotation()), (this.selectedObject.getX() + (this.selectedObject.getWidth() / 2 * this.selectedObject.getScale())),(this.selectedObject.getY() + (this.selectedObject.getHeight() /2 * this.selectedObject.getScale()))); g2.transform(trans); g2.setColor(Color.RED); g2.draw(shape); g2.transform(backup); boolean collide = false; for(Draw draw: entities){ if(!draw.equals(this.selectedObject)){ if(intersection(draw, this.selectedObject)){ collide = true; } } } if(collide){ g2.setColor(new Color(254, 0, 0, 128)); }else{ g2.setColor(new Color(0, 254, 0, 128)); } g2.fill(this.drawDragRectangle(this.selectedObject)); } } 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){ Rectangle2D.Double s1 = new Rectangle2D.Double(d1.getX() - d1.getDistanceToOtherObjects(), d1.getY() - d1.getDistanceToOtherObjects(), d1.getWidth() * d1.getScale() + (2*d1.getDistanceToOtherObjects()) , d1.getHeight() * d1.getScale() + (2*d1.getDistanceToOtherObjects())); Rectangle2D.Double s2 = new Rectangle2D.Double(d2.getX() - d2.getDistanceToOtherObjects(), d2.getY() - d2.getDistanceToOtherObjects(), d2.getWidth() * d2.getScale() + (2*d2.getDistanceToOtherObjects()) , d2.getHeight() * d2.getScale() + (2*d2.getDistanceToOtherObjects())); return s1.intersects(s2); } private 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; } }