Path2D.Double()对象之间发生碰撞的奇怪结果

时间:2016-06-04 21:08:38

标签: java eclipse graphics collision

我使用Java Graphics2D和Path2D处理与某些钻石的碰撞。但是,我得到了奇怪的结果。直到行进的黑色钻石移动到蓝色钻石之外,其中碰撞功能返回真实几秒钟然后随着黑色钻石向前移动而停止,似乎没有碰撞。了解正在发生的事情的最佳方式是简单地为自己测试代码。

当黑色钻石击中蓝色钻石时,它应立即停止。简单。但是,这似乎并没有发生在这里。因为黑色钻石停在蓝色钻石外面。

此体验的主要目标是使用等长投影。如果你知道更好的方法,请告诉我!

main.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main extends JPanel implements ActionListener, KeyListener{

    static int WIDTH;
    static int HEIGHT;

    Rectangle rectangle = new Rectangle(0, 0, 100, 100);
    Rectangle rectangle2 = new Rectangle(110, 110, 100, 100);

    ArrayList<GraphicalObject> objs = new ArrayList<GraphicalObject>();

    int targetFPS = 60;
    int currentFPS = targetFPS;



    int boxx = -500;
    int boxy = 0;
    boolean rising = false;
    boolean ontop = false;

    long oldFpsLoop = System.currentTimeMillis();
    long newFpsLoop = oldFpsLoop;
    int ticks = 0;

    Timer timer = new Timer(1000/targetFPS, this);

    public Main(){
        timer.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
        requestFocus();
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for (int i=0; i < objs.size(); i++){
            GraphicalObject cobj = objs.get(i);
            Graphics2D g2 = (Graphics2D) g.create();


            g2.setColor(Color.RED);
            g2.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
            g2.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);

            if (cobj.type.equals("text")){
                g2.setColor(cobj.color);

                g2.drawString(cobj.content, cobj.x, cobj.y);
            } else if (cobj.type.equals("rect")){
                g2.setColor(cobj.color);


                /**/
                AffineTransform at = new AffineTransform();
                at.setToRotation(Math.toRadians(0), WIDTH/2, HEIGHT/2);
                at.translate(WIDTH/2-cobj.w/2, HEIGHT/2-cobj.h/2);
                g2.setTransform(at);
                /**/
                g2.drawRect(cobj.x, cobj.y, cobj.w, cobj.h);
                g2.fill(cobj.projection);
            }

            g2.dispose();
        }
    }
    public static void main(String[] args){
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        WIDTH = (int) screenSize.getWidth();
        HEIGHT = (int) screenSize.getHeight();
        Main main = new Main();
        JFrame frame = new JFrame();
        frame.setTitle("360 ATTACK");
        frame.setSize(WIDTH, HEIGHT);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.add(main);
        frame.setVisible(true);
    }
    @Override
    public void actionPerformed(ActionEvent e) {

        ticks++;
        newFpsLoop = System.currentTimeMillis();
        if (newFpsLoop - oldFpsLoop > 1000){
            oldFpsLoop = newFpsLoop;
            currentFPS = ticks;
            if (currentFPS < targetFPS){
                for (int i=0; i<targetFPS-currentFPS;i++){
                    logic();
                }
            }
            ticks = 0;
        }

        logic();
        repaint();
    }
    public void logic(){

        objs = new ArrayList<GraphicalObject>();
        objs.add(new GraphicalObject("fps", "text", 0, 10, "FPS: " + currentFPS, Color.BLACK));
        objs.add(new GraphicalObject("base", "rect", 0, 0, 200, 200, Color.BLUE));
        if (ontop == false){
            objs.add(new GraphicalObject("box", "rect", boxx, boxy, 20, 20, Color.BLACK));
            objs.add(new GraphicalObject("top","rect", -100, -100, 200, 200, Color.RED));

        } else {
            objs.add(new GraphicalObject("top", "rect", -100, -100, 200, 200, Color.RED));
            objs.add(new GraphicalObject("box", "rect", boxx, boxy, 20, 20, Color.BLACK));

        }

        GraphicalObject box = null;
        GraphicalObject base = null;
        GraphicalObject top = null;

        for (int i=0; i<objs.size();i++){
            String name = objs.get(i).name;
            if (name.equals("box")){
                box = objs.get(i);
            } else if (name.equals("base")) {
                base = objs.get(i);
            } else if (name.equals("top")){
                top = objs.get(i);
            }
        }

        if(collision(box, base)){
            boxx--;
        }

        if (rising){
            boxx--;
            boxy--;
        } else {
            boxx++;
        }  
    }
    public boolean collision(GraphicalObject a, GraphicalObject b){
        Area aArea = new Area(a.projection);
        Area bArea = new Area(b.projection);
        aArea.intersect(bArea);
        return !aArea.isEmpty();
    }
    @Override
    public void keyPressed(KeyEvent e) {
        int c = e.getKeyCode();
        if (c == KeyEvent.VK_ESCAPE){
            System.exit(0);
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {

    }
    @Override
    public void keyTyped(KeyEvent e) {

    }
}

GraphicalObject.java

import java.awt.Color;
import java.awt.geom.Path2D;

public class GraphicalObject {

    int x, y, w, h;
    public Color color;
    public String type;
    public String content;
    public Path2D.Double projection;            
    public String name;

    public GraphicalObject(String name, String type, int x, int y, int w, int h, Color color){
        this.type = type;
        this.color = color;
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.name = name;

        projection = new Path2D.Double();
        projection.moveTo(x+(w/5), y+(h/5));
        projection.lineTo(x+w, y);
        projection.lineTo(x+w-(w/5), y+h-(h/5));
        projection.lineTo(x,y+h);
        projection.lineTo(x+(w/5), y+(h/5));

    }
    public GraphicalObject(String name, String type, int x, int y, String content, Color color){
        this.name = name;
        this.x = x;
        this.y = y;
        this.color = color;
        this.type = type;
        this.content = content;
     } 
}

0 个答案:

没有答案