JAVA realize the classic Battle City and source code download

First, a brief introduction

        This is a full-function relatively Battle City version of JAVA, JAVA interface is drawn through a graphical user interface to complete, including the menu interface and game interface. Where the menu interface can be used by players to choose again to start the game, pause, resume, whether to play background music to help other operations; game interface is drawn tanks, rivers, meadows, eagles bunkers and other classic tank scene, players in the game interface operation tanks start the game.

         The main technology used in this game there are Swing programming, object-oriented programming, multithreaded programming. Wanted to achieve saved game data I / O programming, no need to feel there is no stand-alone version to get.

The main function of the game to achieve are:

1. The tanks may be up and down, the upper left and lower left upper right lower right eight moving direction, moving sound added

2. The tanks can be bullets (may bursts), emitting a sound when added

3. hit each other tanks, tank disappears and explosions; the bullet hit the eagle bunker, the game is over; the bullet struck a wall of bullets disappear

4. Our tanks eat when blood clots, the value of life to fill

The movement is detected during a collision, the tanks including tanks, tank and grassland, rivers, walls, etc.

6. The sound processing (start music, background music, etc.)

7. menu processing (to start the game, pause the game, continue the game, help, etc.)

8. score (points off, record results)

Second, the project directory

Third, the specific code

Each file has detailed notes, do not understand can contact the author, here only posted Tank.java and TankClient.java code, the source code will be posted out in the final surface article, did not talk much, first on the code

 

Tank.java Code

 

package com.xiaoli.tank;


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;
/**
 * 
 *Title:Tank
 *Description:坦克类,包括坦克移动、坦克发射炮弹等 
 *@author xiaoli
 *@date2017年1月4日
 */
public class Tank {
//坦克X方向速度,设置游戏难度时可拓展
    public static int XSPEED = 5;
    //坦克Y方向速度,设置游戏难度时可拓展
public static int YSPEED = 5;
//坦克宽度
public static final int WIDTH = 30;
//坦克高度
public static final int HEIGHT = 30;
//坦克是否活着
private boolean live = true;
//坦克的生命值
private int life = 100;
//持有对TankClient大管家的引用
TankClient tc;
//判断是否是我方坦克,默认true
private boolean good=true;
//用于记录坦克原来的坐标,碰到墙、坦克时方便退一步
private int oldX,oldY;
//绘制坦克的左上角坐标
private int x, y;
//用于产生随机数
private static Random r = new Random();
//用于控制敌人随机发出子弹
private int step = r.nextInt(30)+10;
//判断是否按下方向键
private boolean bL=false, bU=false, bR=false, bD = false;
//枚举类型定义了坦克的八个方向,和静止时的方向
enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};
//坦克的方向
private Direction dir = Direction.STOP;
//炮筒的方向
private Direction ptDir = Direction.D;
    //血条
private BloodBar bar = new BloodBar();
//构造方法
public Tank(int x, int y, boolean good) {
this.x = x;
this.y = y;
this.good = good;
}
//构造方法
public Tank(int x, int y, boolean good, Direction dir,TankClient tc) {
this(x, y, good);
this.tc = tc;
this.oldX=x;
this.oldY=y;
this.dir=dir;
}
/**
* 
*@Description:画出坦克
* @param g
*/
public void draw(Graphics g) {
if(!live) {
if(!good) {
tc.tanks.remove(this);
}
return;
}
Color c = g.getColor();
if(good) g.setColor(Color.RED);
else g.setColor(Color.BLUE);
g.fillOval(x, y, WIDTH, HEIGHT);
g.setColor(c);
//血条
   if(good) bar.draw(g); 
switch(ptDir) {
case L:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT/2);
break;
case LU:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y);
break;
case U:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y);
break;
case RU:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y);
break;
case R:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT/2);
break;
case RD:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT);
break;
case D:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y + Tank.HEIGHT);
break;
case LD:
g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT);
break;
}

