目录

一、简单介绍

二、工程目录

三、具体代码

四、运行效果截图

五、总结

六、说明与下载


一、简单介绍

    这是一个功能相对全的Java版坦克大战,界面绘制是通过Java的图形化用户界面swing完成的,包括了菜单界面和游戏界面。其中菜单界面可以供玩家选择重新开始游戏、暂停、继续、是否播放背景音乐、设置游戏难度等操作;游戏界面绘制了坦克、河流、草地、墙壁、鹰碉堡等经典坦克场景,玩家在游戏界面操作自己的坦克开始对战。

         本游戏使用的主要技术有Swing编程、面向对象编程、多线程编程。本想用I/O编程实现保存游戏数据,感觉单机版的没必要就没弄了。

游戏实现的主要功能有:

1、我方坦克默认可以渡河,碰到墙壁不能走,鹰碉堡被击中游戏结束

2、坦克可以上下左右、以及左上左下右上右下八个方向移动,移动时添加音效

3、坦克可以发子弹(可以连发),发射时添加音效

4、击中对方坦克时,坦克消失,显示爆炸效果;子弹击中墙壁时,子弹消失

5、我方坦克吃到血块时,生命值加30(可以自己设定);我方被击中时每次血量减50

6、移动过程中检测碰撞,包括坦克与坦克,坦克与草地、河流、墙壁等

7、声音处理(开始音乐、背景音乐、移动音效、爆炸音效等)

8、菜单处理(重新开始、暂停/继续游戏、是否播放背景音乐、设置游戏难度、帮助等)

9、默认击中一个敌人得100分,达到1500分进入下一关,一共设置了3关

10、生命数,默认两条命,命数用完游戏结束

二、工程目录

images文件夹存放草、鹰碉堡和河流图片,墙壁是用画笔画的;audio存放所有音效文件;所有java代码都存放在com.chuenhung.tank包下面。

三、具体代码

由于篇幅有限,这里只贴出Tank类源代码。Tank类是公用的,通过good变量来区分我方和敌人坦克。

Tank类源代码:

package com.chuenhung.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;
/*** *@Description 坦克类,包括坦克移动、坦克发射炮弹等*@author Chuenhung*@email 1271826574@qq.com*@date 2017年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;// 判断是否是我方坦克,默认trueprivate 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();// 剩余生命数private int remainLives =2;// 构造方法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_J:superFire();break;case KeyEvent.VK_SPACE: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 w 墙对象* @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 tanks 多辆坦克* @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 h 鹰碉堡对象* @return 是否碰到了鹰碉堡*/public boolean CollidesWithHome(Home h){if(this.live&&h.isLive()&&this.getRect().intersects(h.getRect())){this.stay();return true;}return false;}/*** * @Description 坦克是否碰到了河流,主要是地方坦克调用,我方坦克能直接渡河* @param r 河流对象* @return 是否碰到了河流*/public boolean CollidesWithRiver(River r){if(this.live&&this.getRect().intersects(r.getRect())){this.stay();return true;}return false;}/*** *@Description 坦克是否碰到了河流,主要是地方坦克调用,我方坦克能直接渡河* @param rivers 河流集合* @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);}/*** *@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 b 血块对象* @return 是否吃到了血块*/public boolean eat(Blood b){if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect())){this.life= life + 30;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;}public int getRemainLives() {return remainLives;}public void setRemainLives(int remainLives) {this.remainLives = remainLives;}
}

四、运行效果截图

重新开始、暂停、继续、发射子弹、爆炸效果演示:

渡河、吃血块功能演示:

五、总结

源代码参考了马老师的Java坦克大战视频教程以及众多互联网资源,这次练手有利于深入理解Java面向对象编程、Swing界面编程以及多线程编程

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

更新于2021/06/04

六、说明与下载

下载地址

备用下载地址

