0

我应该做一个小游戏模拟。在这个游戏中有三个按钮。当用户点击启动坦克和汽车将在 90 度关闭对方当用户点击关闭按钮坦克将向汽车投掷子弹。

我为此做了一个模拟。坦克向汽车投掷子弹,但当子弹撞击汽车时,我无法做到这一点。我只需要增加坦克撞车的次数。

这是源代码

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);
    }
}
4

2 回答 2

2

好的,所以我玩了这个(只是为了好玩) 嘭嘭

现在,这远非一个“正确”或“完整”的游戏引擎,但它提供了一个基本概念,即如何将核心线程引擎与 UI 组件混合在一起。

我没有粘贴整个代码,而是将它的源代码上传到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);
                        }
                    }
                }
            }
        }
    }
}
于 2012-09-17T06:52:12.653 回答
2

Swing 不是线程安全的。事件应该在事件调度线程上触发。

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

于 2012-09-15T15:41:40.877 回答