HTML文件代码,那是笔者的坦克游戏大战的末尾1版

HTML5坦克战役(韩顺平版本)

 2017-3-22
22:46:22 by SemiconductorKING

 

  年暑假学习了一下HTML5落实简单的坦克战役,感到对JavaScript初学者的话,演习那几个小游戏代码段能够学到诸多东西,包蕴canvas的差不离利用,类的协会,类的存续等等。编写三个一体化的十五日游要有较强的逻辑性,那么些demo的学习摄像以及demo文件下载见小编分享的链接:

   链接:http://pan.baidu.com/s/1boAzSir
密码:mcp2

 

   demo截图:

图片 1

 

  此demo只是三个粗略的演练,效果low不low先不提,看代码吧:

 

  HTML文件代码:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4 <meta charset='utf-8'/>
  5 <script src='tank.js'></script>
  6 </head>
  7 <body onkeydown="changeDirect()">
  8 <h1 style="color: #0714b9;">html5坦克大战</h1>
  9 <div style="margin: 30px">
 10     <canvas id='tankMap' width='500px' height='300px' style='background-color:#3e0549;'>
 11         你的浏览器不支持canvas标签 ||||| You are seeing this message because your web browser does not support the canvas tag.
 12     </canvas>
 13 </div>
 14 <div id='add1'></div>
 15 <div id='add2'></div>
 16 <div id='add3'></div>
 17 <div style="margin: 30px;font-size: 12px">
 18     <p>控制方法:按下键盘w s a d或者↑ ↓ ← →分别是坦克的上下左右行驶<br/>按下j或者Enter键为射击</p>
 19 </div>
 20 </body>
 21 <script>
 22     var canvas = document.getElementById('tankMap');
 23     //获得画笔
 24     var ctx = canvas.getContext('2d');
 25 
 26     //定义炸弹数组
 27     var bombs = new Array();
 28 
 29     //构造英雄
 30     var hero = new Hero(380,260,0,heroColor);
 31 
 32     //创建敌人数组
 33     var enemyTanks = new Array();
 34 
 35     //创建敌人的子弹数组
 36     var enemyBullets = new Array();
 37     for(var i=0;i<6;i++){
 38         var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor);
 39         enemyTanks[i] = enemyTank;
 40         //drawTank(enemyTanks[i]);
 41         //让敌人的坦克动起来
 42         var timer = window.setInterval("enemyTanks["+i+"].run()",50);
 43         enemyTanks[i].timer = timer;
 44         //让敌人发射子弹
 45         var enemyBullet = new Bullet(enemyTanks[i].x+9,enemyTanks[i].y+30,enemyTanks[i].direct,enemyTanks[i],'enemy');
 46         enemyBullets.push(enemyBullet);
 47         enemyBullets[i].timer = window.setInterval("enemyBullets["+i+"].run()",50);
 48     }
 49 
 50     //定义英雄子弹数组
 51     var heroBullets = new Array();
 52     var heroBullet = null;
 53     
 54     if(hero.isLive){
 55             drawTank(hero);
 56         }
 57 
 58     //flashMap();
 59     //重置画布
 60     function flashMap(){
 61         ctx.clearRect(0,0,500,300);
 62         isHitHeroTank(enemyBullets,hero);
 63         if(hero.isLive){
 64             drawTank(hero);
 65         }
 66         
 67         isHitEnemyTank(heroBullets,enemyTanks);
 68         //画出自己坦克的子弹
 69         drawHeroBullet(heroBullets);
 70         //画出敌人坦克的子弹
 71         drawEnemyBullet(enemyBullets,enemyTanks);
 72         for(var i=0;i<6;i++){
 73             if(enemyTanks[i].isLive){
 74                 drawTank(enemyTanks[i]);
 75             }
 76         }
 77 
 78         //画出爆炸图片
 79         for(var k=0;k<bombs.length;k++){
 80             var img = new Image();
 81             img.src = 'bomb_1.gif';
 82             var x = bombs[k].x;
 83             var y = bombs[k].y;
 84             ctx.drawImage(img,x,y,30,30);
 85             ctx.drawImage(img,x,y,40,35);
 86             ctx.drawImage(img,x,y,35,40);
 87             bombs.splice(k,1);
 88         }
 89     }
 90 
 91     function changeDirect(){
 92         var keycode = event.keyCode;
 93         switch(keycode){
 94             case 38:;
 95             case 87:hero.moveUp();break;
 96             case 39:;
 97             case 68:hero.moveRight();break;
 98             case 40:;
 99             case 83:hero.moveBottom();break;
100             case 37:;
101             case 65:hero.moveLeft();break;
102             case 74:;
103             case 13:hero.shotEnemy();break;
104         }
105         flashMap();
106     }
107     window.setInterval("flashMap()",50);
108 </script>
109 </html>

 

  tank.js代码:

  1 //定义敌人和我们自己的坦克的颜色
  2 var enemyColor = new Array("#0BB","#0FF");
  3 var heroColor = new Array("#dc0","#ff5");
  4 //封装一个公用的坦克父类
  5 function Tank(x,y,direct){
  6     this.x = x;
  7     this.y = y;
  8     this.speed = 3;
  9     this.direct = direct;
 10     this.moveUp = function(){
 11         if (hero.y>0) {
 12             hero.y -= hero.speed;
 13         }
 14         hero.direct = 0;
 15     }
 16     this.moveRight = function(){
 17         if (hero.x+30<500) {
 18             hero.x += hero.speed;
 19         }
 20         hero.direct = 1;
 21     }
 22     this.moveBottom = function(){
 23         if (hero.y+30<300) {
 24             hero.y += hero.speed;
 25         }
 26         hero.direct = 2;
 27     }
 28     this.moveLeft = function(){
 29         if (hero.x>0) {
 30             hero.x -= hero.speed;
 31         }
 32         hero.direct = 3;
 33     }
 34 }
 35 
 36 //英雄坦克类
 37 function Hero(x,y,direct,color){
 38     //将坦克类的构造方法赋给hero
 39     this.hero = Tank;
 40     //调用,拥有坦克类的所有的属性和方法
 41     this.hero(x,y,direct);
 42     this.color = color;
 43     this.direct = direct;
 44     this.isLive = true;
 45     this.shotEnemy = function(){
 46         switch(this.direct){
 47             case 0:
 48                 heroBullet = new Bullet(this.x+9,this.y,this.direct);
 49             break;
 50             case 1:
 51                 heroBullet = new Bullet(this.x+30,this.y+9,this.direct);
 52             break;
 53             case 2:
 54                 heroBullet = new Bullet(this.x+9,this.y+30,this.direct);
 55             break;
 56             case 3:
 57                 heroBullet = new Bullet(this.x,this.y+9,this.direct);
 58             break;
 59         }
 60         heroBullets.push(heroBullet);
 61         heroBullets[heroBullets.length-1].timer = window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);
 62     }
 63 }
 64 //敌人的坦克
 65 function EnemyTank(x,y,direct,color){
 66     //将坦克类的构造方法赋给敌人坦克
 67     this.enemyTank = Tank;
 68     //调用,拥有坦克类的所有的属性和方法
 69     this.enemyTank(x,y,direct);
 70     this.color = color;
 71     this.isLive = true;
 72     this.timer = null;
 73     this.speed = 1;
 74     this.count = 0;
 75     this.direct = direct;
 76     this.bulletIsLive = true;
 77     this.run = function(){
 78         switch(this.direct){
 79             case 0:
 80                 if(this.y>0){
 81                 this.y--;
 82             }
 83             break;
 84             case 1:
 85                 if(this.x+30<500){
 86                 this.x += this.speed;
 87             }
 88             break;
 89             case 2:
 90                 if(this.y+30<300){
 91                 this.y += this.speed;
 92             }
 93             break;
 94             case 3:
 95                 if(this.x>0){
 96                 this.x -= this.speed;
 97             }
 98             break;
 99         }
100         
101         if(this.count>=30){
102             this.direct = Math.round(Math.random()*3);
103             this.count=0;
104         }
105         this.count++;
106         //在坦克走的过程中,判断一下,这个坦克的子弹是否活着
107         if(this.bulletIsLive == false && this.isLive){
108             //子弹over,加子弹
109             switch(this.direct){
110                 case 0:
111                     enemyBullets.push(new Bullet(this.x+9,this.y,this.direct,this,'enemy'));
112                 break;
113                 case 1:
114                     enemyBullets.push(new Bullet(this.x+30,this.y+9,this.direct,this,'enemy'));
115                 break;
116                 case 2:
117                     enemyBullets.push(new Bullet(this.x+9,this.y+30,this.direct,this,'enemy'));
118                 break;
119                 case 3:
120                     enemyBullets.push(new Bullet(this.x,this.y+9,this.direct,this,'enemy'));
121                 break;
122             }
123             enemyBullets[enemyBullets.length-1].timer = window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);
124                 this.bulletIsLive = true;
125         }
126     }
127 }
128 //绘制坦克
129     function drawTank(hero){
130     switch(hero.direct){
131         case 0:
132         case 2:
133             ctx.fillStyle = hero.color[0];
134             ctx.fillRect(hero.x,hero.y,5,30);
135             ctx.fillRect(hero.x+15,hero.y,5,30);
136             ctx.fillRect(hero.x+6,hero.y+5,8,20);
137             ctx.fillStyle = hero.color[1];
138             ctx.beginPath();
139             ctx.arc(hero.x+10,hero.y+15,3,0,Math.PI*2,true);
140             ctx.closePath();
141             ctx.fill();
142             //画出炮筒(直线)
143             ctx.strokeStyle = hero.color[1];
144             ctx.lineWidth = 2;
145             ctx.moveTo(hero.x+10,hero.y+15);
146             if(hero.direct==0){
147                 ctx.lineTo(hero.x+10,hero.y);
148             }else if(hero.direct==2){
149                 ctx.lineTo(hero.x+10,hero.y+30);
150             }
151             ctx.stroke();
152         break;
153         case 1:
154         case 3:
155             ctx.fillStyle = hero.color[0];
156             ctx.fillRect(hero.x,hero.y,30,5);
157             ctx.fillRect(hero.x,hero.y+15,30,5);
158             ctx.fillRect(hero.x+5,hero.y+6,20,8);
159             //需要注意,画圆的时候需要重新开启路径
160             ctx.fillStyle = hero.color[1];
161             ctx.beginPath();
162             ctx.arc(hero.x+15,hero.y+10,3,0,Math.PI*2,true);
163             ctx.closePath();
164             ctx.fill();
165             //画出炮筒(直线)
166             ctx.strokeStyle = hero.color[1];
167             ctx.lineWidth = 2;
168             ctx.moveTo(hero.x+15,hero.y+10);
169             if(hero.direct ==1){
170                 ctx.lineTo(hero.x+30,hero.y+10);
171             }else if(hero.direct ==3){
172                 ctx.lineTo(hero.x,hero.y+10);
173             }
174             ctx.stroke();
175         break;
176     }
177 }
178 
179 //定义一个子弹类
180 function Bullet(x,y,direct,tank,type){
181     this.x = x;
182     this.y = y;
183     this.speed = 3;
184     this.direct = direct;
185     this.timer = null;
186     this.isLive = true;
187     this.tank = tank;
188     this.type = type;
189     this.run = function(){
190         switch(this.direct){
191             case 0:
192                 this.y -= this.speed;
193             break;
194             case 1:
195                 this.x += this.speed;
196             break;
197             case 2:
198                 this.y += this.speed;
199             break;
200             case 3:
201                 this.x -= this.speed;
202             break;
203         }
204         document.getElementById('add1').innerText = " 子弹x轴:"+this.x+" 子弹y轴:"+this.y;
205         document.getElementById('add2').innerText = " 坦克x轴:"+hero.x+" 坦克y轴:"+hero.y;
206         document.getElementById('add3').innerText = " hero子弹数量:"+heroBullets.length;
207         if(this.x <0 || this.x>=500 ||this.y<0 || this.y>300 || this.isLive==false){
208             this.isLive = false;
209             if(this.type=='enemy'){
210                 this.tank.bulletIsLive = false;
211             }
212             window.clearInterval(this.timer);
213         }
214     }
215 }
216 function drawHeroBullet(bullets){
217     for(var i=0;i<bullets.length;i++){
218         var heroBullet = bullets[i];
219         if(heroBullet.isLive){
220             ctx.fillStyle = '#FEF26E';
221             ctx.fillRect(heroBullet.x,heroBullet.y,2,2);
222         }
223     }
224 }
225 //画出敌人坦克的子弹
226 function drawEnemyBullet(enemyBullets){
227     for(var i=0;i<enemyBullets.length;i++){
228         var enemyBullet = enemyBullets[i];
229         if(enemyBullet.isLive){
230             ctx.fillRect(enemyBullet.x,enemyBullet.y,2,2);
231         }
232     }
233 }
234 function isHitEnemyTank(heroBullets,enemyTanks){
235     for(var i=0;i<heroBullets.length;i++){
236         for(var j=0;j<enemyTanks.length;j++){
237             //判断一下自己的子弹和敌人的坦克坐标
238             if(enemyTanks[j].isLive){
239                 switch(enemyTanks[j].direct){
240                 case 0:
241                 case 2:
242                     if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+20&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+30){
243                         //标记敌人的坦克和我们的子弹已经死掉了
244                         heroBullets[i].isLive = false;
245                         enemyTanks[j].isLive = false;
246                         var bomb = new Bomb(enemyTanks[j].x,enemyTanks[j].y);
247                         bombs.push(bomb);
248 
249                 }
250                 break;
251                 case 1:
252                 case 3:
253                     if(heroBullets[i].x>=enemyTanks[j].x&&heroBullets[i].x<=enemyTanks[j].x+30&&heroBullets[i].y>=enemyTanks[j].y&&heroBullets[i].y<=enemyTanks[j].y+20){
254                         //标记敌人的坦克和我们的子弹已经死掉了
255                         heroBullets[i].isLive = false;
256                         enemyTanks[j].isLive = false;
257                         var bomb = new Bomb(enemyTanks[j].x,enemyTanks[j].y);
258                         bombs.push(bomb);
259                 }
260                 break;
261             }
262             }
263             
264         }
265     }
266 }
267 
268 //定义炸弹类
269 function Bomb(x,y){
270     this.x = x;
271     this.y = y;
272 }
273 
274 //判断敌人的子弹是否击中自己的坦克
275 function isHitHeroTank(enemyBullets,heroTank){
276     for(var i=0;i<enemyBullets.length;i++){
277         if(enemyBullets[i].isLive && heroTank.isLive){
278             switch(heroTank.direct){
279             case 0:
280             case 2:
281                 if(enemyBullets[i].x >= heroTank.x && enemyBullets[i].x <= heroTank.x+20 && enemyBullets[i].y >= heroTank.y && enemyBullets[i].y <= heroTank.y +30){
282                 heroTank.isLive = false;
283                 enemyBullets[i].isLive = false;
284             }
285             break;
286             case 1:
287             case 3:
288                 if(enemyBullets[i].x >= heroTank.x && enemyBullets[i].x <= heroTank.x+30 && enemyBullets[i].y >= heroTank.y && enemyBullets[i].y <= heroTank.y +20){
289                 heroTank.isLive = false;
290                 enemyBullets[i].isLive = false;
291             }
292             break;
293         }
294         }
295     }
296 }

