使用碰撞属性创建许多对象。 JAVA

时间:2015-05-15 03:25:40

标签: java swing

我有一个带有三个矩形的简单程序:一个可以通过按下箭头键移动,另外两个已经自己来回移动。

当'播放器'矩形和顶部红色碰撞,玩家驱动的矩形被放回(0,0)。当我尝试将播放器矩形与底部红色矩形碰撞时,它没有那些碰撞属性,我不知道为什么。

我错过了什么?

import java.awt.*;//needed for graphics
import javax.swing.*;//needed for JFrame window
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class javaapplication23 extends JFrame implements KeyListener, ActionListener {

    public static int x = 0;
    public static int y = 0;
    public static int x2 = 100;
    public static int y2 = 100;

    public javaapplication23() {//constructor for JPanel
        add(new JP());

    }//close Jpanel Contructor

    public static void main(String[] args) {
        javaapplication23 w = new javaapplication23();
        w.setTitle("MIKE IS AWESOME");
        w.setSize(Toolkit.getDefaultToolkit().getScreenSize());
        w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        w.setVisible(true);
        w.addKeyListener(w);
    }

    public class JP extends JPanel {//start JPanel CLass

        public JP() {
            Container c = getContentPane();
            c.setBackground(Color.white);//backgraund color can be changed

        }

        public void paint(Graphics g) {//opens paint method
            super.paint(g);

            player(g, x, y);
            g.setColor(Color.RED);
            enemylevel1(g, x2, y2);

            Rectangle enemyblocks = new Rectangle(x2, y2, 25, 25);
            Rectangle player = new Rectangle(x, y, 25, 25);
            enemyblocks.contains(x2, y2);
            player.contains(x, y);

            if (player.getBounds().intersects(enemyblocks.getBounds())) {

                x = 0;
                y = 0;
            }

            pause(1);

            repaint();

        }//close paint method

    }//close JPanel Class

    public static void pause(int time) {

        try //opens an exception handling statement
        {
            Thread.sleep(time);
        } catch (InterruptedException e) {
        }  //captures the exception
    }

    public void actionPerformed(ActionEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {

        if (e.getKeyCode() == e.VK_RIGHT) {
            x += 20;//global variable controlling right movement
            repaint();
        }
        if (e.getKeyCode() == e.VK_LEFT) {
            x -= 20;//global variable controlling left movement
            repaint();
        }
        if (e.getKeyCode() == e.VK_UP) {
            y -= 20;//global variable controlling up movement
            repaint();
        }
        if (e.getKeyCode() == e.VK_DOWN) {
            y += 20;//global variable controlling down movement
            repaint();
        }
    }

    public void player(Graphics g, int x, int y) {

        g.fillRect(x, y, 30, 30);

    }

    public void enemylevel1(Graphics g, int x, int y) {

        g.fillRect(x2, y2, 25, 25);
        g.fillRect(x2, y2 + 100, 25, 25);

        if (x2 < 200 && y2 == 100) {

            x2 += 1;
        }
        if (x2 == 200 && y2 >= 100) {

            y2 += 1;
        }
        if (x2 <= 200 && y2 >= 101) {

            x2 -= 1;
        }
        if (x2 == 100 && y2 <= 101) {

            y2 -= 1;

        }
        pause(10);
        repaint();
    }

}

1 个答案:

答案 0 :(得分:2)

首先看一下Working with Geometry,这样可以减少代码的复杂性。

基本上,敌人只是一个RectangleGraphics2D可以在没有太大问题的情况下绘制它们。您需要做的是创建一个实例,该实例还可以根据您的需求更新它的位置

public class Enemy extends Rectangle {

    private int xDelta;

    public Enemy(int x, int y) {
        super(x, y, 20, 20);
        if (x == 0) {
            xDelta = 1;
        } else {
            xDelta = -1;
        }
    }

    public void update(Rectangle bounds) {
        x += xDelta;
        if (x < bounds.x) {
            x = bounds.x;
            xDelta *= -1;
        } else if (x > bounds.x + bounds.width - width) {
            x = bounds.x + bounds.width - width;
            xDelta *= -1;
        }

    }

}

因此,这创造了一个单独的工作单元,它与其他所有东西隔离开来,并带有它自己的逻辑。这使得更新,绘画和通常更简单的工作。

接下来,您需要创建List这些

public class Bounce extends JPanel implements KeyListener, ActionListener {

    private List<Enemy> enemies;
    //...

    public Bounce() {

        enemies = new ArrayList<>(5);
        int y = 100;
        for (int index = 0; index < 5; index++) {
            int x = (index % 2 == 0) ? 0  : 200;
            Enemy enemy = new Enemy(x, y);
            enemies.add(enemy);

            y += 60;
        }

这会创建一个List Enemy@Override protected void paintComponent(Graphics g) {//opens paint method super.paintComponent(g); Graphics2D g2d = (Graphics2D)g.create(); g2d.setColor(Color.RED); for (Enemy enemy : enemies) { g2d.fill(enemy); } }//close paint method ,它们在容器中均匀分布。

现在,我们需要画出它们......

paintComponent

nb:一般惯例建议您在要执行自定义绘画时应覆盖public void updateState() { Rectangle bounds = new Rectangle(20, 20, 200, 200); for (Enemy enemy : enemies) { enemy.update(bounds); } }

但他们不动,那种糟透了。所以我们需要一种方法来定期更新敌人的位置......

首先,我们创建一个简单的方法,我们可以调用它来更新敌人,记住,它们能够自我更新,我们只需要告诉它们什么时候

Enemy

请记住,javax.swing.Timer timer = new javax.swing.Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { updateState(); repaint(); } }); timer.start(); 是自包含的,它知道如何根据您提供的限制更新自己。

现在,我们需要定期调用此方法......

updateState

好的,这将每40毫秒安排一次回调,这将允许我们调用repaint方法和Rectangle组件。这很简洁,因为它不会阻止事件调度线程(使我们的程序看起来像挂起),但它会在EDT的上下文中通知我们,从而可以安全地从内部更新UI - WIN / WIN:)

请查看Concurrency in SwingHow to use Swing Timers了解详情。

好的,但这并不能解决碰撞......

玩家也是public class Bounce extends JPanel implements KeyListener, ActionListener { private List<Enemy> enemies; private Rectangle player; //... public Bounce() { player = new Rectangle(0, 0, 30, 30); enemies = new ArrayList<>(5); //... } @Override protected void paintComponent(Graphics g) {//opens paint method super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); drawPlayer(g2d); g2d.setColor(Color.RED); for (Enemy enemy : enemies) { g2d.fill(enemy); if (player.intersects(enemy)) { player.x = 0; player.y = 0; } } }//close paint method public void drawPlayer(Graphics2D g) { g.fill(player); } ,所以为什么不使用与敌人相同的概念......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Bounce extends JPanel implements KeyListener, ActionListener {

    private List<Enemy> enemies;
    private Rectangle player;

    public static void main(String[] args) {
        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 Bounce());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public Bounce() {

        player = new Rectangle(0, 0, 30, 30);
        enemies = new ArrayList<>(5);
        int y = 100;
        for (int index = 0; index < 5; index++) {
            int x = (index % 2 == 0) ? 0 : 200;
            Enemy enemy = new Enemy(x, y);
            enemies.add(enemy);

            y += 60;
        }

        setBackground(Color.white);//backgraund color can be changed
        Timer timer = new Timer(40, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updateState();
                repaint();
            }
        });
        timer.start();
        setFocusable(true);
        requestFocusInWindow();
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                requestFocusInWindow();
            }
        });
        addKeyListener(this);
    }

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

    @Override
    protected void paintComponent(Graphics g) {//opens paint method
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();

        drawPlayer(g2d);
        g2d.setColor(Color.RED);

        for (Enemy enemy : enemies) {
            g2d.fill(enemy);
            if (player.intersects(enemy)) {
                player.x = 0;
                player.y = 0;
            }
        }
    }//close paint method

    public void actionPerformed(ActionEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {

        if (e.getKeyCode() == e.VK_RIGHT) {
            player.x += 20;//global variable controlling right movement
        }
        if (e.getKeyCode() == e.VK_LEFT) {
            player.x -= 20;//global variable controlling left movement
        }
        if (e.getKeyCode() == e.VK_UP) {
            player.y -= 20;//global variable controlling up movement
        }
        if (e.getKeyCode() == e.VK_DOWN) {
            player.y += 20;//global variable controlling down movement
        }
    }

    public void drawPlayer(Graphics2D g) {

        g.fill(player);

    }

    public void updateState() {

        Rectangle bounds = new Rectangle(20, 20, 200, 200);
        for (Enemy enemy : enemies) {
            enemy.update(bounds);
        }

    }

    public class Enemy extends Rectangle {

        private int xDelta;

        public Enemy(int x, int y) {
            super(x, y, 20, 20);
            if (x == 0) {
                xDelta = 1;
            } else {
                xDelta = -1;
            }
        }

        public void update(Rectangle bounds) {
            x += xDelta;
            if (x < bounds.x) {
                x = bounds.x;
                xDelta *= -1;
            } else if (x > bounds.x + bounds.width - width) {
                x = bounds.x + bounds.width - width;
                xDelta *= -1;
            }

        }

    }
}

最终会出现像......

Enemies

这允许你根据需要添加/移除敌人,并且还可以简单轻松地改变敌人的移动方式

我的#34;真棒&#34;测试代码......

MSIEXEC.EXE /qb /L* "%LOGDIR%\myuninstaller.log" /x{GUID}