您好,欢迎来到微智科技网。
搜索
您的当前位置:首页坦克大战课程设计论文

坦克大战课程设计论文

来源:微智科技网
坦克大战游戏设计

1.课程设计的目的

随着手机的日益普及,java功能在移动设备上的实现及java应用程序产生的影响力,对丰富人们的生活内容,提供便捷的咨询起着不可忽视的作用。本项目介绍了坦克大战的基本构建方法、java的相关技术及本程序的结构分析和具体功能的实现。游戏是在Eclipse3.2环境下编程。本项目重点运用了图形化用户界面GUI,Thread多线程的有关知识,其中涉及了绘图工具的运用,事件处理操作以及图形的碰撞检测等知识点。通过此课程设计,使学生巩固所学知识、培养学生动手能力,了解Java的面向对象的体系结构。学生用Java语言设计一个完整的应用程序,综合应用所学知识完成软件的分析、设计、调试和总结,提高学生对Java语言的综合应用能力和解决问题的能力。 2.设计方案论证 2.1设计思路

本项目介绍了坦克大战的基本构建方法、java的相关技术及本程序的结构分析和具体功能的实现。游戏是在Eclipse3.2环境下编程。

一、游戏基本元素: 二、它的主要功能:

(1)能够朝四个方向移动:上、下、左、右键。

(2) 按下鼠标左键发射普通子弹;按下鼠标右键发射散弹;子

弹爆炸的效果,普通子弹和炮弹的效果 (3)敌人能够移动

坦克,炮管,子弹, 墙壁,地雷

(4)能够模拟爆炸 (5)能够产生障碍 (6)能够增长生命

玩家控制主坦克(上方有血条的)的移动以及炮弹的发射。若玩家将敌方坦克全部打掉则玩家胜;若期间由玩家控制的主坦克被打掉则视为玩家失败。游戏中只有普通墙作为障碍物,玩家无法穿越它们并且普通子弹不能将墙打穿

;但是玩家可以用炮弹将普通墙打掉。桃心可以将坦克的血加满。

2.2简要的设计流程:

游戏开始刷屏(间接调用paint)延迟25ms初始化游戏元素键盘判断按下的是那个键paint()根据游戏元素的属性,对其经行操作和绘出其图形改变相应游戏元素的属性战斗是否结束

2.2设计方法

2.2.1构建游戏主类

在主类中构造一个主Frame框架,设置它的大小和位置,并将其显示。在主类中编写一段代码,构造一个窗口。并添加窗口关闭的处理事件,将窗口设置成打小不可变。 主要代码如下:

