矩形和尖线在摆动中旋转的碰撞

时间:2018-01-11 03:41:39

标签: java swing rotation collision-detection

只是一个小程序,我很快就看到我是否可以与矩形对象和旋转的矩形对象进行碰撞。

旋转矩形物体时出现问题,碰撞盒不旋转,只有图像旋转。

在这段代码中,我尝试使用shape对象但是对它进行了转换,但是没有成功。

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseEvent;
    import java.util.*;
    import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import javax.imageio.*;
    import java.awt.Toolkit;
    import java.awt.geom.AffineTransform;

    public class test extends JFrame implements Runnable,KeyListener
    {

      MyDrawPanel playPanel = new MyDrawPanel(); 

      Thread th= new Thread(this);
      int w=500, h=539;
      Rectangle s1;
      Rectangle r1;
      int x=50,y=50;
      int spx=0;
      int spy=0;
      int b=0;
      int spin=0,spin2=0;
      Shape p1;
      AffineTransform tx,ax;

      public static void main (String [] args)
      {
        new test();
      } 

      public test()
      { 
        s1= new Rectangle(200,200,106,16);
        p1= new Rectangle(200,200,106,16);
        r1= new Rectangle(x,y,50,50);

        this.setSize(w,h);
        this.setVisible(true);
        this.setResizable(true);
        this.addKeyListener(this);
        this.add(playPanel);
        playPanel.setDoubleBuffered(true);

        th.start();
      }
      public void keyPressed(KeyEvent e)
      {
        int key =e.getKeyCode();
        if (key == KeyEvent.VK_DOWN)  
        { 
          spy=2;
        }
        if (key == KeyEvent.VK_UP)  
        { 
          spy=-2;
        }
        if (key == KeyEvent.VK_RIGHT)  
        { 
          spx=2;
        }
        if (key == KeyEvent.VK_LEFT)  
        { 
          spx=-2;
        }
      } 
      public void keyReleased(KeyEvent e)
      {
        spx=0;
        spy=0;
      }  
      public void keyTyped(KeyEvent e)
      {} 

      public void coll()
      {
         if (r1.getBounds().intersects(p1.getBounds()))
        {
          b=1;
        }
        else{b=0;}
      }
      public void rot()
      {
        AffineTransform px= new AffineTransform();
        px.rotate(Math.toRadians(spin),w/2,h/2);
        p1=px.createTransformedShape(s1);
      }

    ///DO TOP HEAD INTERSECT CHECKINGGGGGGGGGGGGGGGGG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      public void run () 
      {
        while (true)
        {
          rot();

          r1.x+=spx;
          r1.y+=spy;
          spin+=2;
          coll();

          repaint();

          try 
          {
            Thread.sleep (30);  
          } 
          catch (InterruptedException ex)  
          {
          }
        }
      }

      class MyDrawPanel extends JPanel {
        public void paintComponent(Graphics g) 
        {
          Graphics2D g2 = (Graphics2D)g;
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
              RenderingHints.VALUE_ANTIALIAS_ON);
          if (b==1)
          {
            g2.setColor(Color.RED);
          }
          AffineTransform old= g2.getTransform();
         //g2.rotate(Math.toRadians(spin),
                 //p1.getBounds().x+8,p1.getBounds().y+8);
          g2.fillRect(p1.getBounds().x,p1.getBounds().y,106,16);
          g2.setTransform(old);
          g2.fillRect(r1.x,r1.y,r1.width,r1.height);
        }
      }
    }  


    //15.31
    /* ADD YOUR CODE HERE */

1 个答案:

答案 0 :(得分:0)

已使用Bresenham's algorithm to find all pixels on a Line2D to detect collision between Rectangle and Line through class LineIterator.

尝试下面所说的来源,增加 spx spy 的值,差异值为4,以便更快地移动广场: / p>

