基于java坦克大战课程设计报告
摘 要
随着计算机的普及以及对电子游戏的认识,电子游戏已被越来越多的人选作放松、娱乐的休闲方式;电子游戏既不需要专门购买游戏器材,也不需要宽阔的游戏场地,只需要一台能独立完成任务的计算机即可,它可以是人们工作、学习时用的计算机,并不需要另行配置,这比起传统休闲游戏即省钱又省事。局域网游戏更是可以将现实空间中零散的计算机,组织起来,使其在逻辑空间中集中起来,使游戏的组织、开展变得轻松。如此轻松而又安逸的休闲方式,使得越来越多的人尝试,甚至已经将电子游戏作为主要休闲方式,既然有如此多的人使用,那其中必然存在巨大的商机,即使人们不愿意为一个小小的休闲游戏花费金钱,但在游戏中添加广告、游戏相关服务也包藏了巨大的财富;当然电子游戏的制作如今已是空前的火爆,大大小小的游戏公司横空出世,都想在电子游戏制作这个行业里占据一席之地,而一款成功的电子游戏需要精心的策划、分析、设计,只有这样才能获得游戏中包藏的财富,以及做出一款真正能够让玩家娱乐、放松的游戏,而不是骗取玩家钱财的工具。
关键字: 局域网;电子游戏;坦克大战;
目 录
- 1 -
一、 系统分析
- 1 -
可行性分析
- 1 -
需求分析
- 2 -
二、 概要设计
- 2 -
工作流程图
- 3 -
项目规划
- 3 -
开发及运行环境
- 4 -
三、 详细设计与算法实现
- 4 -
游戏主窗口
- 6 -
网络管理
- 8 -
封装的游戏元素
- 10 -
四、 测试
- 10 -
测试环境
- 10 -
测试结果
- 11 -
五、 软件截图
- 14 -
六、
- 15 -
七、 参考文献
1、 系统分析
可行性分析
技术可行性
软件使用swing、GUI、Socket、面向对象设计等技术实现,这些技术均已是非常成熟的技术,之前已有相当多使用这些技术的成功案例,故现使用这些技术是可行的。
经济可行性
本软件为免费软件,将免费提供软件的下载、运行和维护服务,软件暂无收入,待公布之后随着使用者越来越多,将添加相应的广告、服务,从而增加收入,若使用者寥寥无几,将再次分析是否重新策划软件或者放弃开发,以减少损失。
需求分析
通过反复研究以及市场调查,得知游戏须具有以下功能:
· 需要有图形游戏界面,让用户能看到游戏给出的反馈
· 有人机交互功能,使用户能操作指定的游戏元素
· 不同队伍的坦克,须显示不同外观,已分辨敌我
· 坦克能够开火,攻击敌方,但不能攻击队友
· 需要有不可被子弹穿透的墙,且墙有可摧毁和不可摧毁两种
· 坦克有生命值,并非被击中一次就会爆炸
· 坦克爆炸后将产生道具,拾到道具的坦克可加满生命值
· 游戏须提供网络支持,即局域网联网对战
· 玩家在游戏中可以发言,即群聊功能
· 须在玩家之间设立房主,掌管游戏何时开始
· 游戏结束时须判断哪一队胜利
· 游戏结束后可重新开始
· 游戏的操作、进度等须提供相应说明,以告知玩家
2、 概要设计
工作流程图
项目规划
本游戏是一个典型的局域网对战游戏,应具有如下结构:
· 游戏主窗口
游戏的一切效果、进度、消息等都将由游戏主窗口展示
· 网络管理
负责发送、接收网络数据,以及如何处理这些数据
· 封装的游戏元素
游戏元素包括:坦克、子弹、爆炸效果、墙、道具等游戏必须的元素
开发及运行环境
开发时硬件环境
· CPU:Inter P7350
· 显卡:NVIDIA GeForce 9600M GS
· 内存:威刚2G/DDR2-667
· 显示器:三星液晶15.4寸/分辨率:1280X800
开发时软件环境
· 操作系统:Windows7
· JDK:1.5.0
· IDE:Eclipse3.4.0
运行时硬件环境
· CPU:Inter E5200
· 显卡:NVIDIA GeForce 7300 GS
· 内存:金士顿2G/DDR2-667
运行时软件环境
· 操作系统:Windows Xp
· JRE:1.6.0
· 显示器:三星液晶19寸/分辨率:1440X900
3、 详细设计与算法实现
游戏主窗口
游戏主窗口是人机交互的窗口,对玩家而言,他们只和游戏主窗口打交道,并不关心游戏内部是如何实现的,所以游戏主窗口部分最重要的便是游戏数据的输入、输出。
在程序中须创建一个类TankClient,继承自Frame来创建一个窗口。
游戏数据的输入
游戏中坦克需要能往上、下、左、右四个方向运动,故须设立4个按键,使其能操作坦克,另须设一个键控制坦克开火。为方便操作,本游戏设置WSAD分别
示上下左右,小键盘数字键4,表示开火。
具体实现为,为窗口添加KeyListener(键盘监听器),监听键盘的按下和抬起。在TankClient类中添加内部的适配器类,由于不需要其它类访问,将其设计为private的,以保证面向对象设计的封装性。
代码如下:
/*
* 移动按键键盘监听器
*/
private class MoveKeyL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_A:
myTank.keyDownToDir(Direction.L);
break;
case KeyEvent.VK_W:
myTank.keyDownToDir(Direction.U);
break;
case KeyEvent.VK_D:
myTank.keyDownToDir(Direction.R);
break;
case KeyEvent.VK_S:
myTank.keyDownToDir(Direction.D);
break;
}
}
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_A:
myTank.keyUpToDir(Direction.L);
break;
case KeyEvent.VK_W:
myTank.keyUpToDir(Direction.U);
break;
case KeyEvent.VK_D:
myTank.keyUpToDir(Direction.R);
break;
case KeyEvent.VK_S:
myTank.keyUpToDir(Direction.D);
break;
}
}
}
/*
* 开火按键键盘监听器
*/
private class FireKeyL extends KeyAdapter {
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_NUMPAD4:
myTank.fire();
new TankFireMsg().send();
break;
}
}
}
游戏数据的输出
玩家需要从游戏输出数据中获得游戏信息,如坦克在往上行驶、坦克发了颗子弹、坦克爆炸等,这些均需要通过游戏数据的输出来告知玩家。
由于TankClient继承自Frame,Frame类中的方法paint,可以在窗口中绘制图形,即满足了游戏需要图形界面的需求;另有方法repaint可以刷新窗口,以及时提供游戏信息,故须创建线程,不断地刷新窗口,来获取最新的游戏信息。
代码如下:
public void paint(Graphice g) {
for (int i = 0; i < allGE.size(); i++) {
int allGEOldSize = allGE.size();
GameElement ge = allGE.get(i);
if (ge instanceof Moveable) {
Moveable moveable = (Moveable) ge;
moveable.move();
}
ge.draw(g);
/*
* 如果容器数量减少,则减少相应的遍历索引i
*/
if (0 < allGEOldSize - allGE.size()) {
i -= allGEOldSize - allGE.size();
}
}
/*
* 刷屏线程,负责画面的刷新以及游戏时间的推进
*/
private class MyTh implements Runnable {
public void run() {
while (true) {
repaint();
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
为使游戏主窗口效率更高、更容易被引用,且游戏主窗口只有一个,故TankClient类使用单例模式来设计:
private static final TankClient tc = new TankClient();
private TankClient() {
...
}
public static TankClient getTc() {
return tc;
}
网络管理
游戏需要对局域网对战的支持,所以需要对网络数据进行管理,使游戏能有条不紊地运行,网络管理部分主要负责输入游戏数据后发往其它游戏客户端,以及接收其它客户端发来的游戏数据。需要发送的游戏数据有:坦克创建消息(TankCreateMsg)、坦克开火消息(TankFireMsg)等
客户端游戏数据的收发
由于每个游戏消息都有共同的特性,即发送、接受,故将其抽象出一个父类Msg,所有的消息类都继承自Msg类。
public abstract class Msg {
public static final TankClient tc = TankClient.getTc();
public static final int TANK_CREATE_MSG = 1;
public static final int TANK_CHANGEDIR_MSG = 2;
public static final int TANK_CALIBRATION_MSG = 3;
public static final int TANK_FIRE_MSG = 4;
public static final int CHAT_WORD_MSG = 5;
public static final int TANK_READY_MSG = 6;
public static final int GAME_START_MSG = 7;
public static final int GAME_OVER_MSG = 8;
public static final int GAME_EXIT_MSG = 9;
public static final int GAME_CHANGEMASTER_MSG = 10;
public abstract void send();
public abstract void receive(DataInputStream dis);
}
在需要向每个游戏客户端发送游戏消息时只需实例化一个相应的对象,在调用send方法即可,接收时调用receive方法。
服务器端游戏数据的收发
服务器端的设计,只需将所有接收到的包转发给所有游戏客户端即可。
接收:
public class UDPThread implements Runnable {
public void run() {
byte[] buf = new byte[1024];
DatagramSocket ds = null;
try {
ds = new DatagramSocket(ServerMain.SERVER_UDP_PORT);
} catch (SocketException e) {
e.printStackTrace();
}
while(true){
DatagramPacket dp = new DatagramPacket(buf, buf.length);
try {
ds.receive(dp);
ServerMain.sendToEveryone(ds, dp);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转发:
public static void sendToEveryone(DatagramSocket ds, DatagramPacket dp){
for (int i = 0; i < ServerMain.clients.size(); i++) {
try {
Client c = ServerMain.clients.get(i);
String IP = c.IP;
int port = c.udpPort;
dp.setSocketAddress(new InetSocketAddress(IP, port));
ds.send(dp);
} catch (IOException e) {
e.printStackTrace();
}
}
}
封装的游戏元素
将游戏元素(坦克、子弹、墙等)封装成一个一个的类,将大大地降低游戏设计、实现难度,且符合面向对象的设计方法。
由于这些游戏元素都有一些相同的属性、方法,故将其抽象为父类GameElement。
public abstract class GameElement {
/**
* 持有游戏主窗口的引用
*/
public static final TankClient tc = TankClient.getTc();
/**
* 元素的坐标
*/
public Rectangle rect;
/**
* 元素的类型(队伍)
*/
public GameElementKind kind = GameElementKind.DEMON;
/**
* 由游戏主窗口自动调用,将决定该元素的在游戏中的表现形式
*/
public abstract void draw(Graphics g);
}
程序中共有如下游戏元素:
· Blast:爆炸效果
· Bullet:子弹
· ChatWord:群聊的内容
· Tank:坦克
· Wall:墙
4、 测试
测试环境
测试时硬件环境
· CPU:Inter E5200
· 显卡:NVIDIA GeForce 7300 GS
· 内存:金士顿2G/DDR2-667
测试时软件环境
· 操作系统:Windows Xp
· JRE:1.6.0
· 显示器:三星液晶19寸/分辨率:1440X900
测试结果
在以上软硬件环境中测试,已通过6人互联测试,游戏过程正常,满足软件的功能需求,结果正确无误。
发现的BUG及不足
1. 由于没有添加操作说明,使玩家不知如何操作,大大地影响了游戏的可操作性。
2. 在测试环境测试时,出现画面抖动现象,严重地影响了游戏的进行,必须找到原因并改正。
解决方法
1. 在程序启动时告知玩家游戏该如何操作,使玩家能清楚、正确地开始游戏。
2. 经过反复测试、论证,得知画面抖动现象原因为测试环境JRE安装问
,在重新安装JRE后,游戏画面恢复正常。
5、 软件截图
6、 总结
该游戏定位在小型局域网休闲游戏,是一款免费、绿色、开源的一款软件。
本软件是使用JAVA开发的局域网对战游戏,其不仅实现了基本的功能需求,而且设计灵活、拓展方便、界面生动,多处使用了各种设计模式,是程序的编写效率更高,运行效率更高。由于程序中多数是面向父类或者面向接口的编程,以后如果要更换某些模块、元素的功能,以及添加功能,是非常容易的。现在软件还无收入,但随着玩家的逐渐增多,随时可以利用本软件优良的可拓展性,添加相关内容,从而开始盈利;即便本游戏未得到玩家的喜爱,而需要再次设计游戏或者另行开发新游戏,其内部使用的各个模块、封装的游戏元素,均可以复用,这也是本软件优良的可重用性的体现。
7、 参考文献
· JAVA开发实战宝典--------编著:李钟蔚
出版社:清华大学出版社
· JAVA面向对象编程--------编著:孙卫琴
出版社:电子工业出版社
程序开始
连接服务器
连接成功?
Y
N
新线程
刷屏(间接调用paint)
延迟25ms
初始化游戏元素
根据游戏元素的属性,对其经行操作和绘出其图形
Paint方法
战斗结束?
Y
键盘监听器
判断按下的是那个键
改变相应游戏元素的属性
- 1 -