end…

Java坦克大战(四),java坦克大战

那是本人的坦克游戏战役的最后1版,里面增加大多新的法力。这些坦克战役的有众多不足之处,不过对于初学者的话依然是一个很好的演练项目,从中大家得以学学Java基础知识,将文化与品类结合,学习面向对象编制程序思想,最要害的是编制程序的逻辑练习,代码往往不像是写文章从上到下一气浑成落成,中间很恐怕为扩大3个效率来增多三个类2个办法等,中间有不少细节需求大家着想。小说最后会附加该坦克战争涉及的有关质感。

功能:

一.防御坦克重叠

2.得以分关(闪烁效果)

三.记下成绩(小型游戏都是写在文件中)

四.存盘退出,能够记下可是敌人坦克的坐标

5.得以还原上局,继续玩

陆.坦克的鸣响

坦克战斗最终版本(二.一)

MyTanKGame类:

/*
 * 功能:
 * 1.防止坦克重叠
 * 2.可以分关(闪烁效果)
 * 3.记录成绩(小型游戏都是写在文件中)
 * 4.存盘退出,可以记录但是敌人坦克的坐标
 * 5.可以恢复上局,继续玩
 * 6.坦克的声音
 */
package com.fanghua6;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Vector;
import javax.swing.*;

public class MyTankGame1_7 extends JFrame implements ActionListener {

