import java.awt.*;import java.awt.event.*;import java.awt.geom.Rectangle2D;
import javax.swing.*;
/** * @version 1.0.2 2010-04-08 * @author liangdong HIT */
public class MoveTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { MoveFrame frame = new MoveFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); }}
/** * frame */class MoveFrame extends JFrame { /** * cancel warning */ private static final long serialVersionUID = 1L;
public MoveFrame() { setTitle("MoveTest"); setBounds(STARTX, STARTY, DEFAULT_WIDTH, DEFAULT_HEIGHT);
MovePanel panel = new MovePanel(); add(panel); }
public static final int STARTX = 100; public static final int STARTY = 100; public static final int DEFAULT_WIDTH = 800; public static final int DEFAULT_HEIGHT = 600;
}
/** * panel */class MovePanel extends JPanel { /** * cancel warning */ private static final long serialVersionUID = 1L;
public MovePanel() { setLayout(new BorderLayout()); Action insert = new MoveAction(); x1 = 100; y1 = 100; x2 = 540; y2 = 100; x3 = 100; y3 = 460; x4 = 540; y4 = 460; choice = 1; result = false; lu = new Rectangle2D.Double(x1, y1, D, D); wu = new Rectangle2D.Double(x2, y2, D, D); ld = new Rectangle2D.Double(x3, y3, D, D); wd = new Rectangle2D.Double(x4, y4, D, D); rlu = new Rectangle2D.Double(340, 260, D, D); rwu = new Rectangle2D.Double(380, 260, D, D); rld = new Rectangle2D.Double(340, 300, D, D); rwd = new Rectangle2D.Double(380, 300, D, D);
InputMap imap = this.getInputMap(); imap.put(KeyStroke.getKeyStroke('1'), "lu"); imap.put(KeyStroke.getKeyStroke('2'), "wu"); imap.put(KeyStroke.getKeyStroke('3'), "ld"); imap.put(KeyStroke.getKeyStroke('4'), "wd"); imap.put(KeyStroke.getKeyStroke('w'), "up"); imap.put(KeyStroke.getKeyStroke('s'), "down"); imap.put(KeyStroke.getKeyStroke('a'), "left"); imap.put(KeyStroke.getKeyStroke('d'), "right");
ActionMap amap = this.getActionMap(); amap.put("lu", insert); amap.put("wu", insert); amap.put("ld", insert); amap.put("wd", insert); amap.put("up", insert); amap.put("down", insert); amap.put("left", insert); amap.put("right", insert); new Thread(new Rusult()).start();
}
public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.RED); g2.fill(lu); g2.draw(rlu); g2.setColor(Color.BLACK); g2.fill(wu); g2.draw(rwu); g2.setColor(Color.BLUE); g2.fill(ld); g2.draw(rld); g2.setColor(Color.GREEN); g2.fill(wd); g2.draw(rwd); if(result) { g2.setColor(Color.RED); Font f = getFont(); g2.setFont(new Font(f.getFontName(),f.getStyle(),30)); g2.drawString("you win", 340, 80); } }
private class MoveAction extends AbstractAction { /** * cancel warning */ private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent event) { input = event.getActionCommand(); if (input.equals("1")) choice = 1; else if (input.equals("2")) choice = 2; else if (input.equals("3")) choice = 3; else if (input.equals("4")) choice = 4; if (choice == 1) { Move(lu); } else if (choice == 2) { Move(wu); } else if (choice == 3) { Move(ld); } else if (choice == 4) { Move(wd); } } private void Move(Rectangle2D r) { double x = r.getX(); double y = r.getY(); double x1 = x; double y1 = y; if (input.equals("w") && y > 100) y = y - 40; else if (input.equals("s") && y < 450) y = y + 40; else if (input.equals("a") && x > 100) x = x - 40; else if (input.equals("d") && x1 < 540) x = x + 40; r.setRect(x, y, D, D); if(ztpz()) r.setRect(x1, y1, D, D); repaint(); } private String input; } private class Rusult implements Runnable { public void run() { while(true){ if(lu.equals(rlu)&&wu.equals(rwu)&&ld.equals(rld)&&wd.equals(rwd)) { result = true; repaint(); } else result = false; } } } /** * @author liangdong * @param r1 rectangle2D 1 第一个矩形 * @param r2 rectangle2D 2 第二个矩形 * @return true 意思是发生碰撞 false 意思是没有发生碰撞 */ private boolean isdash(Rectangle2D r1,Rectangle2D r2) { double x1 = r1.getCenterX(); double y1 = r1.getCenterY(); double x2 = r2.getCenterX(); double y2 = r2.getCenterY(); if(Math.abs(x1-x2)<D&&Math.abs(y1-y2)<D) return true; else return false; } /** * 整体碰撞检测 * @return true 意思是整体发生了碰撞 */ private boolean ztpz() { if(isdash(lu,wu)||isdash(lu,ld)||isdash(lu,wd)||isdash(wu,ld)||isdash(wu,wd)||isdash(ld,wd)) return true; else return false; } private Rectangle2D lu; private Rectangle2D wu; private Rectangle2D ld; private Rectangle2D wd; private Rectangle2D rlu; private Rectangle2D rwu; private Rectangle2D rld; private Rectangle2D rwd; private int choice; private boolean result; private double x1; private double y1; private double x2; private double y2; private double x3; private double y3; private double x4; private double y4; public static final double D = 40;}
矩形的碰撞检测问题,对这个模型, |x1-x2|<D and |y1-y2|<D 就能达到目的,原因是两个矩形的边都平行于XY轴,如果不平行的话如何处理?有人明白这个算法吗?想了一段时间没想到答案,