How to notify a multi-threaded swing game event

I have to do a little game simulation. There are three buttons in this game. when the user presses the start button, and the car will close each other at 90 degrees, when the user presses the close button, the tank will throw a bullet into the car.

i and simulations for this. tank throw a bullet at a car, but when a bullet crashes a car I couldn’t. I just need to increase the score, how many times the tank got into the car.

here is the source code

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

public class Vehicle extends Thread {
    private JPanel box;

    private int XSIZE;

    private int YSIZE;

    private int time;

    private int x;

    private int y;

    private int dx = 5;

    private int dy = 5;

    private int dim;

    public Vehicle(JPanel b, int i) {
        box = b;
        this.dim = i;
        if (i == 0) {
            x = 0;
            y = 100;
            time = 1000;
            XSIZE = 9;
            YSIZE = 20;
        } else {
            time = 200;
            y = box.getSize().height;
            x = box.getSize().width / 2;
            XSIZE = 6;
            YSIZE = 10;
        }
    }

    public void draw() {
        Graphics g = box.getGraphics();
        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }

    public void moveHorizontal() {
        if (!box.isVisible())
            return;
        Graphics g = box.getGraphics();
        g.setColor(Color.BLUE);
        g.setXORMode(box.getBackground());
        g.fillOval(x, y, XSIZE, YSIZE);
        x += dx;

        Dimension d = box.getSize();
        if (x < 0) {
            x = 0;
            dx = -dx;
        }
        if (x + XSIZE >= d.width) {
            x = d.width - XSIZE;
            dx = -dx;
        }

        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }

    public JPanel getBox() {
        return box;
    }

    public void setBox(JPanel box) {
        this.box = box;
    }

    public void moveVertical() {
        if (!box.isVisible())
            return;
        Graphics g = box.getGraphics();
        g.setXORMode(box.getBackground());
        g.fillOval(x, y, XSIZE, YSIZE);
        y += dy;
        Dimension d = box.getSize();
        if (y < 0) {
            y = 0;
            dy = -dy;
        }
        if (y + YSIZE >= d.height) {
            y = d.height - YSIZE;
            dy = -dy;
        }

        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }

    public void move(int i) {

        if (i == 0) {

            moveHorizontal();
        } else {
            moveVertical();
        }
    }

    public int getYSIZE() {
        return YSIZE;
    }

    public void setYSIZE(int ySIZE) {
        YSIZE = ySIZE;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public int getXSIZE() {
        return XSIZE;
    }

    public void setXSIZE(int xSIZE) {
        XSIZE = xSIZE;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void run() {
        try {
            draw();
            for (;;) {
                move(dim);
                sleep(time);
            }
        } catch (InterruptedException e) {
        }
    }

}

    import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

public class Bullet extends Thread {
    private JPanel box;

    private int XSIZE = 3;

    public int getXSIZE() {
        return XSIZE;
    }

    public void setXSIZE(int xSIZE) {
        XSIZE = xSIZE;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    private int YSIZE = 1;

    private int x;

    private int y;

    private int dx = 3;

    public Bullet(JPanel b, Vehicle tank, Vehicle car) {
        box = b;

        x = tank.getX() + tank.getXSIZE();
        if (x >= tank.getBox().getSize().width / 2)
            dx = -dx;

        y = tank.getY() + tank.getYSIZE() / 2;
        ;

    }

    public void draw() {
        Graphics g = box.getGraphics();
        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();
    }

    public void move() {
        if (!box.isVisible())
            return;
        Graphics g = box.getGraphics();
        g.setColor(Color.RED);
        g.setXORMode(box.getBackground());
        g.fillOval(x, y, XSIZE, YSIZE);
        x += dx;

        Dimension d = box.getSize();

        if (x < 0) {
            x = 0;

        }
        if (x + XSIZE >= d.width) {
            x = d.width - XSIZE;

        }
        g.fillOval(x, y, XSIZE, YSIZE);
        g.dispose();

    }

    public void run() {
        try {
            draw();
            for (;;) {
                move();

                sleep(20);
            }
        } catch (InterruptedException e) {
        }
    }

}

    import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;

@SuppressWarnings("serial")
public class Tank_Shut_Car_ThreadFrame extends JFrame {

    private JPanel canvas;
    private boolean isOn = false;
    private Vehicle tank;
    private Vehicle car;
    private JLabel score;
    public static int sc = 0;

    public Tank_Shut_Car_ThreadFrame() {
        setResizable(false);
        setSize(600, 400);
        setTitle("Tank Shut Car");
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        Container contentPane = getContentPane();
        canvas = new JPanel();
        contentPane.add(canvas, "Center");
        canvas.setLayout(null);

        score = new JLabel("0");
        score.setBounds(527, 11, 36, 14);
        canvas.add(score);

        JLabel lblScore = new JLabel("score");
        lblScore.setBounds(481, 11, 36, 14);
        canvas.add(lblScore);
        JPanel p = new JPanel();

        addButton(p, "Start", new ActionListener() {
            public void actionPerformed(ActionEvent evt) {

                if (!isOn) {
                    tank = new Vehicle(canvas, 0);
                    tank.start();
                    car = new Vehicle(canvas, 1);
                    car.start();
                    isOn = true;
                }
            }
        });

        addButton(p, "Shut", new ActionListener() {
            public void actionPerformed(ActionEvent evt) {

                if (isOn) {
                    Bullet bullet = new Bullet(canvas, tank, car);
                    bullet.start();
                    score.setText("" + sc);
                }

            }
        });
        addButton(p, "Close", new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                canvas.setVisible(false);
                System.exit(0);
            }
        });

        contentPane.add(p, "South");
    }

    public void addButton(Container c, String title, ActionListener a) {
        JButton button = new JButton(title);
        c.add(button);
        button.addActionListener(a);
    }

}

