zoukankan      html  css  js  c++  java
  • 坦克大战总结

    新手请见谅!不足之处,多多指教!谢谢。

    坦克大战总结

    0.1版本

    实现功能:

    设计出一个框架出来

     

    0.2版本

    实现功能:

    1、添加关闭比窗口事件处理。

    this.addWindowListener(new WindowAdapter ()

    {

    public void windowClosing(WindowEvent e) {

    System.exit(0);

    }

    });

    2、不允许窗口的大小改动。

    this.setResizable(false);

    掌握:

    1、匿名类的用法

    2、匿名类的应用场合(类短小,不涉及将来的扩张,不涉及重要的业务逻辑)

    3、通过eclipse 重写父类方法

    右键-----source----overWrite.

     

     

    0.3版本

    功能:    画出代表坦克的实心圆。

    掌握:    如何重写paint 方法。

    public void paint(Graphics g) {

    Color c = g.getColor();

    g.setColor(Color.red);

    g.fillOval(50,50, 30, 30);

    g.setColor(c);

    }

    注意:不要改变原来的前景色。.

     

     

    0.4版本

    功能:

    让坦克动起来

    步骤:

    1、将位置改变为变量。

    int x = 50,y = 50; g.fillOval(xy, 30, 30);

    2、启动线程不断重画。

    private class PaintThread implements Runnable

    {

    public void run() {

    while(true)

    {

    repaint();

    try {

    Thread.sleep(50);

    catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

     

    }

    3、为什么使用线程重画而不是没按下一个键进行一次重画。

    线程重画更均匀,更能控制重画的速度。

    按键重画不能解决子弹自动飞行的问题。

     

    0.41版本

    功能:使用双缓冲消除闪烁现象。

    原因:刷新重画频率太快,paint 方法还完成。

    解决办法:  将所有东西画在虚拟图片上一次性现实出来。

     

    因为调用paint方法之前会调用updata()方法,现在在update()方法中将重画的图先画在一张图上

    public void update(Graphics g) {

    if(offgreenImage == null)//offgreenImage 在类中定义了。

    {

    offgreenImage = this.createImage(800, 600);

    }

     Graphics offScreen = offgreenImage.getGraphics();//得到图片的画笔

     Color c = offScreen.getColor();

      offScreen.setColor(Color.GREEN);

      offScreen.fillRect(0, 0, 800, 600);

      paint(offScreen);

     g.drawImage(offgreenImage, 0, 0, null);

    }

     

     

    0.5版本

    功能:   代码重构

    将以后可能需要多处改变的变量定义为常量

    本例中是:Frame 的宽度和高度。常量名一般大写。

    注意:常量一般是 public static final 的。

    0.6版本

    功能:  让坦克听从指挥

    1、添加键盘监听器类 KeyMonitor

    private class KeyMonitor extends KeyAdapter {

    public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    switch (key) {

    case KeyEvent.VK_LEFT:

    x -= 5;   break;

    case KeyEvent.VK_RIGHT:

    x += 5;    break;

    case KeyEvent.VK_UP:

    y -= 5;    break;

    case KeyEvent.VK_DOWN:

    y += 5;    break;

    }

    }

    }

    2、TankWar 添加键盘监听器类

     

    luanchFrame中添加this.addKeyListener(new KeyMonitor());

    3、针对不同的键改变坦克的位置,与重画线程结合产生不同方向的运动。

     

    注意:

    Switch case 语句中break 的运用。

     

     

    版本0.7

    功能: 将坦克单独包装成类。

    步骤:

    1、建立Tank

    2、Tank类添加成员变量 x,y

    3、添加draw方法,是Tank类自己控制自己的画法

    4、添加Tank类处理按键的方法

    5、根据Tank类修改TankWar类。

     

    版本0.8

    功能:让坦克朝8个方向行走

    步骤:

    1、添加记录按键状态的布尔量

    private boolean bL = false,bU = false,bR = false,bD = false;

    2、添加代表方向的量(使用枚举)

    enum Direction  {L,LU,U,RU,R,RD,D,LD,STOP};

    Direction dir = Direction.STOP;

    3、根据状态确定坦克的方向

    void locaDirection()

    {

    if(bL && !bU && !bR && !bDdir = Direction.L;

    else if(bL && bU && !bR && !bDdir = Direction.LU;

    else if(!bL && bU && !bR && !bDdir = Direction.U;

    else if(!bL && bU && bR && !bDdir = Direction.RU;

    else if(!bL && !bU && bR && !bDdir = Direction.R;

    else if(!bL && !bU && bR && bDdir = Direction.RD;

    else if(!bL && !bU && !bR && bDdir = Direction.D;

    else if(bL && !bU && !bR && bDdir = Direction.L;

    else if(!bL && !bU && !bR && !bDdir = Direction.STOP;

    }

    4、根据方向进行下一步的移动(move方法)

    5、pressed()方法中调用locaDurection()方法。

    public void pressed(KeyEvent e)

    {

    int key = e.getKeyCode();

    switch (key) {

    case KeyEvent.VK_LEFT:

    bL = true;break;

    case KeyEvent.VK_RIGHT:

    bR = true;break;

    case KeyEvent.VK_UP:

    bU = true;break;

    case KeyEvent.VK_DOWN:

    bD = true;break;

    }

    locaDirection();

    }

     

    版本0.9

    功能:修正0.8版本

    问题:0.8版本中按下一个键后键就永远变成了true

    解决: 处理按键抬起的消息

    1、TankWar中的KeyMoniter中增加按键抬起消息响应。

     

    public void keyReleased(KeyEvent e) {

    myTank.released(e);}

    2、Tank中增加代码

    public void released(KeyEvent e) {

    int key = e.getKeyCode();

    switch (key) {

    case KeyEvent.VK_LEFT:

    bL = false;break;

    case KeyEvent.VK_RIGHT:

    bR = false;break;

    case KeyEvent.VK_UP:

    bU = false;break;

    case KeyEvent.VK_DOWN:

    bD = false;break;

    }

    locaDirection();

    }

     

    版本1.0

    功能:添加子弹类

    步骤:

    1、添加Missile 

    2、添加x,y,dir等属性及常量

    3、添加构造方法,draw方法

    4、更具不同方向,进行不同运动

     

     

    版本1.1

    功能:根据主坦克的方向和位置,打出子弹

    步骤:

    1、增加对CTRL键的按键处理

    2、根据“坦克打出依法子弹”这句话确定Tank中的fire,其返回值是Missile

    3、根据Tank方向和位置设定子弹的方向和位置并画出来,然后返回。

     

     

    版本1.2

    功能:为了解决坦克停下也能打出炮弹的问题-----画出炮筒

    步骤

    1、Tank 类增加新的属性 ptDir

    2、每次move后根据Tank新的方向确定炮筒的方向

    3、将炮筒用直线的形式画出来(在draw方法中中画出来)

     

     

    版本1.3

    功能:打出多发炮弹

    步骤:

    1、使用容器装炮弹

    List<Missile> missiles = new ArrayList<Missile>();

    2、每当抬起Ctrl键就往容器中添加新的炮弹

    case KeyEvent.VK_CONTROL:

     fire();

    break;

    3、逐一画出每一发炮弹

    paint中使用

    for(int i = 0;i<missiles.size();i++)

    {

    Missile m = missiles.get(i);

    m.draw(g);

    4、}

    追:泛型的使用

    TankWar1的示例传递到tank

     

    版本1.4

    功能:解决炮弹不消亡的问题

    解决坦克出界的问题

    if(x<0)  x = 0;

    if(y<30) y = 30;

    if(x+Tank.WIDTH > TankWar1.GAME_WIDTHx =  TankWar1.GAME_WIDTH - Tank.WIDTH;

    if(y + Tank.HEIGHT > TankWar1.GAME_HEIGHTy = TankWar1.GAME_HEIGHT - Tank.HEIGHT;

     

    步骤:

    1、加入控制炮弹生死的量live (Missile类中加入)

    2、当炮弹已经死去就不需要对其进行重画

    3、当炮弹飞出边界就死亡

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

    {

    live  = false;

    this.tc.missiles.remove(this);

    }

    4、但炮弹死亡就从容器中擦出

    5、Missile类中添加新的构造函数 加入对TankWar1的引用

    public Missile(int x,int y,Tank.Direction dir,TankWar1 tc)

    {

    this(x,y,dir);

    this.tc = tc;

    }

    6、当炮弹new 出来时在fire()方法中

    Missile m = new Missile(x,y,ptDir,this.tc);

     

     

    版本1.41

    功能:Debug的使用

    1、一步一步跟踪代码

    2、为代码设置断点

    3、Step into 和 step over 的概念

    4、学会在运行过程中观测变量的值。

     

     

    版本1.5

    功能:画出一量敌人的坦克

    步骤:

    1、加入区别敌我的量

    2、根据敌我的不同设置不同的颜色

    3、更新Tank的构造函数,加入good

    4、TankWar1中画出敌人的坦克并画出。

     

    版本1.6

    功能:将敌人坦克击毙

    分析:一颗子弹击中敌人坦克

    步骤:

    1、Missile中加入hitTankTank)方法,返回布尔类型

    public boolean hitTank(Tank t)

    {

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

    {

    t.setLive(false);

    this.live = false;

    return true;

    }

    return false;

    }

    2、碰撞检测的辅助类Rectangle

    public Rectangle getRect()

    {

    return new Rectangle(x,y,WIDTH,HEIGHT);

    }

     

    3、TankMissile都加入getRect方法

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

    即把坦克和子弹的live 都设置为false

    5、增加控制Tank生死的量live

    6、如果死去就不画了

    7、修改当子弹出界后把子弹的live设置为false,并不把它擦出

    8、当画出子弹时先判断一下子弹是否还活着

    if(!live)

    {this.tc.missiles.remove(this);

    return;}

    版本1.7

    功能: 加入爆炸

    步骤:

    1、添加爆炸类

    2、用不同直径的圆模拟爆炸

    3、加入live 判断爆炸的生死,死了就不要画了

    4、加入位置属性

    5、加入draw方法

     

    爆炸应该位于集合类中

    1、TankWar1加入集合

    List<Explode> explodes = new ArrayList<Explode>();

    2、将集合中的爆炸逐一画出(如果死去就去除)(模仿子弹画法)

    for(int i=0;i<explodes.size();i++)

    {

    Explode e = explodes.get(i);

    e.draw(g);

    }

    击毙一辆坦克时产生爆炸(在hitTank中添加)

    Explode e = new Explode(x,y,tc);

    tc.explodes.add(e);

     

     

    版本1.8

    功能:添加多辆坦克

    步骤:

    1、用容器来装敌人的Tank

    List<Tank> tanks = new ArrayList<Tank>();

    2、向容器中装入多辆敌人的Tank

    for(int i = 0;i<tanks.size();i++)

    {

    Tank t = tanks.get(i);

    t.draw(g);

    }

    3、画出敌人的坦克

    4、运行,不能打掉

    5、添加hitTanks方法,打一系列的坦克

    public boolean hittanks(List<Tank> tanks)

    {

    for(int i = 0;i<tanks.size();i++){

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

    {

    return true;}}

    return false;}

    6、TankWar中每一发子弹都可以打tanks

    7、每次击毙一辆坦克要从容器中去除

    if(!live)

    {if(!good)

    {

    tc.tanks.remove(this);

    }

    return;}

     

     

     

    版本1.9

    功能:让敌军的坦克更加智能

    步骤:

    1、让敌军的坦克动起来

    构造函数中可以指定方向

    New 敌军坦克的时候指定敌军坦克的方向

    2、让敌军的坦克向随机的方向移动

    坦克静态的,添加随机数产生器 java.util.Random

    private static Random r = new Random(); 

    Move完成后,如果是敌军坦克,随机设定一个数来指定坦克的下一个方向

    enum转化为相应的整形数组

    Direction[] dirs = Direction.values();

    Direction.values()

    3、让敌军坦克向随机方向移动随机的步骤

    添加变量,记录随机步骤

    if(step == 0)

    {step = r.nextInt(12)+4;

    int rn = r.nextInt(dirs.length);

    dir = dirs[rn];

    }

    当变量等于0时,改变方向,否则只是随机步骤递减

    4、让敌军坦克发射炮弹

    本军炮弹不打本军炮弹

    炮弹根据好坏添加变量good,根据好坏画出不同的颜色

    修改炮弹的构造方法

    修改坦克的fire()方法

    如果坦克死了的话就不可以打出子弹了

    if(!live)

    return null;

    修改hitTank方法,好不能打好,坏不能打坏

    this.good!=t.isGood()

    5、敌军炮火不可以太猛烈

    用随机数解决

    if(r.nextInt(20)>16)

    {

    this.fire();

    }

     

    版本2.0

    功能:添加两堵墙

    步骤:

    1、建立Wall类,建立Wall对象,画出来

    2、让每一颗子弹打击每一堵墙

    hitWall()方法。

    public boolean hitWall(Obstancle ob)

    {

    if(live && this.getRect().intersects(ob.getRect()))

    {

    live = false;

    return true;

    }

    return false;}

    注意:子弹速度不可以太快,否则容易穿过墙

    3、让坦克不能穿过墙

    记录上一次的位置oldX,oldY

    修改构造函数

    每次move之前记录上一次位置

    添加stay()方法

    public void stay()

    {

    x = oldX;

    y = oldY;

    }

    记录移动前的位置

    当撞到时回到移动前的位置

    当撞到的时候stay

     

     

    版本2.1

    功能:坦克不能互相穿越

    步骤:当坦克撞到坦克时stay Tank类中增加jittanks()方法

    public boolean hitTanks(java.util.List<Tank> tanks)

    {

    for(int i = 0;i<tanks.size();i++)

    {

    Tank t = tanks.get(i);

    if(this!=t)

    {

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

    {

    this.stay();

    t.stay();

    return true;

    }

    }}

    return false;

    }

     

     

    版本2.2

    功能:增加超级炮弹

    代码:

    增加一个fire(Direction dir)方法。

    按方向来打出炮弹

    public void superfire()

    {

    Direction [] dirs = Direction.values();

    for(int i = 0;i<8;i++)

    {

    fire(dirs[i]);

    }

     }

     

    版本2.3

    功能:给我方坦克增加生命值

    给坦克增加life 变量 初始值为100

    hitTank中改变代码

    if(t.isGood())

    {

    t.setLife(t.getLife()-20);

    if(t.getLife()<=0)

    t.setLive(false);

    }

    else

    t.setLive(false);

     

    版本2.4

    功能:图形化表示主坦克的生命值

    步骤:

    根据不同的life值进行不同的显示

    给坦克类增加一个内部类

    private class bloodBar

    {

    public void draw(Graphics g)

    {

    Color c = g.getColor();

    g.setColor(Color.lightGray);

    g.drawRect(xy-10,WIDTHHEIGHT);

    int w = WIDTH * life/100;

    g.fillRect(xy-10, w, 10);

    g.setColor(c);

    }

    }

     

    版本2.5

    功能:添加血块

    添加Blood

    添加必要的方法

    blood对象固定轨迹运动,并在一定时间后消失

     

    版本2.6

    敌人死光了重新加入

    我军死掉了按F12开始

  • 相关阅读:
    swt 更新主UI线程
    java中 快捷键输入System.out.println();
    原型设计工具
    JAVA笔记
    转:java读取配置文件的几种方法
    Server Message Block
    安全标识符
    BitLocker:如何启用网络解锁
    imageX.exe
    组策略首选项
  • 原文地址:https://www.cnblogs.com/LLeiFeng/p/2828600.html
Copyright © 2011-2022 走看看