SpinningRod

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Iterator;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class RotateRectangleRound extends JFrame implements KeyListener {
    private static final long serialVersionUID = 9085168127541601308L;

    private Rectangle stableRect;
    private int cw = 400, ch = 400;
    private boolean collision;
    private int spx = 0, spy = 0;

    private double radius = 120;
    private double angleX = 0, angleY = 0;
    private int rotatingVal = 0;
    private Line2D line;
    private LineIterator iterator;
    private Point currentPoint;
    private Point2D tp;

    private static BasicStroke spinningStroke = new BasicStroke(8);
    private static BasicStroke basicStroke = new BasicStroke(1);

    private MyPanel panel;

    private static boolean startWorker;
    private SwingWorker<Void, Void> swingWorker;

    public RotateRectangleRound() {
        init();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new RotateRectangleRound();
            }
        });
    }

    private void init() {

        this.setTitle("Rotate Rectangle - Paused");
        this.getContentPane().setLayout(new GridLayout(1, 1));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(400, 200, 400, 400);

        this.setLayout(new GridLayout(1, 1));

        this.addKeyListener(this);
        this.setVisible(true);

        // getting the window width & height insets explicitly
        cw = this.getContentPane().getWidth();
        ch = this.getContentPane().getHeight();

        // setting the stableRect and movableRect to between of screen except insets
        stableRect = new Rectangle(20, 20, 40, 40);
        angleX = 192;
        angleY = 300;

        this.panel = new MyPanel();
        this.add(panel);

    }

    @Override
    public void keyTyped(KeyEvent evt) {}

    public void keyPressed(KeyEvent evt) {
        int key = evt.getKeyCode();

        if (key == KeyEvent.VK_DOWN) {
            spy = 4;
            moveStableRectangle();
        } else if (key == KeyEvent.VK_UP) {
            spy = -4;
            moveStableRectangle();
        } else if (key == KeyEvent.VK_RIGHT) {
            spx = 4;
            moveStableRectangle();
        } else if (key == KeyEvent.VK_LEFT) {
            spx = -4;
            moveStableRectangle();
        }

        if (key == KeyEvent.VK_SPACE) {
            startWorker = (!startWorker);
            if (startWorker) {
                this.setTitle("Rotate Rectangle");
                collision = false;
                startRotatingFromPoint();
            }else {
                this.setTitle("Rotate Rectangle - Paused");
            }
        }

    }

    private void moveStableRectangle() {
        stableRect.x += spx;
        stableRect.y += spy;
        repaint();
    }

    public void keyReleased(KeyEvent evt) {
        spx = 0;
        spy = 0;
    }

    private void startRotatingFromPoint() {
        swingWorker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                while (startWorker) {
                    try {
                        if (rotatingVal == 360)
                            rotatingVal = 0;

                        // first getting the angle x, y value for radius 100,
                        // second adding the half of width & height to rotate
                        // between screen accordingly with that w & h value
                        angleX = (Math.sin(Math.toRadians((double) rotatingVal)) * radius) + (cw / 2);
                        angleY = (Math.cos(Math.toRadians((double) rotatingVal++)) * radius) + (ch / 2);

                        // calculating collision
                        collision();
                        // requesting frame repainting
                        repaint();

                        Thread.sleep(10);
                    } catch (InterruptedException iex) {
                        iex.printStackTrace();
                    }
                }

                return null;
            }
        };

        swingWorker.execute();
    }

    public void collision() {
        if (detectCollision()) {
            collision = true;
            startWorker = false;
            this.setTitle("Rotate Rectangle - Hitted");
        } else {
            collision = false;
        }
    }

    private boolean detectCollision() {
        boolean flag = false;

        if(angleX < (cw/2))
            line = new Line2D.Double(angleX, angleY, cw / 2, ch / 2);
        else
            line = new Line2D.Double(cw / 2, ch / 2, angleX, angleY);

        //creating a iterator by use of Bresenham's algorithm
        iterator = new LineIterator(line);

        looperFor:
        for (Iterator<Point2D> it = iterator; it.hasNext();) {
            //getting Point2D Object of Point Iterator
            tp = it.next();
            currentPoint = new Point((int) tp.getX(), (int) tp.getY());

            if (stableRect.contains(currentPoint)) {
                flag = true;
                break looperFor;
            }
        }

        //returning the detected collision flag true or false
        return flag;
    }

    class MyPanel extends JPanel {
        private static final long serialVersionUID = 1L;

        @Override
        public void paintComponent(Graphics gr) {
            Graphics2D g = (Graphics2D) gr;

            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

            g.setStroke(basicStroke);

            if (collision)
                g.setColor(Color.RED);

            g.fillRect(stableRect.x, stableRect.y, stableRect.width, stableRect.height);
            g.setStroke(spinningStroke);
            g.drawLine(cw / 2, ch / 2, (int) angleX, (int) angleY);
        }
    }

}

希望这会对你有所帮助。