[Java] 복잡한 모양으로 충돌 감지


Answers

.. 복잡한 모서리가 있고 모든 것이 사각형이 아닐 것입니다.

이는 ShapeArea 인스턴스를 그리거나 처리하여 얻을 수 있습니다. 예

  • 노란색은 조금 움직이는 '플레이어'입니다.
  • 이미지의 경계는 플레이어의 경로가 포함 된 벽을 나타냅니다 (바운더리가 튀어 오름).
  • 장애물은 충돌이 없을 때 녹색으로, 그렇지 않으면 빨간색으로 칠합니다.

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);
    }
}

편집하다

모든 붉은 색을 감지하고 충돌 범위로 설정합니다.

시작시, 들쭉날쭉 한 경로 매끄럽게 질문에 나오는 소스를 사용하여 빨간색 픽셀의 윤곽을 가져옵니다 ( getOutline(Color target, BufferedImage bi) 메서드 참조). 시작시이 Area 을 단일 장애물로 저장하십시오.

Question

나는 각 레벨이 이미지에서로드 된 게임을 만들고 싶다. 나는 Photoshop에서 전체 레벨을 작성한 다음 배경으로 설정하고 플레이어가 그 위에 다닐 수있게하려고합니다. 나는 보이지 않는 또 다른 이미지가 위에 충돌하는 것을 원한다. 나는 충돌하고 싶은 모든 곳에서 검은 색이 될 것이다.

직사각형 충돌 등으로 훨씬 쉽게 타일을 사용하고 싶지 않은 이유는 복잡한 모서리가 있고 모든 것이 사각형이 아니기 때문입니다.

이것은 좋은 생각입니까, 쉽게 할 수 있습니까? 이것이 큰 CPU 돼지가 될 것인가 아니면 더 좋은 방법이 있을까요?

레벨 이미지

빨간색으로 표시된 장애물