    import javax.swing.JFrame;

public class Test {
    public static void main(String[] args) {

        JFrame frame = new Tank_Shut_Car_ThreadFrame();
        frame.setVisible(true);
    }
}
0
source share
2 answers

Swing is not thread safe. Events must be fired in the event dispatch thread.

http://www.javamex.com/tutorials/threads/invokelater.shtml

+2

, ( ) Bangbang

"" "" , , .

, , Tank.zip

...

public class GameEngine extends Thread {

    public static final Object ASSET_LOCK = new Object();
    private List<GameAsset> lstAssets;
    private GameScreen screen;

    public GameEngine(GameScreen screen) {
        // Let the thread die when the JVM closes
        setDaemon(true);
        // Want to be below the UI thread (personal preference)
        setPriority(NORM_PRIORITY - 1);

        // A list of game assests
        lstAssets = new ArrayList<GameAsset>(25);
        // A reference to the screen
        this.screen = screen;
        // Add global key listener, this is simpler to the trying to attach a key listener
        // to the screen.
        Toolkit.getDefaultToolkit().addAWTEventListener(new EventHandler(), AWTEvent.KEY_EVENT_MASK);

    }

    public GameAsset[] getAssets() {
        synchronized (ASSET_LOCK) {
            return lstAssets.toArray(new GameAsset[lstAssets.size()]);
        }
    }

    /*
     * Allows for assets to be added
     */
    public void addAsset(GameAsset asset) {
        synchronized (ASSET_LOCK) {
            lstAssets.add(asset);
        }
    }

    @Override
    public void run() {

        while (true) {
            try {
                sleep(40);
            } catch (InterruptedException ex) {
            }

            synchronized (ASSET_LOCK) {
                GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
                for (GameAsset asset : assets) {
                    if (lstAssets.contains(asset)) {
                        asset.update(this, screen);
                    }
                }
                screen.repaint(new ArrayList<GameAsset>(lstAssets));
            }
        }
    }

    /**
     * Allows the removal of an asset...
     */
    public void removeAsset(GameAsset asset) {
        synchronized (ASSET_LOCK) {
            lstAssets.remove(asset);
        }
    }

    /**
     * Key event handling...
     */
    protected class EventHandler implements AWTEventListener {

        @Override
        public void eventDispatched(AWTEvent event) {
            KeyEvent keyEvent = (KeyEvent) event;
            if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
                synchronized (ASSET_LOCK) {
                    GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
                    for (GameAsset asset : assets) {
                        if (lstAssets.contains(asset)) {
                            asset.processKeyPressed(GameEngine.this, screen, keyEvent);
                        }
                    }
                }
            } else if (keyEvent.getID() == KeyEvent.KEY_RELEASED) {
                synchronized (ASSET_LOCK) {
                    GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
                    for (GameAsset asset : lstAssets) {
                        if (lstAssets.contains(asset)) {
                            asset.processKeyReleased(GameEngine.this, screen, keyEvent);
                        }
                    }
                }
            }
        }
    }
}
+1

All Articles