要完成java大作业,不知为何就想做一个坦克大战。

功能是逐步加上去的。一开始就是几个IconImage在一个Frame中移动,后来逐渐加入线程、碰撞检测、导弹发射、击中检测、背景音乐、音效、血量控制、音乐开关、起始控制面板、墙壁。。。等等等等。。。

由于一开始没有规划好,没有做好类的层次设计,导致想要继承时发现出了问题,所以我方坦克和敌方坦克出现了一定的代码重写。最后懒得改了,所以这个遗憾就留下了。

【功能分配】

TankClient.java:客户端主界面,继承 JFrame

InitOptionPanel.java:游戏启动时的选择面板,选择自己起始血量、敌方坦克数量、音乐开关、音效开关。

BattleFieldCanvas.java:对所有类的draw方法进行调用,用于重绘界面。其中也涉及胜利和失败时的音效控制。

MyTank.java:我方坦克类

EnemyTank.java:敌方坦克类

Wall.java:墙壁类

Missile.java:炮弹类

下面贴代码:

TankClient.java

import java.awt.*; import java.awt.event.*; import java.applet.*; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Random; import javax.swing.*; import org.omg.CORBA.PRIVATE_MEMBER; import org.omg.CORBA.PUBLIC_MEMBER; public class TankClient extends JFrame implements ActionListener { public static final int WINDOW_WIDTH = 1000;// 实际是Canvas的宽度 public static final int WINDOW_HEIGHT = 700;// 实际是Canvas的高度 public static int WINDOW_X;// 起始窗口位置X坐标 public static int WINDOW_Y;// 起始窗口位置Y坐标 // public static final int ENEMY_TOTAL_COUNT = 20;// 敌方坦克从开始到结束的总数 public static InitOptionPanel initOptionPanel = null; public static final int FLUSH_FREQ = 50;// 图像刷新频率,每隔FLUSH_FREQ毫秒刷新一次 public static TankClient currentClient;// 目前工作的主界面 public static TankClient oldClient;// 重启时用于暂存旧的主界面的引用 public static boolean optionFinished = false;//若开始时设置面板设置完毕并点击了“开始”,则置为true;否则为false private JMenuBar menuBar = new JMenuBar(); private JMenu fileMenu = new JMenu("文件"); private JMenu optionMenu = new JMenu("选项"); private JMenu helpMenu = new JMenu("帮助"); private JMenuItem restartMenuItem = new JMenuItem("重新开始(F2)"); private JMenuItem exitMenuItem = new JMenuItem("退出"); private JCheckBoxMenuItem bgAudioMenuItem = new JCheckBoxMenuItem("背景音乐"); private JCheckBoxMenuItem soundEffectMenuItem = new JCheckBoxMenuItem("音效"); private JMenuItem aboutMenuItem = new JMenuItem("关于"); private AudioClip bgAudio = null; private Image battleFieldImage = null;// 用于在update()中缓存的图片对象 public BattleFieldCanvas battleFieldCanvas = null;// 用于显示游戏画面的Canvas对象 private Thread repaintThread = new Thread(new RepaintThread());// 每隔FLUSH_FREQ的时间,就调用该线程重绘画面 private boolean bgAudioPlaying = false;// 是否正在播放背景音乐 public static int myFullHealth;// 我的生命值 public static int enemyCount = 1;// 初始时敌人数量 public static boolean enableBgAudio; public static boolean enableSoundEffect; private MyTank myTank = null; private Wall wall = null; private ArrayList<EnemyTank> enemyTanks = new ArrayList<EnemyTank>(); private ArrayList<Wall> walls = new ArrayList<Wall>(); public static TextField textField = new TextField(); public static File audioBase = null; public void setEnemyCount(int enemyCount){ this.enemyCount = enemyCount; } public int getEnemyCount(){ return enemyCount; } public void restartGame() { // this.repaintThread.stop(); bgAudio.stop(); bgAudio = null; battleFieldCanvas.resultAudioClip = null; repaintThread.stop(); repaintThread = null; oldClient = currentClient; oldClient.dispose(); currentClient = new TankClient(); } public void quitGame() { // this.repaintThread.stop(); System.exit(0); } public TankClient() { super("坦克大战"); // 初始化主窗口位置 initOptionPanel.dispose(); Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); WINDOW_X = ((int) dimension.getWidth() – WINDOW_WIDTH) / 2; WINDOW_Y = ((int) dimension.getHeight() – WINDOW_HEIGHT) / 2 – 50; // 初始化背景音乐 audioBase = new File(System.getProperty("user.dir") + "//audio"); File bgAudioFile = new File(audioBase, "bgAudio.au"); try { bgAudio = Applet.newAudioClip(bgAudioFile.toURL()); } catch (Exception e) { e.printStackTrace(); } if (enableBgAudio) { if (!bgAudioPlaying) { bgAudioPlaying = true; bgAudio.loop(); } } // 初始化我方坦克 myTank = new MyTank(enemyTanks, walls, battleFieldCanvas, (WINDOW_WIDTH – MyTank.TANK_WIDTH) / 2, WINDOW_HEIGHT / 2 – 100); // 初始化敌方坦克 /* * for (int i = 0; i <= ENEMY_COUNT / 2 – 1; i++) { * * EnemyTank enemyTank = new EnemyTank(enemyTanks, myTank, walls, (i % * ENEMY_COUNT) WINDOW_WIDTH / ENEMY_COUNT, WINDOW_HEIGHT - * EnemyTank.TANK_HEIGHT); enemyTanks.add(i, enemyTank); } for(int i = * ENEMY_COUNT / 2; i < ENEMY_COUNT; i++){ EnemyTank enemyTank = new * EnemyTank(enemyTanks, myTank, walls, (i % ENEMY_COUNT) WINDOW_WIDTH / * ENEMY_COUNT, 0); enemyTanks.add(i, enemyTank); } */ for (int i = 0; i < getEnemyCount(); i++) { boolean temp = false; do { temp = loopCallForEnemyInit(i); } while (!temp); } // 对三堵墙分别初始化 wall = new Wall(0, WINDOW_HEIGHT / 3); walls.add(0, wall); wall = new Wall(WINDOW_WIDTH – wall.getWidth(), WINDOW_HEIGHT / 3); walls.add(1, wall); wall = new Wall(WINDOW_WIDTH / 2 – wall.getWidth() / 2, 2 * WINDOW_HEIGHT / 3); walls.add(2, wall); wall = null; // 初始化战场画布 battleFieldCanvas = new BattleFieldCanvas(battleFieldImage, myTank, enemyTanks, walls); repaintThread.start(); // 添加键盘监听器 addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent ke) { myTank.keyPressed(ke); } public void keyReleased(KeyEvent ke) { myTank.keyReleased(ke); } }); // 对各组件布局 this.setLayout(new BorderLayout()); fileMenu.add(restartMenuItem); restartMenuItem.addActionListener(this); fileMenu.addSeparator(); fileMenu.add(exitMenuItem); exitMenuItem.addActionListener(this); optionMenu.add(bgAudioMenuItem); optionMenu.add(soundEffectMenuItem); bgAudioMenuItem.setSelected(true); soundEffectMenuItem.setSelected(true); bgAudioMenuItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent ie) { if (bgAudioMenuItem.isSelected()) { enableBgAudio = true; } else { enableBgAudio = false; } } }); soundEffectMenuItem.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent ie) { if (soundEffectMenuItem.isSelected()) { enableSoundEffect = true; } else { enableSoundEffect = false; } } }); helpMenu.add(aboutMenuItem); aboutMenuItem.addActionListener(this); menuBar.add(fileMenu); menuBar.add(optionMenu); menuBar.add(helpMenu); setJMenuBar(menuBar); add(BorderLayout.CENTER, battleFieldCanvas); textField.setFocusable(false); // battleFieldCanvas.setFocusable(true); pack(); setSize(getPreferredSize()); setLocation(WINDOW_X, WINDOW_Y); // setResizable(false); setVisible(true); this.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent ke) { myTank.keyPressed(ke); } public void keyReleased(KeyEvent ke) { myTank.keyReleased(ke); } }); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(0); } }); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == restartMenuItem) { restartGame(); } else if (ae.getSource() == exitMenuItem) { //this.quitGame(); //repaintThread.stop(); System.exit(0); } else if (ae.getSource() == aboutMenuItem) { JOptionPane tempPane = new JOptionPane(); tempPane.showMessageDialog(this, "版权所有:ljf from WHU/n出厂日期:2010-12-20"); } } public boolean loopCallForEnemyInit(int index) {// 初始化敌方坦克时调用,index用于确定放入容器的位置 Random rand = new Random(); int tempPosX; int tempPosY; tempPosX = rand.nextInt(WINDOW_WIDTH); tempPosY = rand.nextInt(WINDOW_HEIGHT); EnemyTank enemyTank = new EnemyTank(enemyTanks, myTank, walls, tempPosX, tempPosY); if (enemyTank.collideWithSomething(myTank)) { return false; } for (int i = 0; i < enemyTanks.size(); i++) { if (enemyTank.collideWithSomething(enemyTanks.get(i))) { return false; } } for (int i = 0; i < walls.size(); i++) { if (enemyTank.collideWithSomething(walls.get(i))) { return false; } } enemyTanks.add(index, enemyTank); return true; } public static boolean getEnableBgAudio() { return enableBgAudio; } public static boolean getEnableSoundEffect() { return enableSoundEffect; } public class RepaintThread implements Runnable { public void run() { while (true) { battleFieldCanvas.repaint(); if (!getEnableBgAudio()) { bgAudio.stop(); bgAudioPlaying = false; } else if (!bgAudioPlaying) { bgAudio.loop(); bgAudioPlaying = true; } try { repaintThread.sleep(FLUSH_FREQ); } catch (InterruptedException ie) { ie.printStackTrace(); } } } } }

InitOptionPanel.java

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; public class InitOptionPanel extends JFrame { private final int ENEMY_MINIMUM = 1; private final int ENEMY_MAXIMUM = 20; private final int ENEMY_DEFAULT = 5; private JSlider enemyCountSlider = null;// 设置地方坦克数量 private JSpinner myHealthSpinner = null;// 滑动设置我的初始生命值 private SpinnerModel myHealthSpinnerModel = new SpinnerNumberModel(3, 1, 4, 1); private JCheckBox bgAudioCheckBox = new JCheckBox("背景音乐"); private JCheckBox soundEffect = new JCheckBox("音 效"); private JButton okButton = new JButton("开始游戏"); private JButton exitButton = new JButton("退出游戏"); private JPanel choosePanel1 = new JPanel(); private JPanel choosePanel2 = new JPanel(); private JPanel checkboxPanel = new JPanel(); private JPanel buttonPanel = new JPanel(); private JTextField showEnemyCountTextField = new JTextField(Integer .toString(ENEMY_DEFAULT), 4);// 用于显示滑块当前所指向的数字 private JLabel myHealthLabel = new JLabel("我的初始生命值 "); private JLabel enemyCountLabel = new JLabel("敌方坦克数量 "); public InitOptionPanel() { super("坦克大战-游戏选项"); // 初始化myHealthSpinner myHealthSpinner = new JSpinner(myHealthSpinnerModel); // 初始化enemyCountSlider enemyCountSlider = new JSlider(); enemyCountSlider.setValue(ENEMY_DEFAULT); enemyCountSlider.setMinimum(ENEMY_MINIMUM); enemyCountSlider.setMaximum(ENEMY_MAXIMUM); enemyCountSlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ce) { showEnemyCountTextField.setText(Integer .toString(enemyCountSlider.getValue())); } }); // 对数值选择域布局 choosePanel1.setLayout(new BorderLayout()); choosePanel1.setBorder(BorderFactory.createEmptyBorder(40, 30, 20, 40)); choosePanel1.add(BorderLayout.WEST, myHealthLabel); choosePanel1.add(BorderLayout.CENTER, myHealthSpinner); choosePanel2.setLayout(new BorderLayout()); choosePanel2.setBorder(BorderFactory.createEmptyBorder(40, 30, 20, 40)); choosePanel2.add(BorderLayout.WEST, enemyCountLabel); choosePanel2.add(BorderLayout.CENTER, enemyCountSlider); showEnemyCountTextField.setEditable(false); choosePanel2.add(BorderLayout.EAST, showEnemyCountTextField); // 对复选框域布局 checkboxPanel .setBorder(BorderFactory.createEmptyBorder(10, 30, 20, 30)); checkboxPanel.add(bgAudioCheckBox); checkboxPanel.add(soundEffect); bgAudioCheckBox.setSelected(true); soundEffect.setSelected(true); // 对按钮布局 buttonPanel.add(okButton); buttonPanel.add(exitButton); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { // TankClient.optionFinished = true; TankClient.myFullHealth = Integer.parseInt(myHealthSpinner .getValue().toString()); TankClient.enemyCount = enemyCountSlider.getValue(); TankClient.enableBgAudio = bgAudioCheckBox.isSelected(); TankClient.enableSoundEffect = soundEffect.isSelected(); TankClient.currentClient = new TankClient(); } }); exitButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { System.exit(0); } }); // 向Frame中添加Panel setLayout(new GridLayout(0, 1)); add(choosePanel1); add(choosePanel2); add(checkboxPanel); add(buttonPanel); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); pack(); } public static void main(String args[]) { TankClient.initOptionPanel = new InitOptionPanel(); } }

BattleFieldCanvas.java

import java.applet.Applet; import java.applet.AudioClip; import java.awt.*; import java.io.File; import java.util.ArrayList; import org.w3c.dom.css.RGBColor; public class BattleFieldCanvas extends Canvas { private Image battleFieldImage = null; private Image bgImage = Toolkit.getDefaultToolkit().getImage( "background.jpg"); private MyTank myTank = null; private ArrayList<EnemyTank> enemyTanks = null; private ArrayList<Wall> walls = null; private boolean youWin = false;// 若已经消灭了所有敌人取得了胜利,则为true;否则为false private boolean youLose = false;// 若你被打死了,则你输了,置为false;否则为true private Image winScreenImage = Toolkit.getDefaultToolkit().getImage( "winScreen.gif"); private Image loseScreenImage = Toolkit.getDefaultToolkit().getImage( "loseScreen.gif"); private final int winScreenImageWidth = 600; private final int winScreenImageHeight = 300; public AudioClip resultAudioClip = null;// 胜利了或失败了,分别播放的对应音乐 private String resultAudioString = null;// 对应要播放的音乐的文件名 private boolean resultAudioPlayed = false;// 若胜利、失败音乐已经(在)播放了,则为真;否则为假。用来防止多次播放。 public BattleFieldCanvas(Image battleFieldImage, MyTank myTank, ArrayList<EnemyTank> enemyTanks, ArrayList<Wall> walls) { super(); this.walls = walls; this.myTank = myTank; this.enemyTanks = enemyTanks; this.battleFieldImage = battleFieldImage; this.setSize(TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT); } public boolean getYouWin() { return youWin; } public boolean getYouLose() { return youLose; } public void paint(Graphics g) { // g.clearRect(0, 0, this.getWidth(), this.getHeight()); g.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); for (int i = 0; i < walls.size(); i++) { Wall wall = walls.get(i); wall.draw(g); } if (myTank.canBePaint()) { myTank.draw(g); } for (int i = 0; i < enemyTanks.size(); i++) { EnemyTank temp = enemyTanks.get(i); if (temp.canBePaint()) { temp.draw(g); } } } public void update(Graphics g) { if (battleFieldImage == null) { battleFieldImage = this.createImage(TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT); } Graphics gra = battleFieldImage.getGraphics(); if (enemyTanks.isEmpty()) { youWin = true; } if (!myTank.isAlive()) { youLose = true; } if (!youWin && !youLose) { paint(gra); } else if (youWin) { if (!resultAudioPlayed) { resultAudioString = "youWin.au"; try { resultAudioClip = Applet.newAudioClip((new File( TankClient.audioBase, resultAudioString)).toURL()); } catch (Exception e) { e.printStackTrace(); } if (TankClient.getEnableSoundEffect()) { resultAudioClip.play(); } resultAudioPlayed = true; } gra.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); gra.drawImage(winScreenImage, (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, (TankClient.WINDOW_HEIGHT – this.winScreenImageHeight) / 2, null); Font font = new Font("my font", Font.BOLD, 25); gra.setFont(font); gra.drawString("点击【F2】重新开始游戏,【F4】退出游戏", (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, 200); } else if (youLose) { if (!resultAudioPlayed) { resultAudioString = "youLose.au"; try { resultAudioClip = Applet.newAudioClip((new File( TankClient.audioBase, resultAudioString)).toURL()); } catch (Exception e) { e.printStackTrace(); } if (TankClient.getEnableSoundEffect()) { resultAudioClip.play(); } resultAudioPlayed = true; } gra.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); gra.drawImage(loseScreenImage, (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, (TankClient.WINDOW_HEIGHT – this.winScreenImageHeight) / 2, null); Font font = new Font("my font", Font.BOLD, 25); gra.setFont(font); gra.drawString("点击【F2】重新开始游戏,【F4】退出游戏", (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, 200); } g.drawImage(battleFieldImage, 0, 0, this); } }

MyTank.java

import java.applet.Applet; import java.applet.AudioClip; import java.awt.*; import java.io.File; import java.util.ArrayList; import org.w3c.dom.css.RGBColor; public class BattleFieldCanvas extends Canvas { private Image battleFieldImage = null; private Image bgImage = Toolkit.getDefaultToolkit().getImage( "background.jpg"); private MyTank myTank = null; private ArrayList<EnemyTank> enemyTanks = null; private ArrayList<Wall> walls = null; private boolean youWin = false;// 若已经消灭了所有敌人取得了胜利,则为true;否则为false private boolean youLose = false;// 若你被打死了,则你输了,置为false;否则为true private Image winScreenImage = Toolkit.getDefaultToolkit().getImage( "winScreen.gif"); private Image loseScreenImage = Toolkit.getDefaultToolkit().getImage( "loseScreen.gif"); private final int winScreenImageWidth = 600; private final int winScreenImageHeight = 300; public AudioClip resultAudioClip = null;// 胜利了或失败了,分别播放的对应音乐 private String resultAudioString = null;// 对应要播放的音乐的文件名 private boolean resultAudioPlayed = false;// 若胜利、失败音乐已经(在)播放了,则为真;否则为假。用来防止多次播放。 public BattleFieldCanvas(Image battleFieldImage, MyTank myTank, ArrayList<EnemyTank> enemyTanks, ArrayList<Wall> walls) { super(); this.walls = walls; this.myTank = myTank; this.enemyTanks = enemyTanks; this.battleFieldImage = battleFieldImage; this.setSize(TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT); } public boolean getYouWin() { return youWin; } public boolean getYouLose() { return youLose; } public void paint(Graphics g) { // g.clearRect(0, 0, this.getWidth(), this.getHeight()); g.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); for (int i = 0; i < walls.size(); i++) { Wall wall = walls.get(i); wall.draw(g); } if (myTank.canBePaint()) { myTank.draw(g); } for (int i = 0; i < enemyTanks.size(); i++) { EnemyTank temp = enemyTanks.get(i); if (temp.canBePaint()) { temp.draw(g); } } } public void update(Graphics g) { if (battleFieldImage == null) { battleFieldImage = this.createImage(TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT); } Graphics gra = battleFieldImage.getGraphics(); if (enemyTanks.isEmpty()) { youWin = true; } if (!myTank.isAlive()) { youLose = true; } if (!youWin && !youLose) { paint(gra); } else if (youWin) { if (!resultAudioPlayed) { resultAudioString = "youWin.au"; try { resultAudioClip = Applet.newAudioClip((new File( TankClient.audioBase, resultAudioString)).toURL()); } catch (Exception e) { e.printStackTrace(); } if (TankClient.getEnableSoundEffect()) { resultAudioClip.play(); } resultAudioPlayed = true; } gra.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); gra.drawImage(winScreenImage, (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, (TankClient.WINDOW_HEIGHT – this.winScreenImageHeight) / 2, null); Font font = new Font("my font", Font.BOLD, 25); gra.setFont(font); gra.drawString("点击【F2】重新开始游戏,【F4】退出游戏", (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, 200); } else if (youLose) { if (!resultAudioPlayed) { resultAudioString = "youLose.au"; try { resultAudioClip = Applet.newAudioClip((new File( TankClient.audioBase, resultAudioString)).toURL()); } catch (Exception e) { e.printStackTrace(); } if (TankClient.getEnableSoundEffect()) { resultAudioClip.play(); } resultAudioPlayed = true; } gra.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); gra.drawImage(loseScreenImage, (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, (TankClient.WINDOW_HEIGHT – this.winScreenImageHeight) / 2, null); Font font = new Font("my font", Font.BOLD, 25); gra.setFont(font); gra.drawString("点击【F2】重新开始游戏,【F4】退出游戏", (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, 200); } g.drawImage(battleFieldImage, 0, 0, this); } }

EnemyTank.java

import java.applet.Applet; import java.applet.AudioClip; import java.awt.*; import java.io.File; import java.util.ArrayList; import org.w3c.dom.css.RGBColor; public class BattleFieldCanvas extends Canvas { private Image battleFieldImage = null; private Image bgImage = Toolkit.getDefaultToolkit().getImage( "background.jpg"); private MyTank myTank = null; private ArrayList<EnemyTank> enemyTanks = null; private ArrayList<Wall> walls = null; private boolean youWin = false;// 若已经消灭了所有敌人取得了胜利,则为true;否则为false private boolean youLose = false;// 若你被打死了,则你输了,置为false;否则为true private Image winScreenImage = Toolkit.getDefaultToolkit().getImage( "winScreen.gif"); private Image loseScreenImage = Toolkit.getDefaultToolkit().getImage( "loseScreen.gif"); private final int winScreenImageWidth = 600; private final int winScreenImageHeight = 300; public AudioClip resultAudioClip = null;// 胜利了或失败了,分别播放的对应音乐 private String resultAudioString = null;// 对应要播放的音乐的文件名 private boolean resultAudioPlayed = false;// 若胜利、失败音乐已经(在)播放了,则为真;否则为假。用来防止多次播放。 public BattleFieldCanvas(Image battleFieldImage, MyTank myTank, ArrayList<EnemyTank> enemyTanks, ArrayList<Wall> walls) { super(); this.walls = walls; this.myTank = myTank; this.enemyTanks = enemyTanks; this.battleFieldImage = battleFieldImage; this.setSize(TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT); } public boolean getYouWin() { return youWin; } public boolean getYouLose() { return youLose; } public void paint(Graphics g) { // g.clearRect(0, 0, this.getWidth(), this.getHeight()); g.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); for (int i = 0; i < walls.size(); i++) { Wall wall = walls.get(i); wall.draw(g); } if (myTank.canBePaint()) { myTank.draw(g); } for (int i = 0; i < enemyTanks.size(); i++) { EnemyTank temp = enemyTanks.get(i); if (temp.canBePaint()) { temp.draw(g); } } } public void update(Graphics g) { if (battleFieldImage == null) { battleFieldImage = this.createImage(TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT); } Graphics gra = battleFieldImage.getGraphics(); if (enemyTanks.isEmpty()) { youWin = true; } if (!myTank.isAlive()) { youLose = true; } if (!youWin && !youLose) { paint(gra); } else if (youWin) { if (!resultAudioPlayed) { resultAudioString = "youWin.au"; try { resultAudioClip = Applet.newAudioClip((new File( TankClient.audioBase, resultAudioString)).toURL()); } catch (Exception e) { e.printStackTrace(); } if (TankClient.getEnableSoundEffect()) { resultAudioClip.play(); } resultAudioPlayed = true; } gra.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); gra.drawImage(winScreenImage, (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, (TankClient.WINDOW_HEIGHT – this.winScreenImageHeight) / 2, null); Font font = new Font("my font", Font.BOLD, 25); gra.setFont(font); gra.drawString("点击【F2】重新开始游戏,【F4】退出游戏", (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, 200); } else if (youLose) { if (!resultAudioPlayed) { resultAudioString = "youLose.au"; try { resultAudioClip = Applet.newAudioClip((new File( TankClient.audioBase, resultAudioString)).toURL()); } catch (Exception e) { e.printStackTrace(); } if (TankClient.getEnableSoundEffect()) { resultAudioClip.play(); } resultAudioPlayed = true; } gra.drawImage(bgImage, 0, 0, TankClient.WINDOW_WIDTH, TankClient.WINDOW_HEIGHT, null); gra.drawImage(loseScreenImage, (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, (TankClient.WINDOW_HEIGHT – this.winScreenImageHeight) / 2, null); Font font = new Font("my font", Font.BOLD, 25); gra.setFont(font); gra.drawString("点击【F2】重新开始游戏,【F4】退出游戏", (TankClient.WINDOW_WIDTH – this.winScreenImageWidth) / 2, 200); } g.drawImage(battleFieldImage, 0, 0, this); } }

Missile.java

import java.awt.*; import java.util.ArrayList; public class Missile implements Runnable { private static final int IMAGE_UP = 0; private static final int IMAGE_LEFT = 1; private static final int IMAGE_DOWN = 2; private static final int IMAGE_RIGHT = 3; private static final int MISSILE_WIDTH = 40; private static final int MISSILE_HEIGHT = 40; private static final int MISSILE_SPEED = 40; private double posX; private double posY; private boolean canBePaint; private ArrayList<Image> missileImages = new ArrayList<Image>(); private ArrayList<EnemyTank> enemyTanks = null; private ArrayList<Wall> walls = null; private MyTank myTank = null; private Image missileImage = null; private boolean isAlive;// 若子弹还没有消失,则为true;否则为false private Thread missileThread = new Thread(this); private MyTank.DirectionNow directionNow; public Missile(ArrayList<EnemyTank> enemyTanks, ArrayList<Wall> walls, MyTank myTank) { isAlive = false; canBePaint = true; this.myTank = myTank; this.enemyTanks = enemyTanks; this.walls = walls; missileImages.add(IMAGE_UP, Toolkit.getDefaultToolkit().getImage( "missile_up.gif")); missileImages.add(IMAGE_LEFT, Toolkit.getDefaultToolkit().getImage( "missile_left.gif")); missileImages.add(IMAGE_DOWN, Toolkit.getDefaultToolkit().getImage( "missile_down.gif")); missileImages.add(IMAGE_RIGHT, Toolkit.getDefaultToolkit().getImage( "missile_right.gif")); missileThread.start(); } public void run() { while (true) { if (isAlive) { move(); } try { missileThread.sleep(100); } catch (InterruptedException ie) { ie.printStackTrace(); } } } public void move() { // double tempPosX = this.posX;// 暂存移动前的位置的X坐标 // double tempPosY = this.posY;// 暂存移动前的位置的Y坐标 // canBePaint = false; switch (directionNow) { case LEFT: posX = posX – MISSILE_SPEED; break; case RIGHT: posX = posX + MISSILE_SPEED; break; case UP: posY = posY – MISSILE_SPEED; break; case DOWN: posY = posY + MISSILE_SPEED; break; default: break; } // 判断是否和墙壁碰撞 for (int i = 0; i < walls.size(); i++) { boolean collide; collide = collideWithSomething(walls.get(i)); if (collide) { isAlive = false; return; } } // 判断移动后是否出界 if (this.posX < 0) { isAlive = false; } if (this.posX >= (TankClient.WINDOW_WIDTH – MISSILE_WIDTH)) { isAlive = false; } if (this.posY < 0) { isAlive = false; } if (this.posY >= (TankClient.WINDOW_HEIGHT – MISSILE_HEIGHT)) { isAlive = false; } } public boolean collideWithSomething(Object something) {// 每次调用move()后,都要判断自己是否击中坦克或者墙壁了 // 返回true表示碰撞了,返回false表示没碰撞 int somethingWidth = 0, somethingHeight = 0; double somethingPosX = 0, somethingPosY = 0; if (something instanceof EnemyTank) { EnemyTank enemyTank = (EnemyTank) something; somethingWidth = enemyTank.getWidth(); somethingHeight = enemyTank.getHeight(); somethingPosX = enemyTank.getPosX(); somethingPosY = enemyTank.getPosY(); } if (something instanceof Wall) { Wall wall = (Wall) something; somethingWidth = wall.getWidth(); somethingHeight = wall.getHeight(); somethingPosX = wall.getPosX(); somethingPosY = wall.getPosY(); } if (something instanceof MyTank) { MyTank myTank = (MyTank) something; somethingWidth = myTank.getWidth(); somethingHeight = myTank.getHeight(); somethingPosX = myTank.getPosX(); somethingPosY = myTank.getPosY(); } switch (this.directionNow) { case LEFT: if ((this.posY + this.getHeight() <= somethingPosY) || (this.posY >= somethingPosY + somethingHeight)) { return false; } else if (this.posX + this.getWidth() <= somethingPosX) { return false; } else if (this.posX < somethingPosX + somethingWidth) { return true; } else { return false; } case RIGHT: if ((this.posY + this.getHeight() <= somethingPosY) || (this.posY >= somethingPosY + somethingHeight)) { return false; } else if (this.posX >= somethingPosX + somethingWidth) { return false; } else if (this.posX + this.getWidth() > somethingPosX) { return true; } else { return false; } case UP: if ((this.posX + this.getWidth() <= somethingPosX) || (this.posX >= somethingPosX + somethingWidth)) { return false; } else if (this.posY + this.getHeight() <= somethingPosY) { return false; } else if (this.posY < somethingPosY + somethingHeight) { return true; } else { return false; } case DOWN: if ((this.posX + this.getWidth() <= somethingPosX) || (this.posX >= somethingPosX + somethingWidth)) { return false; } else if (this.posY >= somethingPosY + somethingHeight) { return false; } else if (this.posY + this.getHeight() > somethingPosY) { return true; } else { return false; } default: return false; } } public void setDirectionNow(MyTank.DirectionNow directionNow) { this.directionNow = directionNow; switch (this.directionNow) { case UP: missileImage = missileImages.get(IMAGE_UP); break; case LEFT: missileImage = missileImages.get(IMAGE_LEFT); break; case DOWN: missileImage = missileImages.get(IMAGE_DOWN); break; case RIGHT: missileImage = missileImages.get(IMAGE_RIGHT); break; default: break; } } public MyTank.DirectionNow getDirectionNow() { return directionNow; } public void setPosX(double posX) { this.posX = posX; } public void setPosY(double posY) { this.posY = posY; } public double getPosX() { return posX; } public double getPosY() { return posY; } public boolean isAlive() { return isAlive; } public void setAlive(boolean isAlive) { this.isAlive = isAlive; } public int getHeight() { return this.MISSILE_HEIGHT; } public int getWidth() { return this.MISSILE_WIDTH; } public Thread getMissileThread() { return this.missileThread; } public Image getMissileImage() { return this.missileImage; } public void draw(Graphics g) { g.drawImage(missileImage, (int) posX, (int) posY, MISSILE_WIDTH, MISSILE_HEIGHT, null); } }

Wall.java

import java.awt.*; public class Wall { private final int WALL_WIDTH = 300;//墙的宽度 private final int WALL_HEIGHT = 60;//墙的高度 private int posX; private int posY; private Image wallImage = Toolkit.getDefaultToolkit().getImage("wall.jpg"); public Wall(){ posX = 100; posY = 100; } public Wall(int posX, int posY){ this.posX = posX; this.posY = posY; } public int getWidth(){ return WALL_WIDTH; } public int getHeight(){ return WALL_HEIGHT; } public int getPosX(){ return posX; } public int getPosY(){ return posY; } public void draw(Graphics g){ g.drawImage(wallImage, posX, posY, WALL_WIDTH, WALL_HEIGHT, null); } }

JAVA坦克大战TankBattle相关推荐

  1. java 坦克大战_java课程设计之坦克大战

    本文实例为大家分享了java坦克大战的具体代码,供大家参考,具体内容如下 环境要求: 操作系统:Windows 10 JAVA虚拟机:JDK1.8以上 开发环境:Eclipse(4.5以上) 功能提示 ...

  2. java坦克大战课设报告_java课程设计之坦克大战

    本文实例为大家分享了java坦克大战的具体代码,供大家参考,具体内容如下 环境要求: 操作系统:Windows 10 JAVA虚拟机:JDK1.8以上 开发环境:Eclipse(4.5以上) 功能提示 ...

  3. Java坦克大战游戏源码(java坦克大战)

    Java坦克大战游戏源码(java坦克大战) public Swingtest002() {// 设置标题setTitle("请登陆");// 绝对布局setLayout(null ...

  4. java坦克大战总体功能设计_Java坦克大战设计报告.doc

    Java坦克大战设计报告.doc <语言设计> 设计报告 信息工程学院专业班级:::指导老师:2011年7月22日 目录 目录2 题目一 坦克大战4 1.1题目简介4 1.2设计的内容.要 ...

  5. Java坦克大战,基于Swing编写很哇塞的小游戏,可以做课程设计毕业设计

    Java坦克大战,基于Swing编写很哇塞的小游戏,可以做课程设计毕业设计 有图有真相 操作方法:ASDW控制移动,鼠标控制炮筒旋转,鼠标左键开枪,空格发射炮弹, 开发思路是标准的游戏开发思路,单线程 ...

  6. Java坦克大战 (一) 之产生一个窗口

    本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...

  7. Java坦克大战(四)

    这是我的坦克游戏大战的最后一版,里面添加很多新的功能.这个坦克大战的有很多不足之处,但是对于初学者来说依然是一个很好的练习项目,从中我们可以学习Java基础知识,将知识与项目结合,学习面向对象编程思想 ...

  8. java 坦克大战画坦克_java简易坦克大战(2)

    public class Tank1 extends JFrame implements ActionListener { MyPanel mp = null; GuanKaPanel gkmb = ...

  9. java坦克大战(1.0)

    坦克大战 后面开始学习怎么使用java制造一个坦克大战游戏 但是不是直接开始做,而是随着这个游戏程序的制造,一边学习新知识融入到游戏中.包括多线程,反射,IO流- Java坐标体系 在几乎所有的坐标中 ...

最新文章

  1. 剑指offer 把数组排成最小的数 atoi和itoa,pow
  2. Spring Web Application Security
  3. vue项目设置img标签的默认图片
  4. 使用log4jdbc记录SQL信息
  5. Windows下有关信息收集的命令
  6. python远程调用摄像头_Python设置Socket代理及实现远程摄像头控制的例子
  7. 14寸笔记本电脑_华为笔记本电脑该如何选择?横向对比华为三款14寸笔记本
  8. 最常用标准库函数 (转)
  9. 互联网小团队创业 第三集 创业准备易犯的错误 汪华
  10. 时间序列分析思维导图
  11. 人口普查中应该具备的计算机知识,人口普查知识问答
  12. 空芯线圈电感计算公式
  13. 161128、Redis 4.0发布及其新功能介绍
  14. 进位位判别法_判断加减法溢出时,可采用判断进位的方式,如果符号位的进位为C...
  15. 身为程序员,与程序员有关的电影你看过几部? 一只猫
  16. oa项目经验描述_简历中项目经验模版
  17. Android获取桌面应用程序
  18. 第四届互联网+市赛后总结
  19. PHPstorm 函数时间注释的修改   正常的PHPstorm里面函数方法的注释是没有动态时间设置的,但是看了PHP file里面有时间日期的注释,而PHP Function Doc Commen
  20. py和ipynb文件互相转化

热门文章

  1. 全网最全Fiddler抓包教程,超过十万人学习此教程!
  2. 第二次作业——个人项目实战:数独
  3. 炫酷的进入页面的动画效果
  4. 大数据开发之运维面试题汇总分享
  5. 粉末喷涂机器人行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  6. 再见了!摩托罗拉:从独领风骚到一败涂地
  7. 2021年PMP退考的流程是怎样的?
  8. 当今世界最先进的外科手术机器人----达芬奇
  9. 数据库设计的六个基本步骤
  10. 如何使用域名访问到特定IP地址的服务器