Wykrywanie kolizji o złożonych kształtach
Chcę zrobić grę, która ma każdy poziom załadowany z obrazu. Chcę narysować cały poziom w Photoshopie, a następnie ustawić go jako tło i pozwolić graczowi przejść po nim. Chcę, aby kolejny niewidoczny obraz przeszedł na wierzch, który będzie czarny we wszystkich miejscach, z którymi chcę zderzyć się.
Powodem, dla którego nie chcę używać płytek, które są znacznie łatwiejsze przy kolizji prostokątów i tym podobnych, jest to, że będą złożone narożniki i nie wszystko będzie prostokąt.
Czy to dobry pomysł i czy można to zrobić łatwo? Czy to będzie duży CPU hog czy jest lepszy sposób, aby to zrobić?
Obrazek poziomu
Przeszkody pokazane na Czerwono
1 answers
..będą złożone narożniki i nie wszystko będzie prostokąt.
Można to osiągnąć poprzez rysowanie i radzenie sobie z instancjami Shape
i Area
. E. G.
- Żółty to mały animowany "gracz".
- granice obrazu reprezentują ściany, które zawierają ścieżkę gracza (odbija się od nich).
- przeszkody są pomalowane na zielono, gdy nie są w kolizji, w przeciwnym razie na Czerwono.
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);
}
}
Edit
Niech wykryje cały czerwony kolor i ustaw go jako granice kolizji
Podczas uruchamiania użyj źródła widocznego w pytaniu wygładzanie postrzępionej ścieżki , Aby uzyskać zarys czerwonych pikseli (patrz Metoda getOutline(Color target, BufferedImage bi)
). Przechowuj to Area
jako pojedynczą przeszkodę podczas uruchamiania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:53