this.addWindowListener(new WindowAdapter() {

2.2.2构建坦克类Tank

构造主窗口中所需要的Tank类,并将坦克加到窗口中,实现坦克的四个方向的移动

创建一个坦克类,用画图工具构造出简单的图形代表坦克,并将坦克加入到主窗口当中。 主要代码如下:

abstract class Tank { boolean init=false; //第一次画时将图片载入内存 static final Toolkit TLK=Toolkit.getDefaultToolkit(); //用来将图片读入Image数组 public static Image[] turretImg={ TLK.getImage(Tank.class.getClassLoader().getResource(\"Image/Tank/turret1.png\")), TLK.getImage(Tank.class.getClassLoader().getResource(\"Image/Tank/turret2.png\"))}; BufferedImage bTurretImg=null;

}

public void windowClosing(WindowEvent e) { System.exit(0);

});

this.setResizable(false);

Graphics2D g2=null;

AffineTransform trans=new AffineTransform();

public static final int SHOTSCOUNT=5; //同时可发射的子弹int shotsCount=0; //已经发射的子弹数

public static final int TANKSPEED=5; //Tank移动速度 public static final int TANKWIDTH=36; //Tank的尺寸 public static final int TANKHEIGHT=38;

public static enum TANK_DIR {U,D,L,R,STOP}; TANK_DIR tankDir; //Tank主体的方向 TANK_DIR moveDir; //Tank的运动方向 boolean camp; //Tank的阵营

boolean isNPC; //是否是有电脑控制的机器人Tank boolean isLive=true; //Tank是否存活

int x,y; //Tank主体的中心点坐标 int oldx,oldy; //存储Tank前一步的坐标

int turretDirx, turretDiry; //大炮端点的坐标

public static final int TURRETLENGTH=30; //炮筒的长度

double oldAngel=0; double nowAngel; double turnAngel;

TankClient tc=null; //主界面类的引用 Bomb tankBomb=null;

HitPoint tankHitPoint; //Tank的生命值

static Random rn=new Random(); //随机数发生器

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

class RepaintThread implements Runnable //画面重画线程 { public void run() { while(repaintFlag) { try

{ repaint(); ut.move(); //Tank定时移动 Shot tcShots=null; for(int i=0;iclass RobotTanksThread implements Runnable //机器人Tank的行动线程 { TankClient tc; public RobotTanksThread(TankClient tc) { this.tc=tc; } public void run() { Tank tcTanks=null; int count=-1; while(repaintFlag)

{ if(0==count) //电脑Tank全灭后重新加几辆 { //RobotTank.add(1,false,RobotTank.RTANKTYPE.BOSS,tc); RobotTank.add(2,false,RobotTank.RTANKTYPE.SPE,tc); } try { count=0; for(int i=0;i根据坦克类修改TankClient主类,在主类中注册事件,并

调用Tank类中的方法: class TankMoveLis extends KeyAdapter //玩家Tank按键监听者 { public void keyPressed(KeyEvent e) { if(ut.isLive) { ut.keyDispose(e.getKeyCode(),true); } } public void keyReleased(KeyEvent e) { if(ut.isLive) { ut.keyDispose(e.getKeyCode(),false); } else { if(e.getKeyCode()==KeyEvent.VK_F2) { ut.rebirth(); //复活 } } } } class MouseMoveLis extends MouseMotionAdapter 移动监听者 { public void mouseMoved(MouseEvent e) {

//鼠标 if(ut.isLive) { mousePoint=e.getPoint(); ut.setTurretDir(mousePoint); //根据鼠标位置更新炮筒方向 } } }

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

public void keyDispose(int Key,boolean b) //对用户按键的处理 { if(b) //有键按下 { switch(Key) { case KeyEvent.VK_UP: case KeyEvent.VK_W: { keyList.remove(TANK_DIR.U); keyList.add(TANK_DIR.U); }break; case KeyEvent.VK_DOWN: case KeyEvent.VK_S: { keyList.remove(TANK_DIR.D); keyList.add(TANK_DIR.D); }break; case KeyEvent.VK_LEFT: case KeyEvent.VK_A: { keyList.remove(TANK_DIR.L); keyList.add(TANK_DIR.L); }break; case KeyEvent.VK_RIGHT: case KeyEvent.VK_D: {

keyList.remove(TANK_DIR.R); keyList.add(TANK_DIR.R); }break; case KeyEvent.VK_SPACE: { this.superFire(); }break; default:break; } } else //有键抬起 { switch(Key) { case KeyEvent.VK_UP: case

KeyEvent.VK_W:{ keyList.remove(TANK_DIR.U); }break; case KeyEvent.VK_DOWN: case

KeyEvent.VK_S:{ keyList.remove(TANK_DIR.D); }break; case KeyEvent.VK_LEFT: case

KeyEvent.VK_A:{ keyList.remove(TANK_DIR.L); }break; case KeyEvent.VK_RIGHT: case

KeyEvent.VK_D:{ keyList.remove(TANK_DIR.R); }break; default:break; } } if(keyList.size()==0) { keyList.add(TANK_DIR.STOP); } super.setMoveDir(keyList.get(keyList.size()-1)); }

2.2.3添加炮弹Shot类

在Shot类当中添加x,y,dir等属性以及常量。在Shot类当中添加构造方法,draw方法等必要方法。根据不同的方向,

子弹要进行不同的运动。在TankClient当中new一颗子弹出来。 public void draw(Graphics g) { if(isLive) { g.drawImage(HYDRASHOT,sx-shotRadius,sy-shotRadius,null); } else { if(isBomb&&shotBomb!=null) { shotBomb.draw(g); } } } void draw(Graphics g) { if(isLive) { g.drawImage(SUPERSHOT,sx-shotRadius,sy-shotRadius,null); } else { if(isBomb&&shotBomb!=null) { shotBomb.draw(g); } }

}

