数据结构课程设计报告.docx

上传人:b****6 文档编号:8562104 上传时间:2023-01-31 格式:DOCX 页数:18 大小:207.97KB
下载 相关 举报
数据结构课程设计报告.docx_第1页
第1页 / 共18页
数据结构课程设计报告.docx_第2页
第2页 / 共18页
数据结构课程设计报告.docx_第3页
第3页 / 共18页
数据结构课程设计报告.docx_第4页
第4页 / 共18页
数据结构课程设计报告.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

数据结构课程设计报告.docx

《数据结构课程设计报告.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告.docx(18页珍藏版)》请在冰豆网上搜索。

数据结构课程设计报告.docx

数据结构课程设计报告

《数据结构》课程设计报告

坦克大战游戏设计(java版)

 

组长:

组员:

指导老师:

所在学院:

电子与信息工程学院

班级:

软件工程1001班

 

目录

目录1

1.需求分析2

1.1选题的意义及背景2

1.2本组课程设计的目标2

1.3人员组成3

2.设计方案3

2.1原始数据3

2.2输出数据3

2.3对数据的处理3

2.4程序流程图4

2.5封装的数据元素5

2.6游戏的主要组成5

3.详细设计5

3.1构建游戏主类5

3.2构建坦克类Tank6

3.3添加炮弹Missile类9

3.4实现坦克的互相攻击10

3.5创建Explode类15

3.6添加障碍物16

3.7添加血块类18

4设计结果与分析19

5设计体会22

坦克大战游戏的设计与实现

摘要:

通过此次课程设计,深刻认识了单链表和顺序表的逻辑结构和存储结构,熟练掌握了线性表的存储方式和一些基本操作,如单链表和线性表的建立、求表长操作、取元素操作、按值查找、插入和删除操作等。

通过综合运用课程知识来设计一个初具规模的游戏-坦克大战。

借此熟练了数据结构以及复杂条件语句在游戏中的作用、随机函数在中型游戏中的应用、游戏中状态的概念和切换方法、游戏中速度的实现方法、覆盖和碰撞问题的实现方法、使用API函数和Buffer实现复杂的游戏图像显示以及声音和输入的处理。

该游戏设计已经实现以下功能:

坦克能力说明、地图说明、奖励物品说明、游戏操作说明、游戏技术组成、“坦克大战”游戏的创意、控件参数和窗体属性的设置、游戏代码设计等说明。

关键词:

数据结构java游戏设计函数和变量

1.需求分析

1.1选题的意义及背景

运用数据结构知识,开发一个基于J2SE的游戏-坦克大战

1.2本组课程设计的目标

培养自己综合利用数据结构进行程序设计的能力,主要是培养自己的综合编程能力。

(1)基本实现游戏图形界面,让玩家能看到游戏给出的反馈,让玩家能感受到游戏的乐趣

(2)玩家能操纵特定的游戏元素

(3)不同队伍的坦克须显示不同的外观,以分辨敌我

(4)坦克能够开火攻击敌方,但不能攻击队友

(5)需要有不可被子弹穿透的墙,且墙有可摧毁和不可摧毁两种

(6)能够模拟爆炸,实现较美观的爆炸效果

(7)坦克有生命值,并非被击中一次就会爆炸

(8)游戏中随机出现血块,可以将主战坦克的血量加满

1.3人员组成

组长:

组内成员:

2.设计方案

2.1原始数据

(1)各种坦克的图片,各种墙的图片,基地图片,爆炸的图片,草地图片,河道的图片,药剂的图片。

(2)通过键盘操作,进行游戏。

2.2输出数据

玩家需要从游戏输出数据中获得游戏信息,如坦克往上行驶,坦克发射了子弹,坦克爆炸等,这些均需要通过游戏数据的输出来告知玩家

2.3对数据的处理

本次课程设计主要运用了数据结构中的数组和链表以及向量的存储,

2.4程序流程图

TankClient类

 

2.5封装的数据元素

窗口:

主窗口TankClient

游戏元素:

子弹Missile,坦克tank,墙壁brickWall,爆炸类explode,敌人坦克enemyTank,血量Blood,方向Direction,背景音乐sound.

2.6游戏的主要组成

(1)构建游戏主类

(2)构建坦克类Tank

