毕业设计论文基于Java的坦克大战软件程序设计.docx
- 文档编号:4692947
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:39
- 大小:43.19KB
毕业设计论文基于Java的坦克大战软件程序设计.docx
《毕业设计论文基于Java的坦克大战软件程序设计.docx》由会员分享,可在线阅读,更多相关《毕业设计论文基于Java的坦克大战软件程序设计.docx(39页珍藏版)》请在冰点文库上搜索。
毕业设计论文基于Java的坦克大战软件程序设计
华中科技大学文华学院
基于Java的坦克大战游戏软件程序设计
题目:
基于Java的坦克大战游戏的设计与实现
学生姓名:
学号:
学部(系):
_信息科学与技术学部_
专业年级:
_11级电子信息工程_
指导教师:
职称或学位:
_硕士_
2015年5月2日
摘要
随着网络时代的到来及发展,游戏产业方兴未艾,出现了前所未有的繁荣。
“贪吃蛇”、“俄罗斯方块”这些简单的游戏曾为一代接一代的游戏玩家所熟悉。
并且随着网络通信技术的迅速发展,更加有趣、更为生动的游戏层出不穷。
由于Java技术的不断发展,Java良好的跨平台特性在移动平台的开发中显示出了巨大的威力。
Java语言面向对象的优势也使得开发游戏变得非常容易,同时eclipse平台的优越性也给了这类游戏程序的设计带来了很多的优点和方便。
本论文主要介绍了坦克大战游戏的设计思路和实现过程。
这种设计主要是利用函数对背景的所有物体进行绘图,然后利用线程以及事件监听机制对物体进行控制,例如坦克,从而实现各种功能,最后就可以构成一个活生生的坦克大战游戏了。
Java功能在移动设备上的实现,Java应用程序产生的服务逐渐体现出其影响力,对丰富人们的生活内容、提供快捷的资讯起着不可忽视的作用。
本论文着眼于java语言的优点,开发一款可可供娱乐的游戏程序——坦克大战。
[关键字]:
eclipse平台,游戏,Java,坦克大战
摘要-I-
Abstract-I-
第一章程序结构、思想和相关技术
1.1本程序需解决的有关技术问题
1.坦克大战是一个可大可小的游戏,想法灵活可以编写出很多功能,所以需要对程序的要求量应该是巨大的,但是其代码利用率很高,因此实际编写时也不需要太多的绞尽脑汁,可以利用各模块程序的相近性灵活运用。
一个实时运行的最终作品,每秒都会运行成千上万行程序,绘图事件、键盘事件都会以极高的频率在后台等待响应,若有丝毫的差别都将很容易导致程序在运行不久后可能出现严重错误,甚至死循环。
因此,其逻辑设计应当相当严谨,需将所有可能发生的事件及意外情况考虑在设计中。
2.游戏中为了美观,适用性强以及操作的简便性,我们主要利用draw函数画出矩形,圆及线构成一辆Tank,同时画出子弹,敌方坦克可以直接引用之前画出的坦克,这样画图的问题就基本解决了。
3.己方坦克的运行可以通过键盘响应事件控制,但敌方则因为是自动运行,就需要有一定其一定的智能性;同时,出现在屏幕上的敌方可能会有较多的数量,这需要为每个敌方开辟一个线程以便能让其独立运行。
Java的多线程能力为实现这样的游戏提供了可能。
敌人坦克的运行算法也需要进行适当的设置,以免游戏过于简单,单调。
4.对于双方坦克发出的子弹的控制也需要对其跟踪控制,子弹也需要处在独立的线程中。
敌方子弹仅需要扫描用户坦克,而用户坦克需要在每一步扫描所有的敌方坦克。
这需要对所有的对象有较好的控制。
另外,子弹在运行过程中也需要实时扫描是否碰撞到了相关障碍物或屏幕边界。
同时为了游戏的公平性,己方坦克发出的子弹数量必须控制,不能一下发出太多颗。
5.对于敌我双方的坦克在运动的过程中也需要考虑会不会发生碰撞也就是重叠状况体,也要考虑坦克碰到边缘时不能继续前进,以免跑出有效范围,每前进一步都需要将所有的周围环境进行严格的控制。
6.游戏的结束、开始、动态画面等信息是构成一个完美程序必不可少的环节。
良好的用户界面更是吸引用户的硬实力,为此必须要加入坦克爆炸的效果图以及游戏进行时的音效。
7.用户运行游戏时需要有分数记录的可能。
如何采用合理的记分标准,需要进行适当的设计。
记录分数的存储方式也需要有较好的解决方案,可以利用IO流编程来实现将数据存入电脑硬盘中的某个文件中。
1.2程序流程
本程序采用面向对象的设计模式,对游戏中的所有物体赋予对象的概念和属性。
运行程序后允许用户选择执行选项菜单,在开始游戏后将先对背景的所有物体进行绘图。
在主程序运行的线程中,画面刷新将以一定的频率采用双缓冲技术对屏幕重绘,实时反映整个游戏的进行状态。
用户控制的坦克运行在主线程中,敌方坦克将在游戏开始时逐渐新增线程,每增加一个敌方坦克对象就新增加一条线程,一旦线程数满到最大值(本程序暂设置为20),就不允许敌人再继续出现。
用户坦克自诞生之时起将拥有5发子弹的权利,子弹虽然开在单独的线程中,但运行结束后(比如撞到相关物体或敌方坦克时)并不结束子弹对象,只是将其线程终止。
用户再次发射子弹时只是将终止的线程再次激活。
在屏幕重绘的主程序中,将在每次的循环中判断若干事件。
如:
用户坦克的生命是否为0,敌方坦克数是否已经为零,屏幕上的坦克数量是否少于仍剩下的坦克数量等。
以便程序进入相关的分支执行相关的反应代码,结束游戏或统计分数等。
主程序流程如图所示:
Logo画面
游戏选项
主程序
屏幕绘图
本关记分统计
显示
结束
显示历史记分表
敌方需要出坦克时,生成坦克
初始化参数
死亡时
符合结束条件时
1.3绘图与事件监听以及线程技术和IO流编程
1.3.1Graphics类
Graphics类是所有图形上下文的抽象基类,允许应用程序可以在组件(已经在各种设备上实现),以及闭屏图像上,进行绘制。
用fill3DRect画出矩形,fillOval画出圆,drawLine画出线,三个矩形,一个圆及一条线就可以构成一个坦克,如图:
1.3.2KeyListener监听机制
要想使坦克动起来,子弹运动起来,以及菜单模式下的各种功能能够控制坦克大战游戏的运行,比如继续游戏(continueGame),保存游戏并退出(saveExit),退出游戏(exit)以及开始新游戏(newgame)必须注册监听机制,例如程序如下:
jm1.setMnemonic('G');
jmil=newJMenuItem("开始新游戏(N)");
jmi2=newJMenuItem("退出游戏(E)");
jmi3=newJMenuItem("存盘退出游戏(C)");
jmi4=newJMenuItem("继续上局游戏(S)");
//注册监听
jmi4.addActionListener(this);
jmi4.setActionCommand("continueGame");
//注册监听
jmi3.addActionListener(this);
jmi3.setActionCommand("saveExit");
jmi2.addActionListener(this);
jmi2.setActionCommand("exit");
jmi2.setMnemonic('E');
//对jmil相应
jmil.addActionListener(this);
jmil.setActionCommand("newgame");
1.3.3runnable实现线程
Java界曾流行这样一句话:
不懂线程就不要说自己会Java,可见线程对Java的重要性是多么的大。
那么线程的作用有哪些呢,最为典型的就是你在网络上放一个服务端,一个客户端访问时,就会新建一个线程处理这个客户端的事务,这样的话只要不断新建线程就可以处理多个用户的请求了。
当然我们的这个坦克大战游戏的实现肯定离不开线程,例如己方坦克是必须要会移动的,那么敌人坦克也要移动,子弹呢?
当然也要会移动,等等…。
那么这么多的功能要实现就要用到线程了。
1.3.4io流编程实现菜单功能
IO包括输入和输出流,输入流指的是将数据以字符或字节形式从外部媒介比如文件、数据库等读取到内存中所以也分为字符输入流和字节输入流。
输出流指的是将内存中的数据写入外部媒介,也分为了字符输出流和字节输出流。
我们的坦克大战游戏就是利用IO流来记录玩家的分数,成绩的。
程序如下:
//把玩家击毁敌人坦克数量保存到文件中
publicstaticvoidkeepRecording()
{
try{
//创建
fw=newFileWriter("d:
\\myRecording.txt");
bw=newBufferedWriter(fw);
bw.write(allEnNum+"\r\n");
}catch(Exceptione){
e.printStackTrace();
//TODO:
handleexception
}finally{
//关闭流
try{
//后开先关闭
bw.close();
fw.close();
}catch(Exceptione){
e.printStackTrace();
//TODO:
handleexception
}
}
}
第二章游戏的设计思路
2.1画出坦克
坦克大战游戏中坦克当然得分两类,自己的坦克和敌人的坦克,在游戏中我们就将两类坦克分成两种颜色,以示区分。
当然坦克画在面板中肯定不能自己变化方向,所以就需要画出四个方向的坦克,程序如下:
//画出坦克的函数(扩展)
publicvoiddrawTank(intx,inty,Graphicsg,intdirect,inttype)
{
//判断是什么类型的坦克
switch(type)
{
case0:
g.setColor(Color.cyan);
break;
case1:
g.setColor(Color.yellow);
break;
}
//判断方向
switch(direct)
{
//向上
case0:
//画出我的坦克(到时再封装成一个函数)
//1.画出左边的矩形
g.fill3DRect(x,y,5,30,false);
//2.画出右边矩形
g.fill3DRect(x+15,y,5,30,false);
//3.画出中间矩形
g.fill3DRect(x+5,y+5,10,20,false);
//4.画出圆形
g.fillOval(x+5,y+10,10,10);
//5.画出线
g.drawLine(x+10,y+15,x+10,y);
break;
case1:
//炮筒向右
//画出上面矩形
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;
case2:
//向下
//画出我的坦克(到时再封装成一个函数)
//1.画出左边的矩形
g.fill3DRect(x,y,5,30,false);
//2.画出右边矩形
g.fill3DRect(x+15,y,5,30,false);
//3.画出中间矩形
g.fill3DRect(x+5,y+5,10,20,false);
//4.画出圆形
g.fillOval(x+5,y+10,10,10);
//5.画出线
g.drawLine(x+10,y+15,x+10,y+30);
break;
case3:
//向左
//画出上面矩形
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;
}
}
2.2坦克的控制和敌方的智能运行
坦克分为两种,己方坦克和敌方坦克。
己方坦克在玩家的控制下运行,敌方坦克随机运行。
敌方坦克由于需要具有一定的智能性,以便对玩家攻击,使之具有一定的可玩性。
所以在程序中我们试用random函数来控制敌方坦克的方向,给出0123四个数字,0代表向上运动,1代表右,2代表下,3代表左。
并且敌人可以自动行走自如,但是应当在以下适当的情况下转向:
第一是坦克是否超出界面的边界,第二是坦克是否与地图障碍物发生了碰撞,第三是坦克是否与用户坦克发生了碰撞。
需要指出的是,当发生阻碍不能在不变方向的情况下继续行走时,并不一定立即需要采取转向的对策。
如果一定发生转向,试想,当敌方碰到玩家时,如果它立即转向,将不会对玩家发射射向他的子弹,就不构成任何威胁,当然,也不能永远不转向。
所以本次程序是这样安排的:
当碰撞到障碍物或边界时立即转向,但碰到玩家坦克时需要有一个等待的时间,这个时间由碰撞前随机取得的在某方向上的持续行走步数决定(程序规定坦克走一定的路程后必须转向其他方向,不然就不一直按照之前的方向一直走下去),当发生坦克间碰撞时,此随机数将在下一次循环前减少为原来的2/3,这样就实现了加快转向的时间,避免死锁在一个方向上静止的停留过长的时间。
另外,坦克的转后具体方向都由随机数决定。
为了防止坦克运动过程中出现互相重叠的事情出现,我们必须对坦克的坐标进行判断,坦克与坦克之间的坐标以及边界互相不能侵犯,但是如果某坦克正从上方生成而正好有另一辆阻碍在该地方生成,这将导致不可避免的重叠。
这是允许的,但需要对他们标注状态,即当坦克刚出现时暂时允许重合,一旦在某个时间他们脱离了重合状态,就不能在允许重合,如果不设置这样的判断,刚出现的坦克将会因为受到阻塞而永远不能前进,坦克将混成一团。
本次程序中并未使用过多复杂的人工智能算法,如有时间,将可能再此方面加以完善。
具体实现程序如下:
1:
//键按下处理a表示向左s表示下w表示向上d表示右
publicvoidkeyPressed(KeyEventarg0){
//TODOAuto-generatedmethodstub
if(arg0.getKeyCode()==KeyEvent.VK_W)
{
//设置我的坦克的方向
this.hero.setDirect(0);
this.hero.moveUp();
}elseif(arg0.getKeyCode()==KeyEvent.VK_D)
{
//向右
this.hero.setDirect
(1);
this.hero.moveRight();
}elseif(arg0.getKeyCode()==KeyEvent.VK_S)
{
//向下
this.hero.setDirect
(2);
this.hero.moveDown();
}elseif(arg0.getKeyCode()==KeyEvent.VK_A)
{
//向左
this.hero.setDirect(3);
this.hero.moveLeft();
}
2:
classTank
{
//表示坦克的横坐标
intx=0;
//坦克纵坐标
inty=0;
//坦克方向
//0表示上1表示右2表示下3表示左
intdirect=0;
intcolor;
booleanisLive=true;
//坦克的速度
intspeed=1;
publicTank(intx,inty)
{
this.x=x;
this.y=y;
}
publicintgetX(){
returnx;
}
publicvoidsetX(intx){
this.x=x;
}
publicintgetY(){
returny;
}
publicvoidsetY(inty){
this.y=y;
}
publicintgetDirect(){
returndirect;
}
publicvoidsetDirect(intdirect){
this.direct=direct;
}
publicintgetSpeed(){
returnspeed;
}
publicvoidsetSpeed(intspeed){
this.speed=speed;
}
publicintgetColor(){
returncolor;
}
publicvoidsetColor(intcolor){
this.color=color;
}
}
3:
//判断是否碰到了别的敌人坦克
publicbooleanisTouchOtherEnemy()
{
booleanb=false;
switch(this.direct)
{
case0:
//我的坦克向上
//取出所有的敌人坦克
for(inti=0;i { //取出第一个坦克 EnemyTanket=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) { returntrue; } if(this.x+20>=et.x&&this.x+20<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) { returntrue; } } if(et.direct==3||et.direct==1) { if(this.x>=et.x&&this.x<=et.x+30&&this.y>=et.y&&this.y<=et.y+20) { returntrue; } if(this.x+20>=et.x&&this.x+20<=et.x+30&&this.y>=et.y&&this.y<=et.y+20) { returntrue; } } } } break; case1: //坦克向右 //取出所有的敌人坦克 for(inti=0;i { //取出第一个坦克 EnemyTanket=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) { returntrue; } //下点 if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y+20>=et.y&&this.y+20<=et.y+30) { returntrue; } } if(et.direct==3||et.direct==1) { if(this.x+30>=et.x&&this.x+30<=et.x+30&&this.y>=et.y&&this.y<=et.y+20) { returntrue; } if(this.x+30>=et.x&&this.x+30<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) { returntrue; } } } } break; case2: //坦克向下 //取出所有的敌人坦克 for(inti=0;i { //取出第一个坦克 EnemyTanket=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) { returntrue; } //我的右点 if(this.x+20>=et.x&&this.x+20<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30) { returntrue; } } if(et.direct==3||et.direct==1) { if(this.x>=et.x&&this.x<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+20) {
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 毕业设计 论文 基于 Java 坦克 大战 软件 程序设计