2.2.4实现坦克的互相攻击

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

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

publicShot fire() {

„„

Shot m = new Shot(x, y, ptDir);

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

4)为了能够打出多发炮弹,使用容器填装多发炮弹,每当抬起空格键的时候就往 容器中加入新的炮弹 List missiles = new ArrayList();

5)解决炮弹不消亡的问题,加入控制炮弹生死的量live(Shot),当炮弹已经死去就不需要对其重画,当炮弹飞出边界就死亡,当炮弹死亡就从容器中移去。 public void dead() { if(isLive) { this.isLive=false;

this.ptDir = this.dir;

}

return m;

if(isBomb) { shotBomb=new ShotBomb(sx-32,sy-32,this); } //当撞到墙或Tank时子弹才爆炸 else { this.tc.shotsList.remove(this); //将子弹从List中移除 } }

}

void move() { if(isLive) { sx+=lengthX; sy+=lengthY; if(isOutOfWindow()||isHitTank()) { this.dead(); } }

}

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

1)在TankClient中new出敌人并画出 public static void main(String[] args) { TankClient tc=new TankClient(); tc.lunchFrame();

}

2)在Shot中加入isHitTank()方法,返回布尔类型 public boolean isHitTank() //检查炮弹是否击中Tank { Tank tempTk=null;

for(int i=0;i3)借用碰撞检测的辅助类hitDispose:

public void hitDispose() { Tank tempTank; for(int i=0;i Tank,都减血 } }

}

{

case U: case D:{y=oldy;}break; case L: case R:{x=oldx;}break; default:break; }

this.setMoveDir(TANK_DIR.STOP);

if(camp!=tempTank.camp) //碰到不同阵营的{ }

tempTank.tankHitPoint.cutsHitPoint(1); this.tankHitPoint.cutsHitPoint(1);

4)增加控制坦克生死的Boolean量live,如果live为false就不画了。当炮弹击中敌人坦克时,坦克,子弹也死去。 public boolean hitTank(Tank t) {

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

}

return false;

t.setLive(false); this.live = false; return true;

}

2.2.5创建Item类

(1)创建HitPointerItem子类,作为为tank加血的道具,构造函数eat(Tank tk)加血

void eat(Tank tk) { tk.tankHitPoint.raisesHitPoint(raisesNum); //Tank涨血 tc.itemList.remove(this);

}

2)创建ShotsItem子类,作为涨炮弹的道具。涨炮弹的构造函数为:

void draw(Graphics g) { Color c=g.getColor(); g.setColor(Color.orange); g.fillOval(x,y,width,height); g.setColor(c);

}

} }

2.2.8添加障碍物 1)添加普通墙 private void creat() { for(int i=0;iWallNode(x+j*WallNode.WIDTH,y+i*WallNode.HEIGHT)); } } }

2)普通子弹可以穿墙

public boolean isHits(Shot s) //普通子弹可以破坏墙 { WallNode wn=null;

for(int i=0;i3.程序实现结果

4.设计体会

通过这次课程设计,通过此课程设计,初步了解了java面向对象的特点,掌握了Java的许多基本知识,提升了自己的动手能力。使我对JAVA这门课又做了一次系统的复习,对各个知识点也都有了更深刻的理解,让我掌握的更扎实,掌握JAVA的应用、编写、上机调试的基本方法,同时也增强了实际操作能力,了解了学生信息管理系统的工作流程以及工作模式,程序开发过程中涉及到了数据库的相关知识,使我对数据库的使用也更加的熟练,另一方面也对编程语言有了新的认识,为以后的学习打下了基础。

本项目要学会图形化用户界面的构建,并且本项目用到了多线程Thread的知识。通过启用多线程机制,不断调用java.awt.*中的paint(Graphics g)方法,将画面构造出来。其中要使用双缓冲消

除闪烁现象。程序中还使用了键盘类KeyMonitor实现坦克的控制操作。碰撞检测的辅助类Rectangle可以完成坦克之间,以及坦克与障碍物之间的碰撞检测。初步了解反射,知道对于classloader, 每一个.class实际就是一个Class对象。学会使用Toolkit类,并使用该类加载得到图片。学会使用Random类,并使用其中的nextInt()方法得到随机数。利用了容器类往里添加对象。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务