(3)添加炮弹Missile类

(4)实现坦克的互相攻击

(5)创建Explode类

(6)添加障碍物

(7)添加血块类

3.详细设计

3.1构建游戏主类

在主类中构建一个主Frame框架,主要代码如下:

this.setLocation(200,100);

this.setSize(Game_wide,Game_height);

this.setTitle("坦克大战");

this.addWindowListener(newWindowAdapter(){

publicvoidwindowClosing(WindowEvente){

System.exit(0);

}

});

3.2构建坦克类Tank

构建主窗口中所需的Tank类,用单链表来存储产生的每一辆坦克并将坦克加到主窗体中,

template//建立结构体定义结点

structNode

{

Udata;

Node*next;//也可以省略

};

template

LinkList:

:

LinkList()

{

first=newNode;//动态分配内存

if(first==NULL)

{

cout<<"outofmemory"<

exit(0);

}

first->next=NULL;//建立只有头结点的空链表

}

template//用尾插法建立单链表

LinkList:

:

LinkList(Ta[],intn)

{//尾插法

first=newNode;//生成头结点

Node*p=first;//尾指针初始化

for(inti=0;i

{

Node*s=newNode;//为每一个数组元素建立一个结点

s->data=a[i];

p->next=s;

p=s;//插入到终端结点之后

}

p->next=NULL;//单链表建立完毕,将终端结点的指针域置空

}

Publicvoidpaint(Graphicsg){//调用paint方法画坦克

myTank.draw(g);

}

让坦克朝八个方向运动起来,在主类TankClient中启用多线程机制,让系统不断的进行重画。

并在Tank类中建立处理按键的方法,实现坦克的手动移动;根据坦克类修改TankClient主类,在主类中注册事件监听器,并调用Tank类中的方法。

主类TankClient中使用双缓冲机制消除坦克的闪烁现象。

在Tank类当中添加的按键方法,代码如下:

publicvoidkeyPressed(KeyEvente){

intkey=e.getKeyCode();

switch(key){

caseKeyEvent.VK_LEFT:

bL=true;

break;

……

}

locateDirection();

}

publicvoidkeyReleased(KeyEvente){

intkey=e.getKeyCode();

switch(key){

caseKeyEvent.VK_LEFT:

bL=false;

break;

……

}

locateDirection();

}

TankClient类中的多线程机制的主要代码如下:

newThread(newPaintThread()).start();

……

privateclassPaintThreadimplementsRunnable{

publicvoidrun(){

while(true){

repaint();

try{

Thread.sleep(100);

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

}

3.3添加炮弹Missile类

在Missile类当中添加x,y,dir等属性以及常量。

在Missile类当中添加构造方法,draw方法等必要方法。

根据不同的方向,子弹要进行不同的运动。

在TankClient当中new一颗子弹出来,要用到数据结构单链表的插入方法。

template

boolLinkList:

:

Insert(Tkey,intpos)

{

Node*p=first;

intj=0;

while(p&&j

{

p=p->next;

j++;

}

if(p==NULL)

{

cout<<"erro"<

returnfalse;

}

Node*s=newNode;

s->data=key;

s->next=p->next;//向内存申请一个结点s

p->next=s;//将结点s插入到结点p之后

returntrue;

}

3.4实现坦克的互相攻击

(1)让主战坦克出炮弹

1)在Tank类当中增加对ctrl键的处理,使每按下ctrl键的时候,坦克打出一发炮弹。

caseKeyEvent.VK_CTRL:

fire();

break;

2)根据“坦克打出炮弹”这句话,确定Tank当中的fire方法,其返回值为Missile。

publicMissilefire(){

……

Missilem=newMissile(x,y,ptDir);

returnm;

}

3)为了解决坦克停下来也能开火的问题——给坦克加一炮筒,根据炮筒方向和位置设定子弹的方向和位置并new出来,然后返回,每次move之后根据Tank的新方向确定炮筒的方向。

if(this.dir!

=Direction.STOP){

this.ptDir=this.dir;

}

4)为了能够打出多发炮弹,使用容器填装多发炮弹,每当抬起Ctrl键的时候就往容器中加入新的炮弹

Listmissiles=newArrayList();

5)解决炮弹不消亡的问题,加入控制炮弹生死的量live,当炮弹已经死去就不需要对其重画,当炮弹飞出边界就死亡,当炮弹死亡就从容器中移去,移除用到了单链表的delete方法

