java image awt collision java-2d

java - Detección de colisión con formas complejas



image awt (1)

... habrá esquinas complejas y no todo será rectángulo.

Esto podría lograrse dibujando y tratando con instancias de Shape y Area . P.EJ

  • El amarillo es un pequeño "jugador" animado.
  • Los límites de la imagen representan muros que contienen la ruta del jugador (rebota en ellos).
  • Los obstáculos se pintan de verde cuando no están en colisión, de lo contrario, de color rojo.

import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import javax.swing.*; class ShapeCollision { private BufferedImage img; private Area[] obstacles = new Area[4]; private Area walls; int x; int y; int xDelta = 3; int yDelta = 2; /** A method to determine if two instances of Area intersect */ public boolean doAreasCollide(Area area1, Area area2) { boolean collide = false; Area collide1 = new Area(area1); collide1.subtract(area2); if (!collide1.equals(area1)) { collide = true; } Area collide2 = new Area(area2); collide2.subtract(area1); if (!collide2.equals(area2)) { collide = true; } return collide; } ShapeCollision() { int w = 400; int h = 200; img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); final JLabel imageLabel = new JLabel(new ImageIcon(img)); x = w/2; y = h/2; //circle obstacles[0] = new Area(new Ellipse2D.Double(40, 40, 30, 30)); int[] xTriangle = {330,360,345}; int[] yTriangle = {60,60,40}; //triangle obstacles[1] = new Area(new Polygon(xTriangle, yTriangle, 3)); int[] xDiamond = {60,80,60,40}; int[] yDiamond = {120,140,160,140}; //diamond obstacles[2] = new Area(new Polygon(xDiamond, yDiamond, 4)); int[] xOther = {360,340,360,340}; int[] yOther = {130,110,170,150}; // other obstacles[3] = new Area(new Polygon(xOther, yOther, 4)); walls = new Area(new Rectangle(0,0,w,h)); ActionListener animate = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { animate(); imageLabel.repaint(); } }; Timer timer = new Timer(50, animate); timer.start(); JOptionPane.showMessageDialog(null, imageLabel); timer.stop(); } public void animate() { Graphics2D g = img.createGraphics(); g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(Color.BLUE); g.fillRect(0, 0, img.getWidth(), img.getHeight()); x+=xDelta; y+=yDelta; int s = 15; Area player = new Area(new Ellipse2D.Double(x, y, s, s)); // Acid test of edge collision; if (doAreasCollide(player,walls)) { if ( x+s>img.getWidth() || x<0 ) { xDelta *= -1; } if(y+s>img.getHeight() || y<0 ) { yDelta *= -1; } } g.setColor(Color.ORANGE); for (Area obstacle : obstacles) { if (doAreasCollide(obstacle, player)) { g.setColor(Color.RED); } else { g.setColor(Color.GREEN); } g.fill(obstacle); } g.setColor(Color.YELLOW); g.fill(player); g.dispose(); } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new ShapeCollision(); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html SwingUtilities.invokeLater(r); } }

Editar

hacer que detecte todo el color rojo y establecerlo a medida que los límites de colisión

Al iniciar, use la fuente que se muestra en la pregunta Alisar una ruta irregular para obtener un esquema de los píxeles rojos (consulte el getOutline(Color target, BufferedImage bi) ). Almacene esa Area como el único obstáculo en la puesta en marcha.

Quiero hacer un juego que tenga cada nivel cargado desde una imagen. Quiero dibujar todo el nivel en Photoshop, y luego configurarlo como fondo y permitir que el jugador lo recorra. Quiero que otra imagen invisible pase por encima, que será negra en todos los lugares con los que quiero colisionar.

La razón por la que no quiero usar mosaicos, que son mucho más fáciles con la colisión de rectángulo y demás, es porque habrá esquinas complejas y no todo será rectángulo.

¿Es esta una buena idea, y es posible hacerlo fácilmente? ¿Sería esto un gran cerdo de CPU o hay una mejor manera de hacer esto?

Imagen de nivel

Obstáculos mostrados en rojo