单机版坦克大战游戏系统
—详细设计
目录
1.引言………………………………………………………………………………………2
1.1 编写目的…………………………………………………………………………2
1.2 项目背景…………………………………………………………………………2
1.3 定义………………………………………………………………………………2
1.4 参考资料…………………………………………………………………………2
2.总体设计…………………………………………………………………………………3
2.1 需求概述…………………………………………………………………………3
3.程序描述…………………………………………………………………………………4
3.1 程序逻辑…………………………………………………………………………4
3.1.1 主类模块…………………………………………………………………4
3.1.2 坦克类模块………………………………………………………………4
3.1.3 子弹类模块………………………………………………………………12
3.1.4 爆炸类模块………………………………………………………………14
3.1.5 墙类模块…………………………………………………………………16
3.1.6 血块类模块………………………………………………………………16
3.3 存储分配………………………………………………………………………17
3.4 限制条件………………………………………………………………………18
3.5 测试要点………………………………………………………………………18
- 1 -
1.引言
随着社会的进步,现在人们工作的压力越来越大,休息的时候很少,为了让疲惫的
心灵得以休息,开发了坦克大战的小游戏来让玩家轻松一会,该游戏操作十分简单,只
要操作键盘上的方向键按住攻击键就可以玩该游戏,轻松享受玩游戏的喜悦,可操作性
好,而且不会使玩家沉溺于该游戏,对玩家的学习和工作都起积极的作用。
1.1 编写目的
为明确软件需求、安排项目规划与进度、组织软件开发与测试,撰写本文档。
本文档供项目经理、设计人员、开发人员参考。
1.2 项目背景
a. 项目名称:坦克大战游戏开发
b. 产品用户:对该游戏感兴趣的玩家
c. 项目和系统的关系:本项目旨在编写出一个操作简单但可玩性良好的小游戏来让玩
家放松一下心情,对系统硬件配置要求低。实现简单。
1.3 定义
持有对方的引用:在一个类里面有一个成员变量是另一个类的对象,这个对象相对
于这个类来说就是持有了另一个类的引用,通过这个对象作成员变量可以引用对象这个
类的成员变量和成员方法。
内部类:写在一个类内部的类是内部类,内部类封装在类的内部,不能被其他的外
部类直接访问,起到保护作用,但要写的简短。
1.4 参考资料
《Java 基础知识详解》
《Java 游戏开发》等。
- 2 -
2.总体设计
2.1 需求概述
游戏包括的范围:本游戏包括主类、坦克类、子弹类、爆炸类、墙类、血块类。
要求游戏能有效、快速、安全、可靠和无误的完成上述操作。并要求客户端
的界面要简单明了、易于操作,服务器程序利于维护。
需求
产生游戏的屏幕
将坦克大战的过程呈现在屏幕上
画出坦克
控制坦克的移动并让坦克可以攻
模块
主类模块
击
坦克类模块
让坦克不可以穿越墙或别的坦克
添加坦克的图片
画出子弹
控制子弹的移动
详细查看员工信息
让子弹不可以穿墙
添加子弹的图片
添加培训信息
画出爆炸的过程
控制坦克的爆炸
添加爆炸的图片
画出墙
实现墙的功能
画出血块
子弹类模块
爆炸类模块
墙类模块
让血块围绕着固定的轨迹移动
血块类模块
实现血块的功能
- 3 -
3.程序描述
3.1 程序逻辑
3.1.1 主类模块
主类是要画出屏幕,并且要将坦克之间打斗的全过程都呈现出来的,所以要先产生一个
窗口,窗口产生之后应该要不停的刷新,否则屏幕会定格成画面,用多线程来控制刷新的频
率,如果此时屏幕出现闪屏现象,应该用双缓冲机制来画出屏幕。双缓冲机制是通过虚拟出
一张图片,将屏幕画在这张虚拟的图片上,再将这张虚拟的图片呈现在屏幕上。
调用的方法如下:
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=this.createImage(GAME_WIDTH,GAME_HEIGHT);
}
Graphics gOffScreen=offScreenImage.getGraphics();
Color c=gOffScreen.getColor();
gOffScreen.setColor(Color.GREEN);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage,0,0,null);
}
用多线程来控制屏幕刷新的频率的方法如下:
private class PaintThread implements Runnable{
public void run(){
while(true){
try {
repaint();
Thread.sleep((int)Math.random()*200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
控制其他模块的操作都是在主类中调用其他类的方法即可。
3.1.2 坦克类模块
该类实现在屏幕上画出坦克,并控制坦克的移动,让坦克可以发射炮弹打对方等功能。
- 4 -
画出坦克的方法如下:
public void draw(Graphics g){
Color c=g.getColor();
if(good)g.setColor(Color.RED);
else g.setColor(Color.BLUE);
g.fillOval(x, y, WIDTH, HEIGHT);
g.setColor(c);
move();
switch(ptDir){
case L:
y+Tank.HEIGHT/2);
break;
case LU:
y+Tank.HEIGHT);
break;
case R:
y+Tank.HEIGHT/2);
break;
case RU:
break;
case RD:
y+Tank.HEIGHT);
break;
case U:
y);
y);
break;
case D:
y+Tank.HEIGHT);
break;
}
}
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x,
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x, y);
break;
case LD:
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x,
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH,
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH,
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH,
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2,
g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2,
- 5 -
该方法里实现了一个 move 方法,可以将坦克的移动都画出来,坦克的 move 方法如下:
public void move(){
switch(dir){
case L:
x-=XSPEED;
break;
case LU:
x-=XSPEED;
y-=YSPEED;
break;
case LD:
x-=XSPEED;
y+=XSPEED;
break;
case R:
x+=XSPEED;
break;
case RU:
x+=XSPEED;
y-=YSPEED;
break;
case RD:
x+=XSPEED;
y+=YSPEED;
break;
case U:
y-=YSPEED;
break;
case D:
y+=YSPEED;
break;
case STOP:
break;
}
}
if(dir!=Direction.STOP){
this.ptDir=dir;
if(x<0) x=0;
if(y<30) y=30;
if(x+Tank.WIDTH>tc.GAME_WIDTH)
x = tc.GAME_WIDTH-Tank.WIDTH;
if(y+Tank.HEIGHT>tc.GAME_HEIGHT) y = tc.GAME_HEIGHT-Tank.HEIGHT;
- 6 -
if(!good){
Direction[] dirs = Direction.values();
if(step==0){
step = r.nextInt(12)+3;
int rn = r.nextInt(dirs.length);
dir = dirs[rn];
}
if(r.nextInt(40)>38) fire();
step--;
}
}
这里就涉及了随机数的概念了,用随机数来控制敌军坦克在屏幕上移动的频率,让敌军坦克显得
更加的智能一些,让我军坦克无法预料敌军运动的轨迹,从而增添可玩性。
对按键的处理也是很讲究的,应该是按下某个键或抬起某个键的时候激发事件,而不应该是按下
某个键就一直激发事件,让坦克不停的移动或者开火。实现激发按键事件的代码如下:
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case KeyEvent.VK_CONTROL:
case KeyEvent.VK_LEFT:
case KeyEvent.VK_RIGHT:
fire();
break;
BL=true;
break;
BR=true;
break;
BU=true;
break;
BD=true;
break;
case KeyEvent.VK_UP:
case KeyEvent.VK_DOWN:
}
locateDirection();
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
- 7 -