template

boolLinkList:

:

Delete(intpos)

{

Node*p=first;

intj=0;

while(p&&j

{

p=p->next;

j++;

}

if(!

p||!

p->next)//结点p或结点p的后继结点不存在

{

cout<<"error"<

returnfalse;

}

else

{

Node*q=p->next;

Tx=q->data;//暂存被删结点

p->next=q->next;//摘链

deleteq;

cout<<"被删结点元素是:

"<

returntrue;

}

}

//通过边界条件判定是否移除

if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT){

live=false;

}

publicvoiddraw(Graphicsg){

if(!

live){

tc.missiles.delete(this);

return;

}

……

}

(2)实现坦克的互相开火

1)加入区分敌我的Boolean量good,根据敌我设置不同的坦克

2)更新Tank的构造函数,加入good

3)在TankClient中new出敌人并画出

4)在Missile中加入hitTank(Tankt)方法,返回布尔类型

5)借用碰撞检测的辅助类Rectangle,为Tank和Missile类都添加getRect()方法。

publicRectanglegetRect(){

returnnewRectangle(x,y,WIDTH,HEIGHT);

}

6)增加控制坦克生死的Boolean量live,如果live为false就不画了。

当炮弹击中敌人坦克时,坦克被打死,子弹也死去。

publicbooleanhitTank(Tankt){

if(this.getRect().intersects(t.getRect())&&t.isLive()){

t.setLive(false);

this.live=false;

returntrue;

}

returnfalse;

}

(3)添加多辆坦克

1)建一容器向里面添加敌人的Tank

Listtanks=newArrayList();

添加Tank

for(inti=0;i<10;i++){

tanks.add(newTank(50+40*(i+1),50,false,this));

}

2)在Tank类当中添加hitTanks方法,打一系列Tank;在TankClient里面每发子弹都打tanks

Tank类当中hitTanks方法

publicbooleanhitTanks(Listtanks){

for(inti=0;i

if(hitTank(tanks.get(i))){

returntrue;

}

}

returnfalse;

}

在TankClient里面每发子弹都打tanks

for(inti=0;i

Missilem=missiles.get(i);

m.hitTanks(tanks);

m.draw(g);

}

(4)让坦克更加智能

1)让敌军坦克向随机方向移动。

添加随机数产生器java.util.Random,move完成之后如果是敌军坦克的,在走完一定的步数之后随机产生一个数,来设定坦克的下一个方向。

if(!

good){

Direction[]dirs=Direction.values();

if(step==0){

step=r.nextInt(12)+3;

intrn=r.nextInt(dirs.length);

dir=dirs[rn];

}

step--;

if(r.nextInt(40)>38)this.fire();

}

2)让敌方坦克发射炮弹。

本军坦克不打本军坦克,向炮弹添加表示好坏的Boolean量good。

3)修改炮弹的构造方法;修改Tank的fire方法;修改hitTank方法,坦克只能打击对方。

3.5创建Explode类

(1)加入位置属性x,,y,加入Boolean变量live

(2)加入draw方法,用一系列的爆炸图片来模拟爆炸

(3)在TankClient当中创建容器,将爆炸存放与容器当中,击毙一辆坦克就产生爆炸,将爆炸逐一画出(如果死去就去除),delete方法在前面已写。

Missile类当中的hitTank()方法

publicbooleanhitTank(Tankt){

if(this.getRect().intersects(t.getRect())&&t.isLive()){

t.setLive(false);

this.live=false;

Explodee=newExplode(x,y,tc);

tc.explodes.add(e);

returntrue;

}

returnfalse;

}

爆炸死后去除

if(!

live){

tc.explodes.remove(this);//死后去除

return;

}

3.6添加障碍物

(1)添加金属墙

1)建立Wall类,建立Wall对象,用绘图工具画出来

2)让每一颗子弹打击每一堵墙,添加hitMetalWall()方法。

当子弹接触到墙时子弹消失。

publicbooleanhitMetalWall(MetalWallw){

if(this.live&&this.getRect().intersects(w.getRect())){

this.live=false;

returntrue;

}

returnfalse;

}