    Mypanel1_2 mp = null;

    // 定义开始面板
    MyStartPanel msp = null;
    // 做出菜单
    JMenuBar jmb = null;
    // 开始游戏
    JMenu jm1 = null;
    JMenuItem jmi1 = null;
    // 退出游戏
    JMenuItem jmi2 = null;
    // 存盘退出
    JMenuItem jmi3 = null;
    JMenuItem jmi4 = null;

    public static void main(String[] args) {
        new MyTankGame1_7();
    }

    // 构造函数
    public MyTankGame1_7() {
        // mp = new Mypanel1_2();

        // 启动mp线程
        // Thread t = new Thread(mp);
        // t.start();

        // this.add(mp);
        // 注册监听
        // this.addKeyListener(mp);
        // 创建菜单及菜单选项
        jmb = new JMenuBar();
        jm1 = new JMenu("游戏(G)");
        jm1.setMnemonic('G');
        jmi1 = new JMenuItem("开始新游戏(N)");
        jmi1.setMnemonic('N');

        jmi2 = new JMenuItem("退出游戏(E)");
        jmi2.setMnemonic('E');

        jmi3 = new JMenuItem("存盘退出(C)");
        jmi3.setMnemonic('C');

        jmi4 = new JMenuItem("继续上局(S)");
        jmi4.setMnemonic('S');

        // jmi1相应
        jmi1.addActionListener(this);
        jmi1.setActionCommand("newgame");
        jmi2.addActionListener(this);
        jmi2.setActionCommand("exit");
        jmi3.addActionListener(this);
        jmi3.setActionCommand("saveExit");
        jmi4.addActionListener(this);
        jmi4.setActionCommand("conGame");

        jm1.add(jmi1);
        jm1.add(jmi2);
        jm1.add(jmi3);
        jm1.add(jmi4);

        jmb.add(jm1);

        // 加了开始面板(上面的全注释掉)
        msp = new MyStartPanel();
        this.add(msp);
        // 启动msp面板
        Thread t = new Thread(msp);
        t.start();

        this.setJMenuBar(jmb);

        this.setSize(600, 500);
        this.setTitle("我的坦克大战");
        ImageIcon icon = new ImageIcon("images\\tanke.png");
        this.setIconImage(icon.getImage());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        // 对用户不同的点击做出不同的处理
        if (e.getActionCommand().equals("newgame")) {

            // 创建战场面板
            mp = new Mypanel1_2("newGame");
            // 启动mp线程
            Thread t = new Thread(mp);
            t.start();
            // 先把msp删掉,再加mp
            this.remove(msp);
            this.add(mp);
            // 注册监听
            this.addKeyListener(mp);
            // 显示,刷新JFrame(这个很重要)
            this.setVisible(true);
        } else if (e.getActionCommand().equals("exit")) {

            // 用户退出系统的菜单(保存击毁敌人数量)
            Recorder.keepRecording();

            System.exit(0);
        }// 对存盘退出的处理
        else if (e.getActionCommand().equals("saveExit")) {

            /*
             * 当时这里这样处理的,大错特错。new两次 工作 new Recorder().setEts(mp.ets);new
             * 保存击毁敌人的数量和敌人的坐标 Recorder().keepRecAndEnemyTank();
             */

            // 工作
            Recorder rd = new Recorder();
            rd.setEts(mp.ets);
            // 保存击毁敌人的数量和敌人的坐标
            rd.keepRecAndEnemyTank();

            // 退出
            System.exit(0);
        } else if (e.getActionCommand().equals("conGame")) {
            // 继续游戏
            // 创建战场面板
            mp = new Mypanel1_2("con");

            // 不在这:mp.nodes = new Recorder().getNodesAndEnNums();
            // 启动mp线程
            Thread t = new Thread(mp);
            t.start();
            // 先把msp删掉,再加mp
            this.remove(msp);
            this.add(mp);
            // 注册监听
            this.addKeyListener(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, 30);
            g.setFont(myFont);// 别忘了
            g.drawString("stage: 1", 140, 200);
        }
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            // 休眠
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            times++;
            // 重画
            this.repaint();
        }
    }

}

