如何在碰撞后删除矩形?

时间:2014-01-07 00:35:23

标签: java collision

我有两个矩形,当它们相交时我需要从屏幕上取下。我需要消失的矩形是bulletObject和e1。当我运行它们时它们相交但没有任何反应。我试过把“e1 = new Rectangle(0,0,0,0);”在“if(bulletObject.intersects(e1)){”之后,它告诉我它从未使用过。所有帮助我都很感激。我的代码中有一大块在下面。

 public void draw(Graphics g){

    g.setColor(Color.BLUE);
    g.fillRect(x, y, 40, 10);
    g.fillRect(x+18, y-7, 4, 7);
    Rectangle bulletObject = new Rectangle(x+18, y-7, 4, 7);
    if (shot){
        g.setColor(Color.BLUE);
        g.fillRect(bullet.x, bullet.y , bullet.width, bullet.height);
    }
    //enemies

    g.setColor(Color.RED);
    Rectangle e1 = new Rectangle(20,75,35,35);
    Rectangle e2 = new Rectangle(85,75,35,35);
    Rectangle e3 = new Rectangle(150,75,35,35);
    Rectangle e4 = new Rectangle(205,75,35,35);
    Rectangle e5 = new Rectangle(270,75,35,35);
    Rectangle e6 = new Rectangle(335,75,35,35);
    Rectangle e7 = new Rectangle(405,75,35,35);
    g.setColor(Color.RED);
    g.fillRect(e1.x,e1.y,e1.width,e1.height);
    g.fillRect(e2.x,e2.y,e2.width,e2.height);
    g.fillRect(e3.x,e3.y,e3.width,e3.height);
    g.fillRect(e4.x,e4.y,e4.width,e4.height);
    g.fillRect(e5.x,e5.y,e5.width,e5.height);
    g.fillRect(e6.x,e6.y,e6.width,e6.height);
    g.fillRect(e7.x,e7.y,e7.width,e7.height);
    g.fillRect(bulletObject.x,bulletObject.y,
               bulletObject.width,bulletObject.height);

    if (bulletObject.intersects(e1)){          
        g.clearRect(e1.x, e1.y,e1.width, e1.height );

    }

}

3 个答案:

答案 0 :(得分:1)

让我们从...开始

你的绘画程序不适合做出关于游戏状态的决定,它应该是绘制当前状态的简单负责。

您需要维护一个List可渲染元素,您可以根据自己的需求和要求进行操作。

首先看一下Collections

您还可以通过Performing Custom LaintingPainting in AWT and Swing阅读有用的

以下示例演示了一系列动画,随机,矩形的基本概念,当被火球击中时将被删除,您可以通过按空格键来触发

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Bullet {

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

    public Bullet() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<Rectangle> ships;
        private Map<Rectangle, Integer> delats;

        private Ellipse2D fireBall;

        public TestPane() {
            delats = new HashMap<>(25);
            ships = new ArrayList<>(25);
            Random rnd = new Random();
            while (ships.size() < 12) {

                boolean intersects = true;
                Rectangle rect = null;
                while (intersects) {
                    intersects = false;
                    int x = (int) (Math.random() * 400);
                    int y = (int) (Math.random() * 400);
                    int width = (int) (Math.random() * 50) + 25;
                    int height = (int) (Math.random() * 50) + 25;

                    if (x + width >= 400) {
                        x = 400 - width;
                    } else if (y + height >= 400) {
                        y = 400 - height;
                    }

                    rect = new Rectangle(x, y, width, height);
                    for (Rectangle other : ships) {
                        if (other.intersects(rect)) {
                            intersects = true;
                            break;
                        }
                    }
                }
                ships.add(rect);
                delats.put(rect, (rnd.nextBoolean() ? 1 : -1));
            }

            Timer timer;
            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    if (fireBall != null) {

                        Rectangle bounds = fireBall.getBounds();

                        bounds.x += 5;
                        if (bounds.x >= getWidth()) {
                            fireBall = null;
                        } else {
                            fireBall.setFrame(bounds);
                        }

                    }
                    Iterator<Rectangle> it = ships.iterator();
                    while (it.hasNext()) {
                        Rectangle rct = it.next();
                        int delta = delats.get(rct);
                        rct.y += delta;
                        if (rct.y + rct.height >= getHeight()) {
                            rct.y = getHeight() - rct.height;
                            delta *= -1;
                        } else if (rct.y <= 0) {
                            rct.y = 0;
                            delta *= -1;
                        }

                        delats.put(rct, delta);

                        if (fireBall != null) {

                            if (fireBall.intersects(rct)) {
                                it.remove();
                                delats.remove(rct);
                            }

                        }

                    }

                    repaint();
                }
            });
            timer.start();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "fire");
            ActionMap am = getActionMap();
            am.put("fire", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fireBall = new Ellipse2D.Float(0, (getHeight() / 2) - 5, 10, 10);
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            if (fireBall != null) {

                g2d.setColor(Color.RED);
                g2d.fill(fireBall);

            }

            g2d.setColor(Color.BLACK);
            for (Rectangle rct : ships) {
                g2d.draw(rct);
            }
            g2d.dispose();
        }

    }

}

答案 1 :(得分:0)

听起来你是编程新手,因为你说你不明白列表是什么。我建议你查看在线提供的java教程(例如,了解列表和其他集合:http://docs.oracle.com/javase/tutorial/collections/)。 至于你的问题,我同意MadProgrammer,你应该有一个绘制函数绘制的对象列表,当一个矩形被“命中”时,你应该从这个列表中删除它。 例如,要创建列表,请使用:

List<Shape> shapeList = new ArrayList<Shape>();
Rectangle e1 = new Rectangle(20,75,35,35);
shapeList.add(e1);
Rectangle e2 = new Rectangle(85,75,35,35);
shapeList.add(e2);
//repeat for each rectangle

这不应该在你的draw方法中,因为这个方法将在我假设的程序中被多次调用,并且你不想每次都这样做时重新创建这个列表和每个矩形。

我建议您查看List和ArrayList的文档,并了解如何使用它们,因为几乎每次用Java编写程序时都会使用它们。 祝你好运

答案 2 :(得分:0)

将矩形存储在某种数据结构中 - 如果您知道矩形的最大可能数,则可以使用数组。如果不是 - 列表将是更好的选择,因为它的大小不固定(您只需在列表中添加和删除元素并且不关心它的大小 - 您可以在此处阅读有关列表的更多信息:{{3}在线搜索也应该富有成效。)

一旦所有矩形都在数组或列表(或您选择的任何其他集合)中,您可以绘制当前集合中的所有矩形。如果它们中的两个或更多个碰撞 - 从集合中删除它们并重新绘制(因此再次绘制集合中的所有矩形)。

如果所有这些对您来说都不熟悉(数组,集合......),我强烈建议您查看一些Java教程(或通用编程教程) - 例如Oracle的官方Java Turorial:{{3} }