3)让坦克不能穿过墙。

添加记录上一次位置的oldX,oldY;修改构造函数每次move之前记录上一次的位置。

添加stay方法记录移动之前的位置,当坦克撞到樯时回到移动前的位置,即当碰到墙时stay。

publicbooleancollidesWithMetalWall(MetalWallw){

if(this.live&&this.getRect().intersects(w.getRect())){

this.stay();

returntrue;

}

returnfalse;

}

(2)添加普通墙

建立brickWall类,往里添加相应属性以及相应方法。

具体步骤参考2.7.1中添加金属墙。

不同之处在于Missile类当中的hitbrickWall()方法,挡子弹接触到墙壁时,墙壁消失。

(3)加入图片替换主窗口中的各对象

再将图片加入时,运用了系统提供的工具包ToolKit,用工具包拿到所需图片后再将它放入容器中。

然后再做相应的替换。

下面是Missle类当中的图片加入

privatestaticToolkittk=Toolkit.getDefaultToolkit();

privatestaticImage[]missileImages=null;

privatestaticMapimgs=newHashMap();

static{

missileImages=newImage[]{

tk.getImage(Missile.class.getClassLoader().getResource("images/missileL.gif")),tk.getImage(Missile.class.getClassLoader().getResource("images/missileU.gif")),

tk.getImage(Missile.class.getClassLoader().getResource("images/missileR.gif")),tk.getImage(Missile.class.getClassLoader().getResource("images/missileD.gif")),

};

imgs.put("L",missileImages[0]);

imgs.put("U",missileImages[1]);

imgs.put("R",missileImages[2]);

imgs.put("D",missileImages[3]);

}

其他类的图片载入类似Missile类。

3.7添加血块类

创建Blood类,添加血块,假如必要的属性和方法,使血块沿着固定的轨迹运动,

privateint[][]pos={

{350,300},{360,300},{375,310},{385,290},{400,260},{380,300},{350,300}

};

privatevoidmove(){

step++;

if(step>=pos.length)step=0;

x=pos[step][0];

y=pos[step][1];

}

当主战坦克与血块接触的时候,主战坦克的血量自动加满

publicbooleaneat(Bloodb){

if(this.Live&&b.isLive()&&this.getRect().intersects(b.getRect())){

this.life=100;

b.setLive(false);

returntrue;

}

returnfalse;

}

4设计结果与分析

主战坦克的方向键:

上移:

键盘方向键向上下移:

方向键向下

左移:

键盘方向键向下右移:

方向键向右

左上:

键盘方向键上和左右上:

键盘方向键上和右

左下:

键盘方向键下和左右上:

键盘方向键下和右

普通开火键:

ctrl

超级开火键:

A

主战坦克重生键:

F2

运行结果:

5设计体会

通过这次课程设计,初步了解了高级编程语言面向对象的特点,掌握了数据结构及Java编程的许多基本知识,提升了自己的动手能力。

使我对数据结构这门课又做了一次系统的复习,对各个知识点也都有了更深刻的理解,让我掌握的更扎实,掌握了JAVA的应用、编写、上机调试的基本方法,同时也增强了实际操作能力,了解了程序开发过程中涉及到的相关知识,使我对数据结构的使用也更加的熟练,另一方面对编程语言有了新的认识,为以后的学习打下了基础。

本项目要学会图形化用户界面的构建,并且本项目用到了多线程Thread的知识。

通过启用多线程机制,不断调用java.awt.*中的paint(Graphicsg)方法,将画面构造出来。

其中要使用双缓冲消除闪烁现象。

程序中还使用了键盘监听器接口KeyActionListener实现坦克的控制操作。

碰撞检测的辅助类Rectangle可以完成坦克之间,以及坦克与障碍物之间的碰撞检测。

初步了解反射,知道对于classloader每一个.class实际就是一个Class对象。

学会使用Toolkit类,并使用该类加载得到图片。

学会使用Random类,并使用其中的nextInt()方法得到随机数,以实现敌人坦克的AI智能。

利用了容器类往里添加对象,实现可摧毁墙体类、子弹类及敌人坦克的重生与死亡。

展开阅读全文
相关搜索

当前位置:首页 > 总结汇报 > 实习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1