// 我的面板,拓宽思路:Panel本身就是一个刷新体
class Mypanel1_2 extends JPanel implements java.awt.event.KeyListener, Runnable {

    // 定义我的坦克
    Hero1_2 hero = null;

    // 判断是续上局,还是新游戏

    // 定义敌人的坦克(不止一辆,线程安全,集合)
    Vector<EnemyTank> ets = new Vector<EnemyTank>();
    Vector<Node> nodes = new Vector<Node>();

    // 定义炸弹集合
    Vector<Bomb> bombs = new Vector<Bomb>();

    int enSize = 4;// 敌人坦克保持4个

    // 定义三张图片(三张图片才能组成一颗炸弹)
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    // 构造函数(续局,变成含参的构造函数)
    public Mypanel1_2(String flag) {

        // 恢复记录(写在这里)
        Recorder.getRecoring();

        hero = new Hero1_2(70, 100);

        if (flag.equals("newGame")) {
            // 初始化敌人的坦克
            for (int i = 0; i < enSize; i++) {
                // 创建一辆敌人的坦克
                EnemyTank et = new EnemyTank((i + 1) * 50, 0);
                et.setColor(0);
                // 坦克默认反向是0(向上),这里改一下
                et.setDirect(2);

                // 将MyPanel的敌人坦克向量交给该敌人坦克
                et.setEts(ets);

                // 启动敌人的坦克
                Thread t = new Thread(et);
                t.start();
                // 给敌人坦克添加一颗子弹
                Shot s = new Shot(et.x + 10, et.y + 30, 2);
                // 加入给敌人的坦克
                et.ss.add(s);

                Thread t2 = new Thread(s);
                t2.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.setEts(ets);

                // 启动敌人的坦克
                Thread t = new Thread(et);
                t.start();
                // 给敌人坦克添加一颗子弹
                Shot s = new Shot(et.x + 10, et.y + 30, 2);
                // 加入给敌人的坦克
                et.ss.add(s);

                Thread t2 = new Thread(s);
                t2.start();
                ets.add(et);
            }
        }
        // 初始话图片,这样做击中第一个坦克,爆炸的效果不明显。下面优化
        image1 = Toolkit.getDefaultToolkit().getImage(
                Panel.class.getResource("/bomb_1.gif"));
        image2 = Toolkit.getDefaultToolkit().getImage(
                Panel.class.getResource("/bomb_2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(
                Panel.class.getResource("/bomb_3.gif"));

        // 引包:import javax.imageio.ImagesssIO;
        // try {
        // image1=ImageIO.read(new File("/bomsb_1.gif"));
        // image2=ImageIO.read(new File("/bomb_2.gif"));
        // image3=ImageIO.read(new File("/bomb_3.gif"));
        // } catch (IOException e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }

        // 在Mypanel1_2初始化里,放置开战音效,加载即播放
        // 以后再添加爆炸效果的声音也是这样做的思路
        AePlayWave apw = new AePlayWave("E:\\111.wav");
        apw.start();

    }

    // 提示信息(只需要画笔即可)
    public void showInfo(Graphics g) {
        // 画出提示信息坦克
        this.drawTank(70, 310, g, 0, 0);
        g.setColor(Color.black);
        g.drawString(Recorder.getEnNum() + "", 100, 330);

        this.drawTank(70, 360, g, 0, 1);
        g.setColor(Color.black);
        g.drawString(Recorder.getMyLife() + "", 100, 380);

        // 画出玩家的总成绩
        g.setColor(Color.black);
        Font f = new Font("宋体", Font.BOLD, 20);
        g.setFont(f);
        g.drawString("你的总成绩", 410, 30);
        this.drawTank(410, 60, g, 0, 0);

        g.setColor(Color.black);
        g.drawString(Recorder.getAllEnNum() + "", 440, 80);
    }

    // 重写paint函数
    public void paint(Graphics g) {
        // 一定要调用
        super.paint(g);
        g.fillRect(0, 0, 400, 300);
        // 画出提示信息
        this.showInfo(g);

        // 画出自己的坦克(将方向填进去)
        if (hero.isLive == true) {
            this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
        }
        // 从ss中取出每一颗子弹,并画出
        for (int i = 0; i < hero.ss.size(); i++) {

            Shot myShot = hero.ss.get(i);
            if (myShot != null && myShot.isLive == true) {
                g.draw3DRect(myShot.x, myShot.y, 1, 1, false);

                /*
                 * 画出一颗子弹(后添加 hero.s.isLive==true,节省资源) if (hero.s != null
                 * &&hero.s.isLive == true) { g.draw3DRect(hero.s.x, hero.s.y,
                 * 1, 1,false); }
                 */
            }
            if (myShot.isLive == false) {
                // 从ss(向量)中删除该子弹
                // hero.ss.remove(i);会报异常。
                hero.ss.remove(myShot);
            }
        }

        // 画出炸弹
        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);
            } 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();
            // 如果炸弹生命值为零,就把该炸弹从bombs向量中去掉
            if (b.life == 0) {
                bombs.remove(b);
            }

        }

        // 画出敌人的坦克
        for (int i = 0; i < ets.size(); i++) {
            EnemyTank et = ets.get(i);
            if (et.isLive) {
                this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 0);

                // 画出敌人的子弹
                for (int j = 0; j < et.ss.size(); j++) {
                    // 取出子弹
                    Shot enemyShot = et.ss.get(j);
                    if (enemyShot != null && enemyShot.isLive == true) {
                        g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
                    }
                    if (enemyShot.isLive == false) {
                        // 如果敌人的坦克死亡了,就从Vector中删除
                        et.ss.remove(enemyShot);
                    }
                }
            }
        }
    }

    // 敌人的坦克是否击中我
    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 (hero.isLive) {
                    if (this.hitTank(enemyShot, hero)) {

                    }
                }
            }
        }
    }

    // 判断我的子弹是否击中敌人的坦克
    public void hitEnemyTank() {
        // 判断是否击中敌人的坦克
        for (int i = 0; i < hero.ss.size(); i++) {
            // 取出子弹
            Shot myShot = hero.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();
                        }
                    }

                }
            }
        }
    }

    // 写一个函数 专门判断是否击中敌人坦克(原来第二参数: EnemyTank et)
    // void改成boolean 判断击中的目标是谁

    public boolean hitTank(Shot s, Tank1_2 et) {
        boolean b2 = 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;
                b2 = true;
                // 创建一颗炸弹,放入Vector
                Bomb b = new Bomb(et.x, et.y);
                // 放入Vector
                bombs.add(b);

            }

            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;
                b2 = true;
                // 创建一颗炸弹,放入Vector
                Bomb b = new Bomb(et.x, et.y);
                // 放入Vector
                bombs.add(b);

            }
            break;
        }

        return b2;

    }

    // 画出坦克的函数
    public void drawTank(int x, int y, Graphics g, int direct, int type) {
        // 坦克类型
        switch (type) {
        case 0:
            g.setColor(Color.green);
            break;
        case 1:
            g.setColor(Color.yellow);
            break;
        }
        // 方向设置
        switch (direct) {
        // 向上
        case 0:
            g.fill3DRect(x, y, 5, 30, false);
            g.fill3DRect(x + 15, y, 5, 30, false);
            g.fill3DRect(x + 5, y + 5, 10, 20, false);
            g.fillOval(x + 5, y + 10, 10, 10);
            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:
            g.fill3DRect(x, y, 5, 30, false);
            g.fill3DRect(x + 15, y, 5, 30, false);
            g.fill3DRect(x + 5, y + 5, 10, 20, false);
            g.fillOval(x + 5, y + 10, 10, 10);
            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, y + 10);
            break;
        }

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        // 已更正为顺时针
        if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
            this.hero.moveUp();
            this.hero.setDirect(0);
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT
                || e.getKeyCode() == KeyEvent.VK_D) {
            this.hero.setDirect(1);
            this.hero.moveRight();
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN
                || e.getKeyCode() == KeyEvent.VK_S) {
            this.hero.moveDown();
            this.hero.setDirect(2);
        } else if (e.getKeyCode() == KeyEvent.VK_LEFT
                || e.getKeyCode() == KeyEvent.VK_A) {
            this.hero.moveLeft();
            this.hero.setDirect(3);
        } else if (e.getKeyCode() == KeyEvent.VK_J) {
            // 将J键设置为发出子弹
            // 子弹连发,J被按几下,发几颗:this.hero.shotEnemy();
            // this.repaint();在run函数里,不应该设计在这里
            if (this.hero.ss.size() <= 4) {
                this.hero.shotEnemy();
            }
        }
        // 必须重新绘制Panel
        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        // 每隔100毫秒去重绘
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            // 谨记这里:由于这里多写了这些,线程每次都被重新调用
            // showInfo的信息不会动态改变 调了好久好久。苦笑脸
            // 判断是否击中(写在这里,虽然在每次重绘的时候都要调用,但是没办法)
            // 每一颗子弹都要和每个坦克进行匹配
            // for (int i = 0; i < hero.ss.size(); i++) {
            // // 取出子弹
            // Shot myShot = hero.ss.get(i);
            // // 判断子弹是否有效
            // if (myShot.isLive) {
            // // 取出每个坦克,与它判断
            // for (int j = 0; j < ets.size(); j++) {
            // // 取出坦克
            // EnemyTank et = ets.get(j);
            //
            // if (et.isLive) {
            // this.hitTank(myShot, et);
            // }
            // }
            // }
            // }
            this.hitEnemyTank();

            this.hitMe();

            // 重绘
            this.repaint();
        }
    }
}

