坦克大战实验报告论文.docx
- 文档编号:12307547
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:53
- 大小:183.75KB
坦克大战实验报告论文.docx
《坦克大战实验报告论文.docx》由会员分享,可在线阅读,更多相关《坦克大战实验报告论文.docx(53页珍藏版)》请在冰豆网上搜索。
坦克大战实验报告论文
坦克大战实验报告
班级:
姓名:
学号:
一、系统简介
使用JAVA编写一个人机游戏,有开始启动面板(Stage1),并有闪烁效果。
在开始面板中有游戏(G)和帮助(H)两个菜单。
其中游戏(G)菜单中有开始游戏(N)、退出游戏(E)、保存游戏(S)、继续游戏(C)选项;帮助(H)菜单中有关于坦克如何操作的提示信息。
玩家有1辆坦克(有3条命),电脑有6辆坦克,我的坦克可以通过键盘控制进行移动和发射子弹,敌人坦克可自由运动并自动发射子弹。
敌人坦克相互之间不能重叠,敌人坦克与我的坦克不能重叠,我的坦克与敌人坦克不能重叠。
当子弹击中坦克时坦克死亡,并显示爆炸效果。
当我的坦克生命为0时游戏结束(显示GAMEOVER),当敌方的所有坦克死亡时游戏结束(显示VICTORY)。
二、需求分析
设计一个图形用户界面,将所有游戏的元素都能在此用于界面上表现出来,界面能够接受用户的操作,具有人机交互功能。
用户可以选择开始游戏(N),退出游戏(E),保存游戏(S),继续游戏(C),游戏帮助(H)。
界面中包含我的坦克和敌人坦克以及坦克发出的子弹和爆炸后的效果。
坦克:
坦克分为两种,敌人坦克和我的坦克。
我的坦克和敌人坦克均可以发射子弹,可以改变路径行走,且在行走过程中碰到边界或碰到其它坦克会自动换方向,坦克之间不能相互穿越。
子弹:
子弹可以由敌方坦克和我的坦克发射,且发射出去的子弹可以直线移动,直到碰到其它坦克或超越边界就消失。
坦克受到一颗子弹攻击便死亡,死亡后坦克消失。
爆炸:
当子弹射击到坦克身上时,要产生爆炸效果。
方向:
坦克和子弹都有方向,可以选择上下左右四个方向,且子弹的方向从属于坦克的方向。
具体功能:
1、坦克可以上下左右移动
2、坦克可以发子弹(可以连发,最多5发子弹)
3、当坦克中弹时,坦克消失,并显示爆炸效果。
4、我的坦克被击中后显示爆炸效果
5、防止敌人坦克重叠运动、我的坦克与敌人坦克重叠运动、敌人坦克与我的坦克重叠运动
6、玩游戏时可以保存游戏和继续游戏
7、记录玩家的成绩
三、系统设计
程序流程图:
总体框架:
项目名:
TankGame1
主类文件:
MyFrame.java
坦克父类文件:
Tank.java
坦克子类(我的坦克):
MyTank.java
坦克子类(敌人坦克):
EnemyTank.java
我的面板:
MyPanel.java
子弹类:
Shot.java
开始面板:
MyStartPanel.java
记录类:
Recorder.java
爆炸类:
Bomb.java
四、详细设计
(一)、画坦克
1、Tank类
classTank{
intx,y;//坦克的位置
intdirect;//坦克的方向
intcolor;//坦克的颜色,值为0时为的我的坦克,为1时为敌人的坦克
intspeed;
publicTank(intx,inty){
this.x=x;
this.y=y;
}
setter与getter方法(代码略)
publicvoidmoveUp(){//向上移动,y坐标值减,方向值为0
y-=speed;
this.setDirect(0);
}
publicvoidmoveDown(){//向下移动,y坐标值增,方向值为2
y+=speed;
this.setDirect(0);
}
publicvoidmoveRight(){//向右移动,x坐标值增,方向值为1
x+=speed;
this.setDirect(0);
}
publicvoidmoveLeft(){//向左移动,x坐标值减,方向值为3
x-=speed;
this.setDirect(0);
}
}
2、我的坦克类MyTank
classMyTankextendsTank{
publicMyTank(intx,inty){
super(x,y);
}
}
3、主类MyFrame
publicclassMyFrameextendsJFrame{
MyPanelmp=null;
publicstaticvoidmain(String[]args){
MyFrametankGame1=newMyFrame();
MyFrame.setVisible(true);
}
publicMyFrame(){
mp=newMyPanel();
this.add(mp);
this.setBounds(200,200,600,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
4、在MyFrame.java中创建MyPanel类
classMyPanelextendsJPanel
{
MyTankmytank=null;
publicMyPanel()
{
mytank=newMyTank(200,200);//创建我的坦克并设置其初始位置
}
//重载MyPanel类的paint函数以实现画坦克
publicvoidpaint(Graphicsg)//窗口大小改变或重绘窗口时,执行repaint()时会自动调用
{
super.paint(g);
g.fillRect(0,0,600,500);
this.drawTank(mytank.getX(),mytank.getY(),mytank.getDirect(),mytank.getColor(),5,g);
}
//在MyPanel画坦克的函数,参数包括坦克的位置、方向、类型(用于设置颜色)、画笔:
publicvoiddrawTank(intx,inty,intdirect,intcolor,intsize,
Graphicsg){
switch(color){
case0:
//我的坦克的颜色
g.setColor(Color.cyan);
break;
case1:
g.setColor(Color.yellow);
break;
case2:
//敌人坦克的颜色
g.setColor(Color.green);
break;
}
switch(direct){
case0:
g.fill3DRect(x,y,size,6*size,false);
g.fill3DRect(x+3*size,y,size,6*size,false);
g.fill3DRect(x+size,y+size,2*size,4*size,false);
g.fillOval(x+size,y+2*size,2*size,2*size);
g.drawLine(x+2*size,y,x+2*size,y+3*size);
break;
case3:
g.fill3DRect(x,y,6*size,size,false);
g.fill3DRect(x,y+3*size,6*size,size,false);
g.fill3DRect(x+size,y+size,4*size,2*size,false);
g.fillOval(x+2*size,y+size,2*size,2*size);
g.drawLine(x,y+2*size,x+3*size,y+2*size);
break;
case1:
g.fill3DRect(x,y,6*size,size,false);
g.fill3DRect(x,y+3*size,6*size,size,false);
g.fill3DRect(x+size,y+size,4*size,2*size,false);
g.fillOval(x+2*size,y+size,2*size,2*size);
g.drawLine(x+6*size,y+2*size,x+3*size,y+2*size);
break;
case2:
g.fill3DRect(x,y,size,6*size,false);
g.fill3DRect(x+3*size,y,size,6*size,false);
g.fill3DRect(x+size,y+size,2*size,4*size,false);
g.fillOval(x+size,y+2*size,2*size,2*size);
g.drawLine(x+2*size,y+6*size,x+2*size,y+3*size);
break;
}
}
(二)、移动坦克(事件监听)
●在主类注册键盘事件监听,在MyPanel类中实现事件监听。
●在这里,本文通过另一种新的方法来实现坦克的移动,通过实现keyPressed(KeyEvente)与keyReleased(KeyEvente)这两个事件处理方法,再创建一个action()方法,即可达到坦克移动更加敏捷顺畅,并且可为后面坦克发射子弹做重要铺垫,即可做到坦克边移动,边发射子弹的效果。
//L表示向左,R表示向右,U表示向上,D表示向下
booleanL=false,R=false,U=false,D=false;
@Override
publicvoidkeyPressed(KeyEvente){
if(e.getKeyCode()==KeyEvent.VK_W){
U=true;
}elseif(e.getKeyCode()==KeyEvent.VK_D){
R=true;
}elseif(e.getKeyCode()==KeyEvent.VK_S){
D=true;
}elseif(e.getKeyCode()==KeyEvent.VK_A){
L=true;
}
}
@Override
publicvoidkeyReleased(KeyEvente){
if(e.getKeyCode()==KeyEvent.VK_W){
U=false;
}elseif(e.getKeyCode()==KeyEvent.VK_D){
R=false;
}elseif(e.getKeyCode()==KeyEvent.VK_S){
D=false;
}elseif(e.getKeyCode()==KeyEvent.VK_A){
L=false;
}
}
publicvoidaction(){
if(U){
this.mytank.setDirect(0);
this.mytank.moveUp();
}elseif(R){
this.mytank.setDirect
(1);
this.mytank.moveRight();
}elseif(D){
this.mytank.setDirect
(2);
this.mytank.moveDown();
}elseif(L){
this.mytank.setDirect(3);
this.mytank.moveLeft();
}
}
//重新绘制窗口
this.repaint();
}
再将action()方法放到run()中。
(三)、画出敌人的坦克
1、.创建敌人的坦克类EnemyTank.java
publicclassEnemyTankextendsTank
{
publicEnemyTank(intx,inty)
{
super(x,y);
}
}
2、在MyPanel中,创建敌人的坦克组
ArrayList
EnemyTanket=null;
publicstaticintensize=6;
在构造函数中初始化敌人的坦克:
//创建敌人坦克
for(inti=0;i et=newEnemyTank(20+i*50,0); } 在paint中画出敌人的坦克 publicvoidpaint(Graphicsg){ super.paint(g); //画出我的坦克 if(mytank.isLive()){ this.drawTank(mytank.getX(),mytank.getY(),mytank.getDirect(), mytank.getColor(),5,g); } //画出敌人的坦克 for(inti=0;i et=ets.get(i); drawTank(et.getX(),et.getY(),et.getDirect(),et.getColor(),5,g); } (四)、线程----让坦克能发射子弹并击中敌人坦克 坦克要能发射子弹(按J键时发射子弹),子弹要以一定的速度移动,发射子弹的频率不能过快,当子弹击中敌人的坦克时,子弹死亡,敌人的坦克生命值减少。 基本思路: ●创建一个子弹类线程,在该类中定义子弹的属性,并通过run方法实现子弹的移动 ●在我的坦克类MyTank()中创建子弹集合,添加一个方法shotEnemy用于按方向创建并子弹,同时将创建的子弹添加到子弹集合中,然后启动子弹线程 ●在MyPanel类中添加发射子弹的事件处理: 按J键时调用MyTank()类的shotEnemy方法创建子弹在paint方法中画出子弹。 ●将MyPanel类改为线程类,并在其run方法中调用相关方法判断子弹是否击中坦克 实现爆炸效果。 1、创建子弹类Shot.java 在members.java中定义子弹类,该类通过Runnable实现线程 packageTankWar; publicclassShotimplementsRunnable{ privateintx; privateinty; privateintdirect; privateintspeed=6; privatebooleanisLive=true; publicShot(){} publicShot(intx,inty,intdirect){ this.x=x; this.y=y; this.direct=direct; } @Override publicvoidrun(){ while(true) { try{ Thread.sleep(50); }catch(InterruptedExceptione){ e.printStackTrace(); } switch(this.direct) { case0: y-=speed; break; case1: x+=speed; break; case2: y+=speed; break; case3: x-=speed; break; } //判断子弹是否跑出界面 if(x<=0||x>=480||y<=0||y>=360) { isLive=false; break; } } } } 2.、在MyTank类中创建子弹集,并定义一个方法ShotEnemy,创建子弹并将子弹添加到子弹集中,启动子弹线程。 在MyTank类中添加向量ss用于存放子弹: //创建子弹集 ArrayList Shots=null; 在MyTank类添加一个创建子弹并启动子弹线程的方法 //ShotEnemy创建子弹并将子弹添加到子弹集中,启动子弹线程 publicvoidshotEnemy(){ switch(this.direct){ case0: s=newShot(x+2*size,y,0); ss.add(s); break; case1: s=newShot(x+6*size,y+2*size,1); ss.add(s); break; case2: s=newShot(x+2*size,y+6*size,2); ss.add(s); break; case3: s=newShot(x,y+2*size,3); ss.add(s); break; } //启动子弹线程 Threadt=newThread(s); t.start(); } 3、发射子弹的键盘事件的实现 分别在MyPanel的publicvoidkeyPressed(KeyEvente)和publicvoidkeyReleased(KeyEvente)中添加按j键的事件。 BooleanSHOT=false; publicvoidkeyPressed(KeyEvente){ if(e.getKeyCode()==KeyEvent.VK_J){ SHOT=true; } } @Override publicvoidkeyReleased(KeyEvente){ if(e.getKeyCode()==KeyEvent.VK_J){ SHOT=false; } } publicvoidaction(){ if(SHOT){ if(this.mytank.isLive()&&this.mytank.ss.size()<=4)//最多可连续发5枚子弹 { this.mytank.shotEnemy(); } } } 4、画出子弹 (1)在paint方法中画出子弹: //从ss,中取出每颗子弹,并画出 for(inti=0;i ShotmyShot=mytank.ss.get(i);//从子弹集合中取出子弹 if(myShot! =null&&myShot.isLive()==true)//若子弹集不空,且子弹没有消 { g.draw3DRect(myShot.getX(),myShot.getY(),1,1,false); } if(myShot.isLive()==false)//子弹消失 { //从ss中删除掉该子弹 mytank.ss.remove(myShot); } } (2)、使子弹能自动移动: S1: 在MyPanel中的接口中加入Runnable: publicclassMyPanelextendsJPanelimplementsRunnable S2: 实现接口中的抽象方法run: @Override publicvoidrun(){ //每隔100毫秒去重绘 while(true){ action(); try{ Thread.sleep(100); }catch(Exceptione){ e.printStackTrace(); } //重绘 this.repaint(); } S3: 创建并启动MyPanel线程 在主类的构造函数中创建我的面板线程并启动。 mp=newMyPanel();//创建我的面板 Threadt=newThread(mp); t.start();//线程启动 5、当子弹击中坦克时坦克消失 (1)、在Tank类中添加一个变量用于判断坦克是否死亡 booleanisLive=true; (2)、在MyPanel中添加下面两个函数用于判断子弹是否击中目标 //写一个函数专门判断子弹是否击中敌人坦克 publicbooleanhitTank(Shots,Tanket){ booleanb2=false;//用于判断子弹是否击中坦克 switch(et.direct){ //如果敌人坦克的方向是上或者是下 case0: case2: if(s.getX()>et.x&&s.getX() &&s.getY() s.setLive(false);//子弹死亡 et.setLive(false);//敌人坦克死亡 b2=true; Bombb=newBomb(et.x,et.y);//创建一颗炸弹,放入ArrayList bombs.add(b);//放入ArrayList } break; case1: case3: if(s.getX()>et.x&&s.getX() &&s.getY()
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 坦克 大战 实验 报告 论文