if(hitTank(tanks.get(i))){
//对每一个坦克,调用hitTank
returntrue;
}
}
returnfalse;
}
子弹打到其他坦克上时用hitTank(Tankt)方法,子弹打到墙上时hitWall(CommonWallw)方法,打到金属墙上hitWall(MetalWallw),打到家hitHome(),当然在这些方法里,都要作相应的操作来表示接受到子弹的后果,:
还有,当子弹射击到对方(用户方对敌方)时,当敌方射击到用户方,用户方要减少生命值,没接受一枪,就执行
t.setLife(t.getLife()-50);//受一粒子弹寿命减少50
接受4枪就死,总生命值200,当然方法里面还要做其他很多的判断,如生命值是否小于0,如果是的话就执行t.setLive(false);从而结束游戏。
坦克的爆炸效果独立出来用一个类来描述,爆炸的属性:
位置和存活状态,另外,画爆炸效果的时候要取得用户界面控制,所以要定义privatestaticToolkittk=Toolkit.getDefaultToolkit();其他的方法只能的大同小异。
菜单功能包括游戏的重新开始,暂停,退出等。
这些功能的用户界面放在了MyPanel的构造方法里,用到的是面板类和相应的监听功能,实现出来很简单。
3.2主要方法和变量
属性
intFram_width
游戏用户界面的全局静态变量宽度,初始化为600
intFram_length
游戏用户界面的全局静态变量长度,初始化为500
voidupdate(Graphicsg)
图形用户界面的更新方法
voidframPaint(Graphicsg)
画图形用户界面的方法,需要重画的界面元素都在这个方法里面
voidactionPerformed(ActionEvente)
监听菜单项的方法
staticvoidmain(String[]args)
主函数,启动整个程序
用户类主要是综合调用各个类来协作完成游戏的设计。
2.3游戏主窗口
游戏主窗口是人机交互的窗口,对玩家而言,他们只和游戏主窗口打交道,并不关心游戏内部是如何实现的,所以游戏主窗口部分最重要的便是游戏数据的输入、输出。
在程序中须创建一个类,继承自Frame来创建一个窗口。
2.3.1游戏数据的输入
游戏中坦克需要能往上、下、左、右四个方向运动,故须设立4个按键,使其能操作坦克,另须设一个键控制坦克开火。
为方便操作,本游戏设置WSAD分别表示上下左右,小键盘数字键4,表示开火。
具体实现为,为窗口添加KeyListener(键盘监听器),监听键盘的按下和抬起。
在类中添加内部的适配器类,由于不需要其它类访问,将其设计为private的,以保证面向对象设计的封装性。
2.3.2游戏数据的输出
玩家需要从游戏输出数据中获得游戏信息,如坦克在往上行驶、坦克发了颗子弹、坦克爆炸等,这些均需要通过游戏数据的输出来告知玩家。
由于继承自Frame,Frame类中的方法paint,可以在窗口中绘制图形,即满足了游戏需要图形界面的需求;另有方法repaint可以刷新窗口,以及时提供游戏信息,故须创建线程,不断地刷新窗口,来获取最新的游戏信息。
四.系统的功能测试与调整
4.1菜单项测试
菜单项可以选择开始新游戏,退出,暂停,继续,储存游戏记录,帮助功能,对于开始新游戏,退出两个功能,要给出提示,用户是否真的想继续操作!
菜单效果图:
4.2游戏运行测试
4.3坦克爆炸测试
4.4保存游戏信息设置
4.5帮助功能测试
五.设计体会与小结
本软件是使用java开发的小型游戏,其不仅实现了基本的功能需求,而且涉及到了java程序的编写的各个知识点,如事件监听、多线程、异常处理、数组、向量。
图形界面等,所创建的每一个类都体现了java面向对象编程的特点,为以后的网络编程等java的高级运用打下了基础。
由于本软件拓展方便、界面生动,多处使用了各种设计模式,是程序的编写效率更高,运行效率更高。
由于程序中多数是面向父类或者面向接口的编程,以后如果要更换某些模块、元素的功能,以及添加功能,是非常容易的。
六.附录
程序代码:
packagecome.test9;
/*
*1.坦克大战
*2.坦克可以上下左右移动
*3.坦克可以发子弹(可以连发)
*4.我的坦克击中敌人坦克时,敌人就消失(显示爆炸效果)
*5.我被击中后显示爆炸效果
*6.防止敌人坦克重叠运动
*7.玩游戏时可以暂停和继续
*8.可以分关
*9.记录玩家的成绩
importjava.awt.*;
importjava.io.*;
importjavax.imageio.ImageIO;
importjavax.swing.*;
importcome.test9.Help;
importcome.test9.Shot;
importcome.test9.EnemyTank;
importcome.test9.Recorder;
importcome.test9.MyPanel;
importcome.test9.MyTank;
importcome.test9.ReSuccess;
importjava.awt.event.*;
importjava.util.*;
publicclassTankGameextendsJFrameimplementsActionListener{
MyPanelmp=null;
//定义一个开始面板
MyStartPanelmsp=null;
//做出我需要的菜单
JMenuBarjmb=null;
//开始游戏
JMenujm1=null;
JMenujm2=null;
JMenuItemjmi1=null;
JMenuItemjmi2=null;
JMenuItemjmi3=null;
JMenuItemjmi4=null;
JMenuItemjmi5=null;
JMenuItemjmi21=null;
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
TankGamed2=newTankGame();
}
//构造函数
publicTankGame(){
jmb=newJMenuBar();
jm1=newJMenu("游戏(G)");
//设置快捷键
jm1.setMnemonic('G');
//设置菜单选项
jmi1=newJMenuItem("新游戏(N)");
jmi1.setMnemonic('N');
jmi2=newJMenuItem("暂停(S)");
jmi2.setMnemonic('s');
jmi3=newJMenuItem("继续(C)");
jmi3.setMnemonic('c');
jmi4=newJMenuItem("储存游戏记录(Q)");
jmi4.setMnemonic('q');
jmi5=newJMenuItem("退出游戏(E)");
jmi5.setMnemonic('E');
//对jmi1响应
jmi1.addActionListener(this);
jmi1.setActionCommand("newgame");
//对jmi2响应
jmi2.addActionListener(this);
jmi2.setActionCommand("suspend");
//对jmi3响应
jmi3.addActionListener(this);
jmi3.setActionCommand("continue");
//对jmi4响应
jmi4.addActionListener(this);
jmi4.setActionCommand("save");
//对jmi5响应
jmi5.setActionCommand("exit");
jmi5.addActionListener(this);
jm2=newJMenu("帮助(H)");
jm2.setMnemonic('h');
jmi21=newJMenuItem("操作说明(U)");
jmi21.setMnemonic('u');
jmi21.addActionListener(this);
jmi21.setActionCommand("help");
this.setJMenuBar(jmb);
jmb.add(jm1);
jmb.add(jm2);
jm1.add(jmi1);
jm1.add(jmi2);
jm1.add(jmi3);
jm1.add(jmi4);
jm1.add(jmi5);
jm2.add(jmi21);
msp=newMyStartPanel();
//启动msp的线程
Threadt=newThread(msp);
t.start();
this.add(msp);
this.setSize(600,500);
setResizable(false);
setTitle("坦克大战");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
publicvoidactionPerformed(ActionEvente){
//对用户不同的点击做不同的处理
if(e.getActionCommand().equals("newgame")){
if(this.mp!
=null){this.remove(mp);
}
//创建战场面板
mp=newMyPanel("newgame");
//启动面板的线程
Threadt=newThread(mp);
//先删除旧的面板
this.remove(msp);
t.start();
this.add(mp);
//注册监听
this.addKeyListener(mp);
Recorder.setEnSize(5);
Recorder.setMyLife
(1);
Recorder.setAllEnemy(0);
//要显示战斗场面先要移除开始画面
this.remove(msp);
//显示刷新JFrame
this.setVisible(true);
}//战斗暂停
elseif(e.getActionCommand().equals("suspend"))
{
//让子弹和坦克的速度变为0
MyTank.setSpeed(0);
EnemyTank.setSpeed(0);
Shot.setSpeed(0);
//让坦克不能改变方向
EnemyTank.setTingzhi(true);
MyTank.setMytingzhi(true);
EnemyTank.setStrar(false);
MyTank.setStrar(false);}
/战斗重新开始
elseif(e.getActionCommand().equals("continue"))
{
//恢复子弹和坦克的速度
MyTank.setSpeed(3);
EnemyTank.setSpeed
(1);
Shot.setSpeed(3);
EnemyTank.setStrar(true);
MyTank.setStrar(true);}
/储存游戏
elseif(e.getActionCommand().equals("save"))
{
//调用保存游戏函数
Recorder.saveRecording();
//跳出保存成功窗口
ReSuccessre=newReSuccess();
}
elseif(e.getActionCommand().equals("exit")){
//用户点击了退出游戏菜单
//保存击毁敌人数量
Recorder.saveRecording();
System.exit(0);
}
//帮助
elseif(e.getActionCommand().equals("help"))
{Helph=newHelp();
}}}
//开始面板
classMyStartPanelextendsJPanelimplementsRunnable{
inttimes=0;
publicvoidpaint(Graphicsg){
super.paint(g);
g.fill3DRect(0,0,440,360,false);
if(times%2==0){
//提示信息
g.setColor(Color.yellow);
FontmyFont=newFont("华文新魏",Font.BOLD,50);
g.setFont(myFont);
g.drawString("第一关",140,140);}
}
@Override
publicvoidrun(){
while(true){
//休眠
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
times++;
//重画
this.repaint();
}}}
//我的面板
classMyPanelextendsJPanelimplementsKeyListener,Runnable{
Stringflag;
//定义一个我的坦克
MyTankmytank=null;
//定义敌人的坦克组
Vectorets=newVector();
//定义炸弹集合
Vectorbombs=newVector();
intenSize=5;
//定义三张图片,组成一颗炸弹
Imageimage1=null;
Imageimage2=null;
Imageima