Java实现经典版坦克大战(有工程源码,极致还原原版游戏)

1 篇文章 0 订阅
1 篇文章 1 订阅

2023/12/8 13:30更(20年完结,源码下载方法在文章底部。截至今天还可完美运行)

        闲来无事写写帖子,想想上次更新已经是在一年前。源码里面附带了注解和思路。我把游戏效果展示给企业的老师看,给我的反馈是很满意。项目的历程很艰辛,原本是三人的合作项目硬生生被我一个人包揽,最终功能实现得比较完整,算是对所学交了一份满意的答卷。

        整个项目按照规范开发,但不可避免,部分冗余依然还是存在的(已经优化过了)。毕竟是个人的小试牛刀。

        先来谈谈:众多课设题目里为甚偏偏对坦克大战情有独钟?(这里的课设指的是 Java 课程的大作业)。听前辈说 Java 的 swing 框架开发游戏已经过时,我也表示赞同。对初学 Java 的编程者,这样的实践能深刻反应阶段学习的成果,比如涉及到了多线程、考察代码风格、语言基础、设计模式等等。坦克大战是对童年的致敬,为什么这么说呢?因为这是笔者童年重要的一部分,放在当下仍然属于风靡的东西。当然这样的选题,最重要的原因还是应付学习任务 :)

        代码的细节及其实现,现在还是有一些印象。整个项目历时一周,大部分时间忙在逻辑设计和抠图。网上林林总总搜出来许多素材,但我感觉都没有原来的味道,所以大部分素材都被我二次加工。俗话:自己动手,丰衣足食。遗憾的是最后没有实现二人联网对战,因为个人技术不成熟。我的短板本来想着留给其他伙伴弥补,最后发现理想最是美好。但是在此项目基础上,结合在座大牛优化改进,肯定能呈现更好的效果。

        开发环境基于Eclipse photo(IDEA也可打开),JDK1.8,window10。先放一波代码运行效果:

20190706143540281.gif

20190706144152844.gif

        简单地阐述一下功能(有些细节不懂可以私我,虽然截至现在,大部分细节都忘了):

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0lfYW1fYV9ocmVv,size_16,color_FFFFFF,t_70

        游戏分为主界面和计数模板,主界面就是游戏界面,计数模板记录了关卡敌军数量和自己剩余命数,通关后在积分板,可以看到当前得分,每关会累加。如果得了最高分,会相应更新游戏的开始界面上的分数。输掉了当然就回到开始界面。双人被其他小伙伴实现了(这部分不是我做的,他做的挺摆烂,在大项目里可以把双人部分的子工程移除,然后自己可以去扩展、实现这部分)。

        游戏规则大家想必都懂。整个游戏的地图都是自己编辑的,我写了三个图。依葫芦画瓢,自己参照一下,也可以编辑出 more creative map。

        这里有必要说明下实现思路,是按照左上角像素点(x,y)在画板上描图。所以在源码里map包里可以看到大量包含点坐标的类。地图里包含五种元素,砖块、铁块、海洋、草地、冰块(在原版,坦克行驶在冰块上会滑行,但能力有限,没实现,只是显示图片哈)。一些地图元素坦克不能直接穿越,比如海洋和砖块。如何实现呢?有必要先说明,我的整个窗口以像素为单位,长高固定 560x560。地图元素(砖块等)图片32x32。建立一个二维像素数组(Tank[560][560],初始每个坐标值为 0),数组每个坐标(i,j)代表一个像素点,这里有个java swing小知识点(1.(0,0)坐标对应的是左上角,而不是左下角,这里不同与数学里的坐标轴。2.画图是在给定一个像素坐标,并以此为左上角绘制),比如:我想要在最左上角(0,0)绘制一块砖块,用循环把  Tank 数组里该图片所覆盖的点的坐标值设为 1(可以利用这里的值不同标记不同的地图元素,比如1代表砖块,2代表海洋等等),很明显这里需要修改的坐标区间是(i,j)且 i:0~32  j:0~32。接着在坦克移动前加上逻辑判断(这里还得分情况,上下一种,另外一种为左右,逻辑难度不高),对不同的坐标值做不同处理,比如 1 表示要移动的方位上有砖块,此时坦克应不能继续移动,即坦克对应在 Tank 数组里的坐标不改变。

        还有就是如何实现坦克履带会动,这些算细节的优化啦,不过还是强调先做出项目雏形。实现方法:判断坦克是否在移动,是则用 gif 替换静止的时候的坦克图片,根本不算技术活!源文件里有 Building 公共父类,这是所有地图元素(Grass,Ice,Sea,Steel,Wall)的父类。

        最后讲讲坦克和道具,这就比较复杂。源文件里有 Tank 公共父类,延申出的还有 Player(玩家)和 Enemy(敌人)类。坦克类的属性字段都有源文件注解哦,包含的属性有速度、移动方向、是否在移动、生命条数等,还有一些用于逻辑判断所需要额外添加的字段(比如:firstDraw,实现出生是有无敌光圈。fastBullet,吃到道具触发子弹加速等等)。Player 类里显式的看到有个存子弹的ArrayList,这样便于画出飞行的子弹,还有好多技术细节就不赘述了。Enemy 坦克类还有重要的 type 字段,不同的值对应不同类型的坦克(肉盾坦克(血条2条),飞速坦克(速度快),普通坦克,共三种),还有就是用来实现坦克消亡后掉落道具的 award 字段。道具也是多种多样。坦克消亡要额外 kill 线程。

        项目里面有涉及多线程,一个子弹就是一个线程,坦克也是。道具出现则在二维数组也要修改对应的(i,j)值。道具大概有以下几种类型,Boom(屏幕上出现的全部 Enmey 坦克自爆),Clock(时间静止,敌军坦克不能移动),Star(加分数),SteelHome(没有实现,就是基地护栏变成金属),Life(增加一条命),Shield(增加无敌护盾)等。

        源码重中之重在StageBody这里类里面,paintComponent方法加载了整个游戏的音效和图片和游戏逻辑、元素。

      运行的机器要配置好 Java8 运行环境,IDEA和Eclipse均可打开。附带游戏源码下载链接(源码放github,记得star哦 

打工人混口饭吃,源码放闲鱼(超低Price):【闲鱼】搜索用户:ufc小熊选手」
 

开发心得: 1. 做游戏能增加编程乐趣。2. 如果你们开发的游戏运行时,发现显卡处理得占比很高,最后程序崩溃,试试 paintComponent(Graphics g) 方法里加线程休眠(不要设置得太久,要不然游戏会严重卡顿,即刷新率慢。试试10~100)。3. 想把项目打包成 exe 格式,试试 exe4j 工具。不过打包出的游戏运行会和IDE里跑的有点差别(下面会留白边,而且窗口不知道怎得变大了一些)。4. 想实现坦克从草地下面驶出,只要改变一下画图的顺序,先画草地,再画坦克(paintComponent(Graphics g)里面去实现),就像PS里的图层概念。5. foreach 循环里不要进行remove和add操作(特别是多线程下),今天阿里开发手册看到的,开发时遇过小坑。

  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值