标签:
好学而不勤问非真好学者。
本讲内容:坦克大战11.0版(面向对象的思想)
一、解决:播放声音
1、定义一个播放声音的类AePlayWave
2、在面板构造方法启动声音
二、同一个包下建二个文件分别为:MyTankGame、Members(负责其它成员譬如:制造坦克、子弹等)
MyTankGame类
/** * 功能:坦克游戏的8.0版本 1:画出坦克 * 2:实现我方坦克可以上下左右移动 * 3:可以發射子彈,子彈可以連發(最多可以发5颗) * 4:画出敌人的坦克 * 5:当我方坦克击中敌人坦克时,敌人的坦克就消失 * 6:消失时显示爆炸效果图 * 7:让敌人的坦克也可以自由随机的上下左右移动并在规定范围内移动。 * 8:让敌人坦克可以发射子弹 * 9:当敌人坦克打到我方会爆炸 * 10:防止敌人坦克重叠运动和我方坦克死亡(即隐身)后,该处被子弹击中不再发生爆炸 * 11:做一个空的Panel 主要用于提示 字体闪烁 * 12:做一个菜单栏,包括 开始新游戏(N)、退出游戏(E) * 13:画出提示坦克数量以及我一共打多少辆坦克 * 14:存盘退出游戏,可以记录当时的地敌人,并可以恢复 */ public class MyTankGame extends JFrame implements ActionListener { // 定义一个开始面板 MyStartPanel startmp = null; MyPanel mp = null; // 做出我需要的菜单 JMenuBar cd = null; JMenu cd1, cd2, cd3; JMenuItem ycd1, ycd2,ycd3,ycd4; public static void main(String[] args) { MyTankGame mtg = new MyTankGame(); } // 构造函数 public MyTankGame() { // 创建菜单以及菜单选项 cd = new JMenuBar(); cd1 = new JMenu("游戏"); cd2 = new JMenu("帮助"); cd3 = new JMenu("设置"); ycd1 = new JMenuItem("开始新游戏(N)"); ycd1.setMnemonic('N'); ycd2 = new JMenuItem("退出游戏(E)"); ycd2.setMnemonic('E'); ycd3 = new JMenuItem("存盘退出游戏(C)"); ycd3.setMnemonic('C'); ycd4 = new JMenuItem("继续上局游戏(S)"); ycd4.setMnemonic('S'); // 注册监听 ycd1.addActionListener(this); ycd1.setActionCommand("start"); ycd2.addActionListener(this); ycd2.setActionCommand("exit"); ycd3.addActionListener(this); ycd3.setActionCommand("saveExit"); ycd4.addActionListener(this); ycd4.setActionCommand("conGame"); cd1.add(ycd1); cd1.add(ycd2); cd1.add(ycd3); cd1.add(ycd4); cd.add(cd1); cd.add(cd2); cd.add(cd3); startmp = new MyStartPanel(); this.setJMenuBar(cd); this.add(startmp); // 启动startmp线程 Thread t = new Thread(startmp); t.start(); // 设置窗体属性 this.setTitle("坦克大战10.0版—小劲"); this.setLocation(300, 300); this.setSize(600, 500); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("start")) { mp = new MyPanel("newGame"); this.addKeyListener(mp);// 注册监听 // 启东mp线程 Thread t = new Thread(mp); t.start(); // 删掉旧的面板msp this.remove(startmp); this.add(mp); // 显示刷新JFrame this.setVisible(true); } else if (e.getActionCommand().equals("exit")) { //用户点击了退出系统的菜单 保存击毁敌人坦克数量 Recorder.keepRecording(); System.exit(0); } else if(e.getActionCommand().equals("saveExit")){ System.out.println("22"); //存盘退出保存敌人的数量和敌人的坐标 Recorder rd=new Recorder(); rd.setEts(mp.ets);//知道外面的世界 rd.keeprRecAndEnemyTank(); System.exit(0); }else if(e.getActionCommand().equals("conGame")){ mp = new MyPanel("con"); this.addKeyListener(mp);// 注册监听 // 启东mp线程 Thread t = new Thread(mp); t.start(); // 删掉旧的面板msp this.remove(startmp); this.add(mp); // 显示刷新JFrame this.setVisible(true); } } } // 提示的面板 class MyStartPanel extends JPanel implements Runnable { int times = 0; public void paint(Graphics g) { super.paint(g); g.fillRect(0, 0, 400, 300); // 提示信息 if (times % 2 == 0) { // 设置字体颜色 g.setColor(Color.yellow); // 设置字体 Font myFont = new Font("华文新魏", Font.BOLD, 50); g.setFont(myFont); g.drawString("stage: 1", 120, 150); } } public void run() { while (true) { try { Thread.sleep(400); } catch (Exception e) { e.printStackTrace(); } times++; // 重画 this.repaint(); } } } // 我的面板 class MyPanel extends JPanel implements KeyListener, Runnable { // 定义一个坦克 Tank tank = null; // 定义一个我的坦克 MyTank myTank = null; // 定义敌人的坦克 Vector<EnemyTank> ets = new Vector<EnemyTank>(); //恢复容器 Vector<Node> nodes=new Vector<Node>(); // 定义炸弹的集合 (在击中中创建然后在Panel画出) Vector<Bomb> bombs = new Vector<Bomb>(); int enSize = 6; // 定义三张爆炸需要的图片,组成一颗炸弹 Image image1 = null; Image image2 = null; Image image3 = null; // 构造函数 public MyPanel(String flag) { // 我的坦克 //恢复记录 Recorder.getRecoring(); myTank = new MyTank(150, 250); // 初始化敌人的坦克 if (flag.equals("newGame")) { for (int i = 0; i < enSize; i++) { // 创建一个敌人坦克 EnemyTank et = new EnemyTank((i + 1) * 50, 0); et.setColor(0); et.setDirect(2); // 将MyPanel的敌人的坦克容器交给该敌人的坦克 et.getEts(ets); // 启东敌人的坦克 Thread t = new Thread(et); t.start(); // 加入到面板中 ets.add(et); } } else { nodes=new Recorder().getNodesAndEnNums(); // 恢复敌人的坦克 for (int i = 0; i < nodes.size(); i++) { Node node=nodes.get(i); // 创建一个敌人坦克 EnemyTank et = new EnemyTank(node.x, node.y); et.setColor(0); et.setDirect(node.direct); // 将MyPanel的敌人的坦克容器交给该敌人的坦克 et.getEts(ets); // 启东敌人的坦克 Thread t = new Thread(et); t.start(); // 加入到面板中 ets.add(et); } } //播放开战声音 AePlayWave apw=new AePlayWave("./tank.wav"); apw.start(); // 初始化图片//ImageIO.read可以解决加载慢问题 try { image1 = ImageIO.read(new File("images/bzxg1.gif")); image2 = ImageIO.read(new File("images/bzxg2.gif")); image3 = ImageIO.read(new File("images/bzxg3.gif")); } catch (Exception e) { e.printStackTrace(); } } // 绘制提示信息 public void showInfo(Graphics g) { // 画出提示信息敌人的坦克 this.drawTank(80, 330, g, 0, 0); // 设置字体的颜色 g.setColor(Color.red); g.drawString(Recorder.getEnNum() + "", 110, 350);// +""转成string // 画出提示信息我的坦克记录信息 this.drawTank(130, 330, g, 0, 1); g.setColor(Color.black); g.drawString(Recorder.getMyLife() + "", 160, 350); // 画出玩家的总成绩提示信息 g.setColor(Color.black); // 设置字体的大小 Font f = new Font("宋体", Font.BOLD, 20); g.setFont(f); g.drawString("您的总成绩", 420, 30); // 画出玩家的总共摧毁敌人多少坦克的记录 this.drawTank(420, 60, g, 0, 0); g.setColor(Color.black); g.drawString(Recorder.getAllEnEum() + "", 460, 80); } public void paint(Graphics g) { super.paint(g); // 画出提示信息 this.showInfo(g); // 设置图像的背景色 g.fillRect(0, 0, 400, 300); // 畫出自己的坦克 if (myTank.isLive) { this.drawTank(myTank.getX(), myTank.getY(), g, myTank.direct, 1); } // 画出敌人的坦克 for (int i = 0; i < ets.size(); i++) { EnemyTank et = ets.get(i); if (et.isLive) { this.drawTank(ets.get(i).getX(), ets.get(i).getY(), g, ets.get( i).getDirect(), 0); // 画出敌人的子弹 for (int j = 0; j < et.ss.size(); j++) { // 取出子弹 Shot enemyShot = et.ss.get(j); if (enemyShot.isLive) { g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); } else { // 如果敌人的坦克死亡就从Vector中移除子弹 et.ss.remove(enemyShot); } } } } // 画出炸弹 for (int i = 0; i < bombs.size(); i++) { // 取出炸弹 Bomb b = bombs.get(i); if (b.life > 6) { g.drawImage(image1, b.x, b.y, 30, 30, this); // this表示就在当前面板上绘制 } else if (b.life > 4) { g.drawImage(image2, b.x, b.y, 30, 30, this); } else { g.drawImage(image3, b.x, b.y, 30, 30, this); } // 减小b的生命值 b.lifeDown(); // 如果炸弹的生命值为0,就把炸弹bombs去掉 if (b.life == 0) { bombs.remove(b); } } // 我的坦克从ss中取出每一颗子弹并画出 for (int i = 0; i < myTank.ss.size(); i++) { Shot myShot = myTank.ss.get(i); // 画子弹,畫出一顆子彈 if (myShot != null && myTank.s.isLive == true) { g.draw3DRect(myShot.x, myShot.y, 1, 1, false); } // 删除符合条件的子弹 if (myShot.isLive == false) { // 从ss中删掉该子弹 myTank.ss.remove(myShot);// 不要写i } } } // 判断我的子弹是否击中敌人的坦克 public void hitEnemyTank() { // 判断是否击中敌人的坦克 for (int i = 0; i < myTank.ss.size(); i++) { // 取出子弹 Shot myShot = myTank.ss.get(i); // 判断子弹是否有效 if (myShot.isLive) { // 取出每一个敌人的坦克与之匹配, for (int j = 0; j < ets.size(); j++) { // 取出坦克 EnemyTank et = ets.get(j); if (et.isLive) { if (this.hitTank(myShot, et)) {// 判断并执行 Recorder.reduceEnNum(); Recorder.addEnNumRec(); } } } } } } // 敌人的子弹是否击中我方 public void hitMe() { // 取出每一个敌人的坦克 for (int i = 0; i < this.ets.size(); i++) { // 取出坦克 EnemyTank et = ets.get(i); // 取出每一颗子弹 for (int j = 0; j < et.ss.size(); j++) { // 取出子弹 Shot enemyShot = et.ss.get(j); if (myTank.isLive) { if (this.hitTank(enemyShot, myTank)) { Recorder.reduceMyNum(); } } } } } // 写一个函数专门判断子弹对否击中敌人的坦克(考虑在什么地方调用函数?在Panel中run()) public boolean hitTank(Shot s, Tank et) { // 判断是否击中 boolean isShotTank = false; // 判断该坦克的方向 switch (et.direct) { // 如果敌人的坦克的方向是向上或者向下 case 0: case 2: if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) { // 击中 // 子弹死亡 s.isLive = false; // 敌人坦克死亡 et.isLive = false; // 创建一颗炸弹,放入到Vcetor Bomb b = new Bomb(et.x, et.y); // 放入到Vector bombs.add(b); isShotTank = true; } break; case 1: case 3: if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) { // 击中 // 子弹死亡 s.isLive = false; // 敌人坦克死亡 et.isLive = false; // 创建一颗炸弹,放入到Vcetor Bomb b = new Bomb(et.x, et.y); // 放入到Vector bombs.add(b); isShotTank = true; } break; } return isShotTank; } // 绘制坦克的函数 public void drawTank(int x, int y, Graphics g, int direct, int type) { switch (type) { case 0: g.setColor(Color.cyan); break; case 1: g.setColor(Color.yellow); break; } // 判断方向 switch (direct) { case 0: // 向上 // 画出我的坦克(到时候会封装成一个函数) // 1:绘制左边的矩形 g.fill3DRect(x, y, 5, 30, false); // 2:绘制右边的矩形 g.fill3DRect(x + 15, y, 5, 30, false); // 3:绘制中间矩形 g.fill3DRect(x + 5, y + 5, 10, 20, false); // 4:画出圆形 g.fillOval(x + 5, y + 10, 10, 10); // 5:绘制炮筒 g.drawLine(x + 10, y + 15, x + 10, y); break; case 1: // 向右 // 绘制上面的矩形 g.fill3DRect(x, y, 30, 5, false); // 绘制下面的矩形 g.fill3DRect(x, y + 15, 30, 5, false); // 绘制中间的矩形 g.fill3DRect(x + 5, y + 5, 20, 10, false); // 画出圆形 g.fillOval(x + 10, y + 5, 10, 10); // 绘制炮筒 g.drawLine(x + 15, y + 10, x + 30, y + 10); break; case 2: // 向下 // 1:绘制左边的矩形 g.fill3DRect(x, y, 5, 30, false); // 2:绘制右边的矩形 g.fill3DRect(x + 15, y, 5, 30, false); // 3:绘制中间矩形 g.fill3DRect(x + 5, y + 5, 10, 20, false); // 4:画出圆形 g.fillOval(x + 5, y + 10, 10, 10); // 5:绘制炮筒 g.drawLine(x + 10, y + 15, x + 10, y + 30); break; case 3: // 向左 // 绘制上面的矩形 g.fill3DRect(x, y, 30, 5, false); // 绘制下面的矩形 g.fill3DRect(x, y + 15, 30, 5, false); // 绘制中间的矩形 g.fill3DRect(x + 5, y + 5, 20, 10, false); // 画出圆形 g.fillOval(x + 10, y + 5, 10, 10); // 绘制炮筒 g.drawLine(x + 15, y + 10, x - 3, y + 10); break; } } // 键按下处理 a s w d public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_W) { // 向上 前进 this.myTank.setDirect(0); this.myTank.moveUp(); } else if (e.getKeyCode() == KeyEvent.VK_D) { // 向右前进 this.myTank.setDirect(1); this.myTank.moveRight(); } else if (e.getKeyCode() == KeyEvent.VK_S) { // 向下前进 this.myTank.setDirect(2); this.myTank.moveDown(); } else if (e.getKeyCode() == KeyEvent.VK_A) { // 向左前进 this.myTank.setDirect(3); this.myTank.moveLeft(); } if (e.getKeyCode() == KeyEvent.VK_J) {// 不用else if是為了防止走動時發不了子彈 // 判断玩家是否按下J键 開火 if (this.myTank.ss.size() < 5) {// 使最多发5颗子弹 this.myTank.shotEnemy(); } } // 重新绘制窗口 this.repaint(); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } public void run() { // 每隔100毫秒重新绘制子弹 while (true) { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } this.hitEnemyTank(); // 调用 判断敌人的子弹是否击中我的方法 this.hitMe(); // 重新绘制窗口 this.repaint(); } } }
//播放声音的类 class AePlayWave extends Thread { private String filename; public AePlayWave(String wavfile) { filename = wavfile; } public void run() { File soundFile = new File(filename); AudioInputStream audioInputStream = null; try { audioInputStream = AudioSystem.getAudioInputStream(soundFile); } catch (Exception e1) { e1.printStackTrace(); return; } AudioFormat format = audioInputStream.getFormat(); SourceDataLine auline = null; DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); try { auline = (SourceDataLine) AudioSystem.getLine(info); auline.open(format); } catch (Exception e) { e.printStackTrace(); return; } auline.start(); int nBytesRead = 0; // 这是缓冲 byte[] abData = new byte[512]; try { while (nBytesRead != -1) { nBytesRead = audioInputStream.read(abData, 0, abData.length); if (nBytesRead >= 0) auline.write(abData, 0, nBytesRead); } } catch (IOException e) { e.printStackTrace(); return; } finally { auline.drain(); auline.close(); } } } class Node { int x; int y; int direct; public Node(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } } // 记录类,同时可以保存玩家的设置 class Recorder { // 记录每关有多少敌人 private static int enNum = 20; // 设置我有多少可以用人 private static int myLife = 3; // 记录总共消灭了多少敌人的坦克 private static int allEnNum = 0; // 从文件恢复记录点 static Vector<Node> nodes = new Vector<Node>(); // 创建文件流,记录退出的信息导入到文件 private static FileWriter fw = null; private static BufferedWriter bw = null; private static FileReader fr = null; private static BufferedReader br = null; // 必须知道外面的世界 保存敌人的数量和敌人坦克坐标,方向 private static Vector<EnemyTank> ets = new Vector<EnemyTank>(); public static Vector<EnemyTank> getEts() { return ets; } public static void setEts(Vector<EnemyTank> ets) { Recorder.ets = ets; } // 把玩家击毁敌人坦克数量保存到文件中 public static void keepRecording() { try { fw = new FileWriter("e:/myRecording.txt"); bw = new BufferedWriter(fw); bw.write(allEnNum + "\r\n"); } catch (Exception e) { e.printStackTrace(); } finally { try { // 关闭流,先开的后关闭 bw.close(); fw.close(); } catch (Exception e2) { e2.printStackTrace(); } } } // 从文件中读取记录 public static void getRecoring() { try { fr = new FileReader("e:/myRecording.txt"); br = new BufferedReader(fr); String n = br.readLine(); allEnNum = Integer.parseInt(n);// string to int } catch (Exception e) { e.printStackTrace(); } finally { try { br.close(); fr.close(); } catch (Exception e2) { // TODO: handle exception } } } // 保存机会敌人的数量和敌人坦克坐标,方向 public static void keeprRecAndEnemyTank() { try { fw = new FileWriter("e:/myRecording.txt"); bw = new BufferedWriter(fw); bw.write(allEnNum + "\r\n"); // 保存当前还活着的敌人的坦克的坐标和方向(必须知道外面的世界) for (int i = 0; i < ets.size(); i++) { // 取出第一个坦克 EnemyTank et = ets.get(i); if (et.isLive) { // 活的就保存 String recode = et.x + " " + et.y + " " + et.direct; // 写入到文件中 bw.write(recode + "\r\n"); } } } catch (Exception e) { e.printStackTrace(); } finally { try { // 关闭流,先开的后关闭 bw.close(); fw.close(); } catch (Exception e2) { e2.printStackTrace(); } } } // 完成读取保存敌人的数量和敌人坦克坐标,方向 public Vector<Node> getNodesAndEnNums() { try { fr = new FileReader("e:/myRecording.txt"); br = new BufferedReader(fr); String n = ""; // 先读取第一行 n = br.readLine(); allEnNum = Integer.parseInt(n); while ((n = br.readLine()) != null) { String[] xyz = n.split(" ");// 以空格分隔字符串,得到字符串数组 Node node = new Node(Integer.parseInt(xyz[0]), Integer .parseInt(xyz[1]), Integer.parseInt(xyz[2])); nodes.add(node); } } catch (Exception e) { e.printStackTrace(); } finally { try { br.close(); fr.close(); } catch (Exception e2) { e2.printStackTrace(); } } return nodes; } public static int getAllEnEum() { return allEnNum; } public static void setAllEnEum(int allEnEum) { Recorder.allEnNum = allEnEum; } public static int getEnNum() { return enNum; } public static void setEnNum(int enNum) { Recorder.enNum = enNum; } public static int getMyLife() { return myLife; } public static void setMyLife(int myLife) { Recorder.myLife = myLife; } // 减少敌人生命的的数量 public static void reduceEnNum() { enNum--; } // 减少我的生命数量 public static void reduceMyNum() { myLife--; } // 当消灭敌人的时候我的战绩+1 public static void addEnNumRec() { allEnNum++; } } // 炸弹类 class Bomb {// 炸弹不会移动不用实现线程 // 定义炸弹的坐标 int x, y; // 炸弹的生命 int life = 9; boolean isLive = true; public Bomb(int x, int y) { this.x = x; this.y = y; } // 减少生命值 public void lifeDown() { if (life > 0) { life--; } else { this.isLive = false; } } } // 子弹类 class Shot implements Runnable {// 创建线程使子弹跑起来 //子弹在哪创建就在启动线程 int x; int y; int direct; int speed = 5; // 是否还活着 boolean isLive = true; public Shot(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; } public void run() { while (true) { try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } switch (direct) { case 0: // 子弹向上 y -= speed; break; case 1: x += speed; break; case 2: y += speed; break; case 3: x -= speed; break; } // System.out.println("子弹的坐标x="+x+"子弹的y坐标y="+y); // 子弹何时死亡 // 判断该子弹是否碰到边缘 if (x < 0 || x > 500 || y < 0 || y > 400) { this.isLive = false; break; } } } } // 定义一个坦克类 class Tank { // 表示坦克的横坐标x 和纵坐标y int x = 0; int y = 0; // 定义方向 0表示向上 1表示右, 2表示下 3表示左 int direct = 0; // 坦克颜色 int color = 0; // 坦克速度 int speed = 5; boolean isLive = true; public Tank(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } } // 敌人的坦克 class EnemyTank extends Tank implements Runnable { int times; // 子弹 Shot s = null; // 定义子弹容器使可以連發 Vector<Shot> ss = new Vector<Shot>(); // 定义一个容器,可以访问到MyPanel 上所有的坦克 Vector<EnemyTank> ets = new Vector<EnemyTank>(); public EnemyTank(int x, int y) { super(x, y); } // 得到MyPanel中的敌人的坦克容器(在哪调用) public void getEts(Vector<EnemyTank> ets) { this.ets = ets; } // 判断是否碰到了别的敌人的坦克 public boolean isTouchOtherEnemy() { boolean b = false; switch (this.direct) { case 0: // 我的坦克向上 // 取出所有的敌人的坦克 for (int i = 0; i < ets.size(); i++) { // 取出第一个坦克 EnemyTank et = ets.get(i); // 如果不是自己 if (et != this) { // 如果敌人的方向是向上或者向下 if (et.direct == 0 || et.direct == 2) { if (this.x >= et.x && this.x <= et.x + 20 && this.y >= y && this.y <= et.y + 30) { return true; } if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20 && this.y >= et.y && this.y <= et.y + 30) { return true; } } if (et.direct == 3 || et.direct == 1) { if (this.x >= et.x && this.x <= et.x + 20 && this.y >= y && this.y <= et.y + 20) { return true; } if (this.x + 20 >= et.x && this.x + 20 <= et.x + 30 && this.y >= et.y && this.y <= et.y + 20) { return true; } } } } break; case 1: // 我的坦克向右 // 取出所有的敌人的坦克 for (int i = 0; i < ets.size(); i++) { // 取出第一个坦克 EnemyTank et = ets.get(i); // 如果不是自己 if (et != this) { // 如果敌人的方向是向上或者向下 if (et.direct == 0 || et.direct == 2) { if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20 && this.y >= y && this.y <= et.y + 30) { return true; } if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20 && this.y + 20 >= et.y && this.y + 20 <= et.y + 30) { return true; } } if (et.direct == 3 || et.direct == 1) { if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20 && this.y >= y && this.y <= et.y + 20) { return true; } if (this.x + 30 >= et.x && this.x + 30 <= et.x + 30 && this.y + 20 >= et.y && this.y + 20 <= et.y + 20) { return true; } } } } break; case 2: // 我的坦克向下 // 取出所有的敌人的坦克 for (int i = 0; i < ets.size(); i++) { // 取出第一个坦克 EnemyTank et = ets.get(i); // 如果不是自己 if (et != this) { // 如果敌人的方向是向上或者向下 if (et.direct == 0 || et.direct == 2) { if (this.x >= et.x && this.x <= et.x + 20 && this.y + 30 >= y && this.y + 30 <= et.y + 30) { return true; } if (this.x + 20 >= et.x && this.x <= et.x + 20 && this.y + 30 >= et.y && this.y + 30 <= et.y + 30) { return true; } } if (et.direct == 3 || et.direct == 1) { if (this.x >= et.x && this.x <= et.x + 20 && this.y + 30 >= y && this.y + 30 <= et.y + 20) { return true; } if (this.x + 20 >= et.x && this.x + 20 <= et.x + 30 && this.y + 30 >= et.y && this.y + 30 <= et.y + 20) { return true; } } } } break; case 3: // 我的坦克向左 // 取出所有的敌人的坦克 for (int i = 0; i < ets.size(); i++) { // 取出第一个坦克 EnemyTank et = ets.get(i); // 如果不是自己 if (et != this) { // 如果敌人的方向是向上或者向下 if (et.direct == 0 || et.direct == 2) { // 我的上一点 if (this.x >= et.x && this.x <= et.x + 20 && this.y >= y && this.y <= et.y + 30) { return true; } // 我的下一点 if (this.x >= et.x && this.x <= et.x + 20 && this.y + 20 >= et.y && this.y + 20 <= et.y + 30) { return true; } } if (et.direct == 3 || et.direct == 1) { if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20 && this.y >= y && this.y <= et.y + 20) { return true; } if (this.x >= et.x && this.x <= et.x + 30 && this.y + 20 >= et.y && this.y + 20 <= et.y + 20) { return true; } } } } break; } return b; } public void run() { while (true) { switch (this.direct) { case 0:// 说明坦克正在向上移动 for (int i = 0; i < 30; i++) { if (y > 0 && !this.isTouchOtherEnemy()) {// 在规定范围行动 y -= speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } } break; case 1:// 说明坦克正在向右移动 for (int i = 0; i < 30; i++) { if (x < 440 && !this.isTouchOtherEnemy()) {// 注意坐标是左上边 x += speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } } break; case 2:// 说明坦克正在向下移动 for (int i = 0; i < 30; i++) { if (y < 340 && this.isTouchOtherEnemy()) { y += speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } } break; case 3:// 说明坦克正在向左移动 for (int i = 0; i < 30; i++) { if (x > 0 && !this.isTouchOtherEnemy()) { x -= speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } } break; } this.times++; // 判断是否需要给坦克加入新的子弹 if (times % 2 == 0) {// 使3秒添加一次(因为sleep1.5秒) if (isLive) { if (ss.size() < 5) { // 每辆每3秒添加子弹 switch (direct) { case 0: s = new Shot(x + 10, y, 0); ss.add(s); break; case 1: s = new Shot(x + 30, y + 10, 1); ss.add(s); break; case 2: s = new Shot(x + 10, y + 30, 2); ss.add(s); break; case 3: s = new Shot(x, y + 10, 3); ss.add(s); break; } // 启动子弹 Thread t = new Thread(s); t.start(); } } } // 让坦克随机产生一个新的方向 this.direct = (int) (Math.random() * 4); // 判断敌人的坦克是否死亡 if (this.isLive == false) { // 让坦克死亡后推出线程 break; } } } } // 我的坦克 class MyTank extends Tank { // 子弹 Shot s = null; // 定义子弹容器使可以連發 Vector<Shot> ss = new Vector<Shot>(); public MyTank(int x, int y) { super(x, y); } // 开火 public void shotEnemy() {// 子弹在哪创建就在启动线程 switch (this.direct) { case 0: // 創建一顆子彈 s = new Shot(x + 10, y, 0); ss.add(s);// 放入子弹容器 然后在JPanel畫出來 break; case 1: s = new Shot(x + 30, y + 10, 1); ss.add(s); break; case 2: s = new Shot(x + 10, y + 30, 2); ss.add(s); break; case 3: s = new Shot(x, y + 10, 3); ss.add(s); break; } // 创建线程并启动 Thread t = new Thread(s); t.start(); } // 坦克向上移动 public void moveUp() { y -= speed; } // 坦克向右移动 public void moveRight() { x += speed; } // 向下移动 public void moveDown() { y += speed; } // 向左边移动 public void moveLeft() { x -= speed; } }
标签:
原文地址:http://blog.csdn.net/liguojin1230/article/details/42592377