move();
}
/*
* 坦克移动
*/
void move() {
this.oldX=x;
this.oldY=y;
switch(dir) {
case L:
x -= XSPEED;
break;
case LU:
x -= XSPEED;
y -= YSPEED;
break;
case U:
y -= YSPEED;
break;
case RU:
x += XSPEED;
y -= YSPEED;
break;
case R:
x += XSPEED;
break;
case RD:
x += XSPEED;
y += YSPEED;
break;
case D:
y += YSPEED;
break;
case LD:
x -= XSPEED;
y += YSPEED;
break;
case STOP:
break;
}
if(this.dir != Direction.STOP) {
this.ptDir = this.dir;
}
if(!good){
Direction[] dirs = Direction.values();
if(step==0){
step=r.nextInt(30)+10;
int rn = r.nextInt(9);
this.dir=dirs[rn];
}
step--;
//敌人发子弹
if(r.nextInt(40)>36){
  this.fire();
}
}
if(x < 0) x = 0;
if(y < 55) y = 55;
if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
}
/**
* 
*@Description:用于撞到墙、坦克时返回上一步
*/
private void stay(){
x=oldX;
y=oldY;
}
/**
* 
*@Description:按下键时监听
* @param e
*/
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_R:
tc.bloods.clear();
    tc.grasses.clear();
    tc.rivers.clear();
    tc.walls.clear();
    tc.missiles.clear();
    tc.tanks.clear();
    tc.explodes.clear();
    
    //关卡、分数重置
    tc.score=0;
    tc.level=1;
    //草地
    tc.newGrass();
    //河流
    tc.newRiver();
    //墙
    tc.newWall();
    //当在区域中没有坦克时,就出来坦克      
    if (tc.tanks.size() == 0) {   
    tc.newTank();
}
tc.myTank = new Tank(220, 560, true, Direction.STOP, tc);//设置自己出现的位置
if(!tc.home.isLive()){
tc.home.setLive(true);
}
tc.dispose();
new TankClient().lauchFrame();
break;
case KeyEvent.VK_LEFT :
bL = true;
break;
case KeyEvent.VK_UP :
bU = true;
break;
case KeyEvent.VK_RIGHT :
bR = true;
break;
case KeyEvent.VK_DOWN :
bD = true;
break;
}
locateDirection();
}
/**
* 
*@Description:定位坦克的方向
*/
void locateDirection() {
if(bL && !bU && !bR && !bD) dir = Direction.L;
else if(bL && bU && !bR && !bD) dir = Direction.LU;
else if(!bL && bU && !bR && !bD) dir = Direction.U;
else if(!bL && bU && bR && !bD) dir = Direction.RU;
else if(!bL && !bU && bR && !bD) dir = Direction.R;
else if(!bL && !bU && bR && bD) dir = Direction.RD;
else if(!bL && !bU && !bR && bD) dir = Direction.D;
else if(bL && !bU && !bR && bD) dir = Direction.LD;
else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;
}
    /**
     * 
     *@Description:松开键时监听
     * @param e
     */
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_K:
if(this.good){
if(!this.live){
this.live=true;
this.life=100;
//复活次数加1
tc.count++;
}
}
break;
case KeyEvent.VK_J:
superFire();
break;
case KeyEvent.VK_CONTROL:
fire();
//发射炮弹音效
new Audio(2);
break;
case KeyEvent.VK_LEFT :
bL = false;
new Audio(1);
break;
case KeyEvent.VK_UP :
bU = false;
new Audio(1);
break;
case KeyEvent.VK_RIGHT :
bR = false;
new Audio(1);
break;
case KeyEvent.VK_DOWN :
bD = false;
new Audio(1);
break;
}
locateDirection();
}
/**
* 
*@Description:坦克开火
* @return 炮弹对象
*/
public Missile fire() {
if(!live)return null;
int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
Missile m = new Missile(x, y, ptDir,this.good, this.tc);
tc.missiles.add(m);
return m;
}
/**
* 
*@Description:坦克根据方向开火
* @return 炮弹对象
*/
public Missile fire(Direction dir) {
if(!live)return null;
int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
Missile m = new Missile(x, y, dir,this.good, this.tc);
tc.missiles.add(m);
return m;
}
/**
* 
*@Description:超级炮弹,可以向八个方向开火
*/
public void superFire(){
Direction[] dirs = Direction.values();
for(int i=0;i<8;i++){
fire(dirs[i]);
}
}
/**
* 
*@Description:判断坦克是否撞墙
* @param 墙对象
* @return 是否撞墙了
*/
public boolean CollidesWithWall(Wall w){
if(this.live&&this.getRect().intersects(w.getRect())){
this.stay();
return true;
}
return false;
}
public boolean CollidesWithWalls(List<Wall> walls){
        for(int i=0;i<walls.size();i++){
        Wall w = walls.get(i);
        if(this.live&&this.getRect().intersects(w.getRect())){
           this.stay();
        return true;
        }
        }
return false;
}
/**
* 
*@Description:判断坦克是否相撞
* @param 多辆坦克
* @return 是否和坦克相撞了
*/
public boolean collidesWithTanks(List<Tank> tanks){
for(int i=0;i<tanks.size();i++){
Tank t = tanks.get(i);
if(this!=t){
if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){
this.stay();
t.stay();
return true;
}
}
}
return false;
}
/**
* 
*@Description:坦克是否碰到了鹰碉堡
* @param 鹰碉堡对象
* @return 是否碰到了鹰碉堡
*/
public boolean CollidesWithHome(Home h){
if(this.live&&h.isLive()&&this.getRect().intersects(h.getRect())){
this.stay();
return true;
}
return false;
}
/**
* 
*@Description:坦克是否碰到了河流,主要是地方坦克调用,我方坦克能直接渡河
* @param 河流对象
* @return 是否碰到了河流
*/
public boolean CollidesWithRiver(River r){
if(this.live&&this.getRect().intersects(r.getRect())){
this.stay();
return true;
}
return false;
}
/**
* 
*@Description:坦克是否碰到了河流,主要是地方坦克调用,我方坦克能直接渡河
* @param 河流集合
* @return 是否碰到了河流
*/
public boolean CollidesWithRivers(List<River> rivers){
for(int i=0;i<rivers.size();i++){
River t = rivers.get(i);
if(this.live&&this.getRect().intersects(t.getRect())){
this.stay();
return true;
}
}
return false;
}
public Rectangle getRect() {
return new Rectangle(x, y, WIDTH, HEIGHT);
}
    /**
     * 
     *Title:BloodBar
     *Description:我方坦克的血条,用于显示我方坦克的生命值 
     *@author xiaoli
     *@date2017年1月4日
     */