Java实现经典坦克大战及源代码下载相关推荐

  1. java完成经典坦克大战项目源码

    图片是类与类之间的包位置关系,与代码的导包操作相关 ​[点击并拖拽以移动] 图片是类之间的关系,以及工具类的包位置package com.tank.app;import com.tank.game.G ...

  2. HTML5经典坦克大战及源码

    目录 一.简单介绍 二.具体界面 主界面 排行榜界面 组员信息界面 组员信息场景 三.部分代码 3.1 界面绘制的实现 6.2 坦克移动实现 3.3 发射炮弹 3.4声音处理 3.5计分 四.总结 一 ...

  3. Java实现的经典坦克大战小游戏

    Java实现的经典坦克大战小游戏 先看一下游戏结构: 有点多,没有耐心的可以不用看,这里先给出链接吧! 云链接:经典坦克大战 提取码:s9ai 这里就不介绍功能了,贴了一张游戏运行的截图,具体的功能自 ...

  4. html实现经典坦克大战小游戏

    文章目录 1.设计来源 1.1 游戏主界面 1.2 游戏界面 2.效果和源码 2.1 动态效果 2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/w ...

  5. JAVA 实现《坦克大战》游戏|CSDN创作打卡

    前言 小时候大家都玩过坦克大战吧,熟悉的旋律和丰富的关卡陪伴了我们一整个寒暑假,还记得传说中的经典坦克大战 吗?那些怀旧的记忆,伴随着我们一起走过来的经典坦克大战,刚开始那战战兢兢,屡屡被敌人坦克击毁 ...

  6. Java练习之坦克大战!!!复制可以直接用!!!文章最后有飞机大战代码!!!

    用Java写一个入门游戏--坦克大战! 源代码!!!复制可以直接用!!! 文章最后还有飞机大战代码!!! 本代码写的较为入门,有需要的铁铁们可以去看看!!! 在往期我们讲解了窗口.循环.数组和继承的一 ...

  7. 【180718】FC经典坦克大战源码

    采用VB.NET开发的经典坦克大战FC游戏源码,模拟任天堂的坦克大战.全开源代码,测试请注意开启键盘大写.控制方式:大写的J K L I 控制坦克方向,F发弹. 注意事项: 开发环境为Visual S ...

  8. 【180622】VC++ 超经典坦克大战双人版

    超经典坦克大战双人版,VC++完整版,含声音.地图.资源文件,编译后请将Map.Sound.graphics拷贝至可执行文件同级目录内,否则出错.大家看看界面就知这游戏有多经典了吧?小时候没玩过的不多 ...

  9. C++实现经典坦克大战(一)

    简介 本项目是基于easyX库来实现的一个C++版本的经典坦克大战的游戏界面. easyX库的下载及安装使用 easyX的全称为EasyX Graphics Library,是针对与Visual C+ ...

  10. 实战小例子 | 经典坦克大战的python实现

    ​ 目录 效果展示 开发工具 讲解部分 一:游戏介绍 二:主体构成(地图讲解为主) 三:游戏的进阶 相关资源 代码获取 效果展示 开发工具 编译器:python3.6.4 主要的第三方库:pygame ...

最新文章

  1. “官之道”与“商之道”
  2. rsa python实现_RSA算法python实现
  3. 华为软件编程规范和范例 函数、过程
  4. 【MySql】 BlackHole :黑洞引擎
  5. python软件_Python自制照片美颜软件~
  6. 《从零开始学keras之神经风格迁移
  7. js中call()方法和apply方法的使用
  8. 蓝桥杯比赛的RTC时钟配置
  9. 小学 学生学籍信息汇总及自动检查代码(Python)
  10. LINQ 花3个礼拜的时间来弄清楚
  11. 【图像融合】基于matalb小波变换(加权平均法+局域能量+区域方差匹配)图像融合【含Matlab源码 1819期】
  12. “程序员的理财计划”-待完善
  13. linux工作周报范文300字,工作周报范文300字
  14. java httpclient 下载_java HttpClient 下载一张图片
  15. rfm模型python_Python pandas RFM模型应用实例详解
  16. java tld tag_jsp中引用的tag和tld文件
  17. 鸽了亿下下的游记——2022 GDOI普及组游记
  18. Tc27x的MTCR与MFCR指令
  19. 如何在 Windows 中快速查找文档
  20. 租车新玩法 神州租车打造行业标杆

热门文章

  1. 餐饮营销策划案例合集(共18份)
  2. PCSCHEMATIC ELAUTOMATION.V19.0.1.69中文正式单机版
  3. android 通过platform.pk8,platform.x509.pem生成jks签名文件
  4. esp32获取网络时间
  5. 计算机二级公共基础知识易错点汇总
  6. Win7安装RNDIS驱动
  7. RT-Thread Studio开发GD32VF103
  8. android游戏策划方案,游戏策划案模板.doc
  9. 物联网可视化平台-场景编辑器-轻松实现三维地图搭建
  10. java环境安装说明