Menbers类:

package com.fanghua6;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

//播放声音的类
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;
    }
}

// 记录类,同时也可以保存玩家的设置(一般都是事先写在缓存里面的)
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 Vector<EnemyTank> ets = new Vector<EnemyTank>();

    // 完成读取的函数(记录点和敌人的数量)
    public Vector<Node> getNodesAndEnNums() {
        try {
            fr = new FileReader("E:/Tanke.txt");
            br = new BufferedReader(fr);
            String n = "";
            n = br.readLine();// 设置先读第一行
            allEnNum = Integer.parseInt(n);
            // 接着读
            while ((n = br.readLine()) != null) {
                String[] xyz = n.split(" ");
                // 在知道只有三条数据的情况下,用了这个方法。否则要用for循环
                Node node = new Node(Integer.parseInt(xyz[0]),
                        Integer.parseInt(xyz[1]), Integer.parseInt(xyz[2]));
                nodes.add(node);
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                br.close();
                fr.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return nodes;
    }

    public Vector<EnemyTank> getEts() {
        return ets;
    }

    public void setEts(Vector<EnemyTank> ets) {
        this.ets = ets;
    }

    // 保存击毁敌人的数量和击毁敌人坦克的坐标、方向
    public void keepRecAndEnemyTank() {
        try {
            fw = new FileWriter("E:/Tanke.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 (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                bw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                fw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    // 从文件中读取,记录
    public static void getRecoring() {
        try {
            fr = new FileReader("E:/Tanke.txt");
            br = new BufferedReader(fr);
            String n = br.readLine();
            allEnNum = Integer.parseInt(n);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                br.close();
                fr.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    // 把玩家击毁敌人坦克数量保存到文件中
    public static void keepRecording() {
        try {
            fw = new FileWriter("E:/Tanke.txt");
            bw = new BufferedWriter(fw);

            bw.write(allEnNum + "\r\n");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                bw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                fw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

    public static int getAllEnNum() {
        return allEnNum;
    }

    public static void setAllEnNum(int allEnNum) {
        Recorder.allEnNum = allEnNum;
    }

    public static int getEnNum() {
        return enNum;
    }

    public static void setEnNum(int enNum) {
        Recorder.enNum = enNum;
    }

    public static int getMyLife() {
        return myLife;
    }

    public void setMyLife(int myLife) {
        Recorder.myLife = myLife;
    }

    // 减少敌人数
    public static void reduceEnNum() {
        enNum--;
    }

    // 消灭敌人
    public static void addEnNumRec() {
        allEnNum++;
    }

}

// 炸弹类(没必要定义为线程,因为它不会移动,没有坐标改变)
class Bomb {
    // 定义炸弹的坐标
    int x, y;
    int life = 9;// 炸弹的生命(三张图片)
    // 可以看出isLive很有用,它可以决定类(或者对象)要不要展现在面板上
    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;
    // 设置子弹的消亡(默认活着的)
    boolean isLive = true;
    // speed要给个初始值1,之前给0,按J键,子弹没有动
    int speed = 1;

    public Shot(int x, int y, int direct) {
        super();
        this.x = x;
        this.y = y;
        this.direct = direct;

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

        while (true) {
            // 设置子弹休息50毫秒

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            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);
            // 子弹什么时候死亡
            // 判断该子弹是否碰到边缘
            if (x < 0 || x > 400 || y < 0 || y > 300) {
                this.isLive = false;
                break;
            }
        }
    }
}

// 坦克类
class Tank1_2 {

    int x = 0;
    int y = 0;
    boolean isLive = true;

    // 坦克方向:0表示上,1表示右,2表示下,3表示左
    int direct = 0;
    int speed = 1;
    // 坦克的颜色
    int color;

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        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 Tank1_2(int x, int y) {
        this.x = x;
        this.y = y;

    }

}

// 敌人的坦克(做成线程,会移动)
class EnemyTank extends Tank1_2 implements Runnable {

    int times = 0;
    // 定义一个向量,可以访问MyPanel上所有敌人的坦克
    Vector<EnemyTank> ets = new Vector<EnemyTank>();
    // 定义向量,可以存放敌人的子弹
    Vector<Shot> ss = new Vector<Shot>();

    // 敌人添加子弹,应该刚刚创建坦克和敌人子弹死亡后

    public EnemyTank(int x, int y) {
        super(x, y);
    }

    // 得到MyPaneld的敌人坦克向量
    public void setEts(Vector<EnemyTank> vv) {
        // 此时拥有一种能力,可以拿到yPan el上所有敌人的坦克
        this.ets = vv;
    }

    // 判断是否碰到别的敌人的坦克
    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 >= et.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 == 1 || et.direct == 3) {
                        if (this.x >= et.x && this.x <= et.x + 30
                                && this.y >= et.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 >= et.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 == 1 || et.direct == 3) {
                        if (this.x + 30 >= et.x && this.x + 30 <= et.x + 30
                                && this.y >= et.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 >= et.y
                                && this.y + 30 <= et.y + 30) {
                            return true;
                        }
                        if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20
                                && this.y + 30 >= et.y
                                && this.y + 30 <= et.y + 30) {
                            return true;
                        }
                    }
                    if (et.direct == 1 || et.direct == 3) {
                        if (this.x >= et.x && this.x <= et.x + 30
                                && this.y + 30 >= et.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 >= et.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 == 1 || et.direct == 3) {
                        if (this.x >= et.x && this.x <= et.x + 30
                                && this.y >= et.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;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            try {
                // 设置坦克休息一会
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            switch (this.direct) {
            case 0:
                // 说明坦克正在向上运动(继续往上走,符合实际)
                // y -= speed;设置坦克平滑移动的效果
                for (int i = 0; i < 30; i++) {
                    if (y > 0 && !this.isTouchOtherEnemy()) {
                        y -= speed;
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            case 1:
                for (int i = 0; i < 30; i++) {
                    // 这里注意坐标起点问题不是(400x300)
                    if (x < 400 && !this.isTouchOtherEnemy()) {
                        x += speed;
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            case 2:
                for (int i = 0; i < 30; i++) {
                    if (y < 300 && !this.isTouchOtherEnemy()) {
                        y += speed;
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            case 3:
                for (int i = 0; i < 30; i++) {
                    if (x > 0 && !this.isTouchOtherEnemy()) {
                        x -= speed;
                    }
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                break;
            }
            this.times++;
            // 设置3秒发一颗子弹
            if (times % 2 == 0) {
                if (isLive) {
                    if (ss.size() < 5) {
                        Shot s = null;
                        // 没有子弹,添加
                        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) {
                // 让坦克死亡,后退出线程
                return;
            }

        }
    }
}

// 我的坦克
class Hero1_2 extends Tank1_2 {
    // 多个子弹,用向量创建
    Vector<Shot> ss = new Vector<Shot>();
    // 子弹
    Shot s = null;

    public Hero1_2(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);
            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;
    }
}

贯彻图片:

图片 2

相关资料:

一.放炮效果的图片(三张)

图片 3图片 4图片 5

贰.游戏音响素材

以此自个儿下载三个好啊(小编的是地点命名字为11壹.wav的文件,这里不协理上传)

http://www.bkjia.com/Javabc/1304229.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javabc/1304229.htmlTechArticleJava坦克大战(四),java坦克大战
那是本人的坦克游戏大战的末尾一版,里面增加大多新的效果。这些坦克战役的有许多不足之处,不过对于…