private class BloodBar{
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.PINK);
g.drawRect(x,y-10,WIDTH,8);
//里面的
g.setColor(Color.PINK);
int w =WIDTH*life/100;
g.fillRect(x, y-10, w, 8);
g.setColor(c);
}
}
/**
* 
*@Description:吃血块,主要是我方坦克调用
* @param 血块对象
* @return 是否吃到了血块
*/
public boolean eat(Blood b){
if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect())){
this.life=100;
b.setLive(false);
tc.bloods.remove(b);
//吃血块音效
new Audio(4);
return true;
}
return false;
}
public boolean isLive() {
return live;
}


public void setLive(boolean live) {
this.live = live;
}
public int getLife() {
return life;
}


public void setLife(int life) {
this.life = life;
}
public boolean isGood() {
return good;
}
}

 

TankClient.java Code

package com.xiaoli.tank;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


import javax.swing.JOptionPane;
/**
 * 
 *Title:TankClient
 *Description:这个类是大管家,控制着其他类,也是程序入口 
 *@author xiaoli
 *@date2017年1月4日
 */
public class TankClient extends Frame implements ActionListener {
//游戏宽度
public static final int GAME_WIDTH = 800;
//游戏高度
public static final int GAME_HEIGHT = 600;
    //是否开启重绘线程
public static boolean printable=true;
//用于产生随机数
Random r = new Random();
//记录复活次数
public static int count=0;
//关卡
public static int level=1;
//分数
public static int score=0;
//菜单条
MenuBar jmb = null;
//菜单
Menu jm1 = null, jm2 = null, jm3 = null, jm4 = null;
//菜单项
MenuItem jmi1 = null, jmi2 = null, jmi3 = null, jmi4 = null, jmi5 = null,
jmi6 = null, jmi7 = null, jmi8 = null, jmi9 = null,jmi10=null,jmi11=null;
//从上到下从左到右画墙
Wall w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12;
//创建我的坦克
Tank myTank = new Tank(220, 560, true,Tank.Direction.STOP, this);
//创建鹰碉堡
Home home = new Home(379,556,this);
    //墙集合,用于存放墙
List<Wall> walls = new ArrayList<Wall>();
//河流集合,用于存放河流
List<River> rivers = new ArrayList<River>();
//定义一个血块
Blood b=null;
//血块集合,用于存放血块。用集合的原因是方便删除
List<Blood> bloods = new ArrayList<Blood>();
//草集合,用于存放草
List<Grass> grasses = new ArrayList<Grass>();
//炸弹集合,用于存放炸弹
List<Explode> explodes = new ArrayList<Explode>();
//炮弹集合,用于存放炮弹
List<Missile> missiles = new ArrayList<Missile>();
//坦克集合,用于存放坦克
List<Tank> tanks = new ArrayList<Tank>();
//用于解决双缓冲闪烁现象
Image offScreenImage = null;
/**
* 绘制场景
*/
public void paint(Graphics g) {
//分关
if (score >= 1000 * level ) {
setLevel(level + 1); // 进入下一关
new Audio(5);
grasses.clear();
    rivers.clear();
    missiles.clear();
    tanks.clear();
       explodes.clear();
    walls.clear();
    this.dispose();
new TankClient().lauchFrame();
}
//家
home.draw(g);
//只能复活一次
if(myTank.getLife()<=0&&count==1){
myTank.setLive(false);
home.gameOver(g);
}
if(r.nextInt(50)>48){
newBlood();
}
//敌人死光
if(tanks.size()<=0){
for(int i=0; i<6; i++) {
if(i<3){
   tanks.add(new Tank(50 + 40*(i+1), 50, false,Tank.Direction.D, this));
}else{
tanks.add(new Tank(50 + 40*(i+1), 50, false,Tank.Direction.R, this));
}
}
}
//g.drawString("血块数量:" + bloods.size(), 10, 50);
//g.drawString("子弹数量:" + missiles.size(), 10, 70);
//g.drawString("炸弹数量:" + explodes.size(), 10, 90);
//g.drawString("坦克数量:" + tanks.size(), 10, 110);
g.drawString("关卡:" + level, 10, 90);
g.drawString("分数:" + score, 10, 110);
g.drawString("生命值:" + myTank.getLife(), 10, 130);
g.drawString("复活次数:" + count, 10, 150);
//画墙
for(int i=0;i<walls.size();i++){
walls.get(i).draw(g);
}
for(int i=0; i<missiles.size(); i++) {
Missile m = missiles.get(i);
m.hitWalls(walls);
m.hitTanks(tanks);
m.hitTank(myTank);
m.hitHome(home);
m.draw(g);
//if(!m.isLive()) missiles.remove(m);
//else m.draw(g);
}

for(int i=0; i<explodes.size(); i++) {
Explode e = explodes.get(i);
e.draw(g);
}

for(int i=0; i<tanks.size(); i++) {
Tank t = tanks.get(i);
t.CollidesWithWalls(walls);
myTank.collidesWithTanks(tanks);
t.collidesWithTanks(tanks);
t.CollidesWithHome(home);
t.CollidesWithRivers(rivers);
t.draw(g);
}
myTank.CollidesWithWalls(walls);
myTank.CollidesWithHome(home);
//画河流
for(int i=0;i<rivers.size();i++){
rivers.get(i).draw(g);
}
myTank.draw(g);
// 画草地
for (int i = 0; i < grasses.size(); i++) {
grasses.get(i).draw(g);
}
// 画血块
for (int i = 0; i < bloods.size(); i++) {
Blood b = bloods.get(i);
b.draw(g);
myTank.eat(b);
}
}
/**
* repaint先调用update再调用paint,用于解决双缓冲闪烁现象
*/
public void update(Graphics g) {
if(offScreenImage == null) {
offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(new Color(0xcce8cf));
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
    /**
     * 本方法显示程序主窗口
     */
public void lauchFrame() {
//菜单项
newMenu();
//墙
newWall();
//河流
newRiver();
//草地
newGrass();
//坦克
newTank();
this.setTitle("经典坦克大战游戏 作者:小李");
//this.setLocation(600,300);
this.setSize(GAME_WIDTH, GAME_HEIGHT);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((dim.width - getSize().width) / 2,
(dim.height - getSize().height) / 2);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setResizable(false);
this.addKeyListener(new KeyMonitor());

setVisible(true);

new Thread(new PaintThread()).start();
//声音
if(this.level==1){
 StartAudio startAudio = new StartAudio("audio/7301.wav");
 startAudio.start();
}
}
/**
* 
*@Description:菜单项
*/
public void newMenu(){
// 创建菜单及菜单选项
jmb = new MenuBar();
jm1 = new Menu("游戏");
jm2 = new Menu("暂停/继续");
jm3 = new Menu("帮助");
jm4 = new Menu("游戏难度");
jm1.setFont(new Font("宋体", Font.BOLD, 15));// 设置菜单显示的字体
jm2.setFont(new Font("宋体", Font.BOLD, 15));// 设置菜单显示的字体
jm3.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
jm4.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体


jmi1 = new MenuItem("重新开始");
jmi2 = new MenuItem("退出");
jmi11= new MenuItem("开启背景音乐");

jmi3 = new MenuItem("暂停");
jmi4 = new MenuItem("继续");
jmi5 = new MenuItem("游戏说明");
jmi6 = new MenuItem("难度1");
jmi7 = new MenuItem("难度2");
jmi8 = new MenuItem("难度3");
jmi9 = new MenuItem("难度4");
jmi10 = new MenuItem("操作说明");

jmi1.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi2.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi3.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi4.setFont(new Font("TimesRoman", Font.BOLD, 15));
jmi5.setFont(new Font("TimesRoman", Font.BOLD, 15));


jm1.add(jmi1);
jm1.add(jmi2);
jm1.add(jmi11);

jm2.add(jmi3);
jm2.add(jmi4);
jm3.add(jmi5);
jm3.add(jmi10);

jm4.add(jmi6);
jm4.add(jmi7);
jm4.add(jmi8);
jm4.add(jmi9);


jmb.add(jm1);
jmb.add(jm2);
jmb.add(jm4);
jmb.add(jm3);
jmi1.addActionListener(this);
jmi1.setActionCommand("NewGame");
jmi2.addActionListener(this);
jmi2.setActionCommand("Exit");
jmi11.addActionListener(this);
jmi11.setActionCommand("startMain");

jmi3.addActionListener(this);
jmi3.setActionCommand("Stop");
jmi4.addActionListener(this);
jmi4.setActionCommand("Continue");
jmi5.addActionListener(this);
jmi5.setActionCommand("help1");
jmi10.addActionListener(this);
jmi10.setActionCommand("help2");

jmi6.addActionListener(this);
jmi6.setActionCommand("level1");
jmi7.addActionListener(this);
jmi7.setActionCommand("level2");
jmi8.addActionListener(this);
jmi8.setActionCommand("level3");
jmi9.addActionListener(this);
jmi9.setActionCommand("level4");


this.setMenuBar(jmb);// 菜单Bar放到JFrame上
}
/**
* 
*@Description:生成墙
*/
public void newWall() {
if(this.level==1){
w1 = new Wall(210, 200, 100, 30, this);
w2 = new Wall(210, 200, 30, 190, this);
w3 = new Wall(280, 200, 30, 190, this);
w4 = new Wall(210, 370, 100, 30, this);
w5 = new Wall(440, 200, 100, 30, this);
w6 = new Wall(440, 200, 30, 95, this);
w7 = new Wall(470, 265, 70, 30, this);
w8 = new Wall(510, 200, 30, 190, this);
w9 = new Wall(440, 370, 100, 30, this);
w10 = new Wall(379, 530, 43, 20, this);
w11 = new Wall(280, 530, 30, 70, this);
w12 = new Wall(510, 530, 30, 70, this);
walls.add(w1);
walls.add(w2);
walls.add(w3);
walls.add(w4);
walls.add(w5);
walls.add(w6);
walls.add(w7);
walls.add(w8);
walls.add(w9);
walls.add(w10);
walls.add(w11);
walls.add(w12);
}else if(this.level==2){
w1 = new Wall(210, 200, 100, 30, this);
w2 = new Wall(210, 200, 30, 190, this);
w3 = new Wall(280, 200, 30, 190, this);
w4 = new Wall(210, 370, 100, 30, this);

w5 = new Wall(410, 200, 30, 70, this);
w6 = new Wall(410, 200, 90, 30, this);
w7 = new Wall(470, 200, 30, 190, this);
w8 = new Wall(470, 370, 90, 30, this);
w9 = new Wall(530, 320, 30, 65, this);

w10 = new Wall(379, 530, 43, 20, this);
w11 = new Wall(280, 530, 30, 70, this);
w12 = new Wall(510, 530, 30, 70, this);
walls.add(w1);
walls.add(w2);
walls.add(w3);
walls.add(w4);
walls.add(w5);
walls.add(w6);
walls.add(w7);
walls.add(w8);
walls.add(w9);
walls.add(w10);
walls.add(w11);
walls.add(w12);
}else if(this.level>=3){
w1 = new Wall(210, 200, 100, 30, this);
w2 = new Wall(210, 200, 30, 190, this);
w3 = new Wall(280, 200, 30, 190, this);
w4 = new Wall(210, 370, 100, 30, this);

w5 = new Wall(430, 200, 90, 30, this);
w6 = new Wall(430, 285, 90, 30, this);
w7 = new Wall(430, 370, 90, 30, this);
w8 = new Wall(500, 200, 30, 200, this);

w10 = new Wall(379, 530, 43, 20, this);
w11 = new Wall(280, 530, 30, 70, this);
w12 = new Wall(510, 530, 30, 70, this);
walls.add(w1);
walls.add(w2);
walls.add(w3);
walls.add(w4);
walls.add(w5);
walls.add(w6);
walls.add(w7);
walls.add(w8);

walls.add(w10);
walls.add(w11);
walls.add(w12);
}
}
/**
* 
*@Description:生成血块
*/
public void newBlood(){
//血块
b = new Blood();
//if(b.CollidesWithWalls(walls)){//血块不能画在墙里面
//return;
//}
if(bloods.size()==0){
 bloods.add(b);
}
}
/**
* 
*@Description:生成河流
*/
public void newRiver(){
for(int i=0;i<6;i++){
River river = new River(18+i*30,340);
rivers.add(river);
river = new River(18+i*30,340+30);
rivers.add(river);
}
for(int i=0;i<6;i++){
River river = new River(568+i*30,340);
rivers.add(river);
river = new River(568+i*30,340+30);
rivers.add(river);
}
}
/**
* 
*@Description:生成草地
*/
public void newGrass() {
// 草地
for (int i = 0; i < 10; i++) {
Grass grass = new Grass((i + 1) * 18, 200);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 1 * 18);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 2 * 18);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 3 * 18);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 4 * 18);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 5 * 18);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 6 * 18);
grasses.add(grass);
grass = new Grass((i + 1) * 18, 200 + 7 * 18);
grasses.add(grass);
}
for (int i = 1; i <= 11; i++) {
Grass grass = new Grass(250 + 18 * 7, 182 + i * 18);
grasses.add(grass);
grass = new Grass(250 + 18 * 8, 182 + i * 18);
grasses.add(grass);
grass = new Grass(250 + 18 * 5, 182 + i * 18);
grasses.add(grass);
grass = new Grass(250 + 18 * 6, 182 + i * 18);
grasses.add(grass);
}
for(int i=0;i<10;i++){
Grass grass = new Grass(550+(i + 1) * 18, 200);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 1 * 18);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 2 * 18);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 3 * 18);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 4 * 18);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 5 * 18);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 6 * 18);
grasses.add(grass);
grass = new Grass(550+(i + 1) * 18, 200 + 7 * 18);
grasses.add(grass);
}
}
/**
* 
*@Description:生成坦克
*/
public void newTank(){
for (int i = 0; i < 10; i++) {
if (i < 5) {
tanks.add(new Tank(50 + 40 * (i + 1), 55, false,
Tank.Direction.D, this));
} else {
tanks.add(new Tank(50 + 40 * (i + 1), 55, false,
Tank.Direction.R, this));
}
}
}
/**
* 
*@Description:主函数、程序入口
* @param args
*/
public static void main(String[] args) {
TankClient tc = new TankClient();
tc.lauchFrame();

}
/**
* 
*Title:PaintThread
*Description:重绘线程,模拟动态效果 
*@author xiaoli
*@date2017年1月4日
*/
private class PaintThread implements Runnable {


public void run() {
while(printable) {
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 
*@Description:按键监听,对坦克、炮弹等进行人机交互
* @param e
*/
private class KeyMonitor extends KeyAdapter {
public void keyReleased(KeyEvent e) {
myTank.keyReleased(e);
}


public void keyPressed(KeyEvent e) {
myTank.keyPressed(e);
}

}
    /**
     * 对菜单项操作
     */
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getActionCommand().equals("NewGame")) {
printable = false;
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要重新开始!", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
                this.score=0;
                this.setLevel(1);
printable = true;
this.dispose();
new TankClient().lauchFrame();
} else {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}


} else if (e.getActionCommand().endsWith("Stop")) {
printable = false;
// try {
// Thread.sleep(10000);
//
// } catch (InterruptedException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
} else if (e.getActionCommand().equals("Continue")) {


if (!printable) {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}
// System.out.println("继续");
} else if (e.getActionCommand().equals("Exit")) {
printable = false;
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
System.out.println("退出");
System.exit(0);
} else {
printable = true;
new Thread(new PaintThread()).start(); // 线程启动


}


} else if (e.getActionCommand().equals("help1")) {
printable = false;
JOptionPane.showMessageDialog(null, "随着人们精神文化生活的日益丰富,游戏成为了人们生活中必不可少的一部分\n90《坦克大战》更是90后一代人童年的回忆,也是一款经典游戏。\n"
+ "开发java版坦克大战有利用更深入理解java面向对象编程、swing界面编程、多线程编程"+"\n"+"参考:马士兵坦克大战视频教程、以及互联网资源"+"\n"+"作者邮箱:[email protected]"+"\n"
+"若有关内容侵犯了您的权益,请及时联系作者删除,谢谢!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
this.setVisible(true);
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
} else if(e.getActionCommand().equals("help2")){
printable = false;
JOptionPane.showMessageDialog(null, "用→ ← ↑ ↓控制方向,CTRL键盘发射,J超级炮弹,K复活(只能复活一次),R重新开始!\n"+"作者邮箱:[email protected]"+"\n"
+"若有关内容侵犯了您的权益,请及时联系作者删除,谢谢!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
this.setVisible(true);
printable = true;
new Thread(new PaintThread()).start(); // 线程启动
}

else if (e.getActionCommand().equals("level1")) {
//Tank.count = 12;
Tank.XSPEED = 5;
Tank.YSPEED = 5;
Missile.XSPEED = 10;
Missile.YSPEED = 10;
this.dispose();
new TankClient().lauchFrame();;
} else if (e.getActionCommand().equals("level2")) {
//Tank.count = 12;
Tank.XSPEED = 8;
Tank.YSPEED = 8;
Missile.XSPEED = 14;
Missile.YSPEED = 14;
this.dispose();
new TankClient().lauchFrame();;


} else if (e.getActionCommand().equals("level3")) {
//Tank.count = 20;
Tank.XSPEED = 12;
Tank.YSPEED = 12;
Missile.XSPEED = 18;
Missile.YSPEED = 18;
this.dispose();
new TankClient().lauchFrame();;
} else if (e.getActionCommand().equals("level4")) {
//Tank.count = 20;
Tank.XSPEED = 16;
Tank.YSPEED = 16;
Missile.XSPEED = 24;
Missile.YSPEED = 14;
this.dispose();
new TankClient().lauchFrame();;
}else if(e.getActionCommand().equals("startMain")){
printable = false;
JOptionPane.showMessageDialog(null, "开启后不能关闭!请不要重复点击!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
this.setVisible(true);
printable = true;
// 线程启动
new Thread(new PaintThread()).start(); 
new Audio(0);
}
 }
/*
 * 设置关卡
 */
public void setLevel(int level) { //设置三关
if (level > 10) {
level = 10;
}
this.level = level;
}
}

 

Fourth, run shot

 




V. Summary

Reference to the source code of java Battle City Ma, video tutorials, and a number of Internet resources, this practice has the use of hand-depth understanding of java object-oriented programming, swing interface programming, multithreaded programming

大部分功能是本人在实训期间完成(2016.12.30),当时有兴趣想巩固一下java知识就开始做了
这个坦克大战到这里就告一个段落,时间荏苒,马上就要毕业了,要学的东西很多的,希望以后能够做出更加优秀的作品。
该程序谨供参考,不得用于商业用途,希望大神能提出更多优化的建议,一起交流。
若有关内容侵犯了您的权益请及时联系作者删除,作者邮箱[email protected]

六、说明与下载

之前把那个资源修改了,然后CSDN出BUG了,等了10多天都没修复,所以重新上传了该资源。这个资源我一直没设置积分,CSDN改版后会随着下载次数增多,积分也增多,刚刚看了需要50分。

我看到文章下面很多用户留言,其实大部分的我都通过邮箱发送了,帮助了很多人。

下载地址

 

 

发布了30 篇原创文章 · 获赞 74 · 访问量 12万+

Guess you like

Origin blog.csdn.net/a1275302036/article/details/54232751