现在的位置: 首页 > 综合 > 正文

用面向对象的思想探讨游戏“魔兽争霸”(3)-模板模式的应用(修改版)

2013年11月10日 ⁄ 综合 ⁄ 共 4004字 ⁄ 字号 评论关闭

【文章标题】用面向对象的思想探讨游戏“魔兽争霸”(3)-模板模式的应用(修改版)

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ190678908

【作者博客】http://blog.csdn.net/newjueqi

【编程环境】JDK 1.6.0_01

【作者声明】欢迎转载文章,但转载请保留文章的完整性以及注明文章的出处。

 

 

*******************************************************************************

       本人在看完《大话设计模式》中的第10章——“考题抄错会做也白搭—模板方法模式”后就突然之灵光一闪,这个模板模式不就是改良在上篇文章《用面向对象的思想探讨游戏“魔兽争霸”(2)-继承和多态的应用》(详见本人的博客:http://blog.csdn.net/newjueqi)的 妙药。

       我们比较一下在上篇文章《用面向对象的思想探讨游戏“魔兽争霸”(2)-继承和多态的应用》中弓箭手类Bower和食尸鬼类Ghost所覆盖战士类Fighter的方法public void getHunt( Fighter fighter )

 

其中弓箭手类BowergetHunt方法如下:

//受到攻击时调用这个方法计算伤害值

       public void getHunt( Fighter fighter )

       {

              //只有在食尸鬼和弓箭手都没死亡的前提下会攻击   

              if( fighter.getLifeNum()>0 && getLifeNum()>0 )

              {

                     //如果受到的攻击值大于自身的生命值表示对象死亡

                     if( (fighter.getAttackNum()-getUntenNum())>=getLifeNum() )

                     {

                            setLifeNum( 0 );

                            System.out.print("弓箭手"+getId()+"受到食尸鬼"+fighter.getId());

                            System.out.print("的攻击力"+fighter.getAttackNum());

                            System.out.println(",弓箭手"+getId()+"死亡");

                           

                     }

                     else //用生命值减去受到的伤害值

                     {

                            setLifeNum( getLifeNum()-(fighter.getAttackNum()-getUntenNum()) );

                            System.out.print("弓箭手"+getId()+"受到食尸鬼"+fighter.getId());

                            System.out.print("的攻击力"+fighter.getAttackNum());

                            System.out.println(",剩余生命值为"+getLifeNum());                           

                     }

               }

       }    

             

 

 

食尸鬼类Ghost getHunt方法如下:

//受到攻击时调用这个方法计算伤害值

       public void getHunt( Fighter fighter )

       {

              //只有在食尸鬼和弓箭手都没死亡的前提下会攻击

              if( fighter.getLifeNum()>0 && getLifeNum()>0 )

              {

              //如果受到的攻击值大于自身的生命值表示对象死亡

                     if( ( fighter.getAttackNum()-getUntenNum())>=getLifeNum() )

                     {

                            setLifeNum( 0 );

                            System.out.print("食尸鬼"+getId()+"受到弓箭手"+fighter.getId());

                            System.out.print("的攻击力"+fighter.getAttackNum());

                            System.out.println(",食尸鬼"+getId()+"死亡");

                           

                     }

                     else //用生命值减去受到的伤害值

                     {

                            setLifeNum( getLifeNum() -

                                   (fighter.getAttackNum()-getUntenNum()) );

                            System.out.print("食尸鬼"+getId()+"受到弓箭手"+fighter.getId());

                            System.out.print("的攻击力"+fighter.getAttackNum());

                            System.out.println(",剩余生命值为"+getLifeNum() );

                     }

              }

       }

 

大家仔细比较这两个方法的不同点,就除了所有的输出语句中的“食尸鬼”和"弓箭手"这两个字符串不同外(即各自类型的字符表达形式),其他的内容都是相同的。

在《《设计模式:可复用面向对象软件的基础》》中是这样定义模板模式:定义一个操作中的算法的骨架,而将一些步?延迟道子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步?。

分析getHunt 方法中的不变量与变化量:不变量是整个算法的步?,变化量是一个字符串的表示,我们根据模板模式的思想:把不变量写在父类中,在父类中把变化量抽象出来,而变化量的实现则延迟到子类中。

同理,可进一步抽象moveTo

重构后的父类Fighter如下:

 

 

//战士类,所有的士兵都继承于这个类

abstract class Fighter

{

    private int posX;     //战士在地图上X的坐标

    private int posY;     //战士在地图上Y的坐标

    private int id;     //战士在地图上Y的坐标

    private int lifeNum;      //战士的生命值

    private int attackNum;   //战士的攻击力

    private int untenNum;      //战士的防御力 

    private String fightername;      //战士的名称

   

    public Fighter(    int posX,

                  int posY,

                  int id,

                  int lifeNum,

                  int attackNum,

                  int untenNum,

                   String fightername ) {

 

        this.posX = posX;

        this.posY = posY;

        this.id = id;

        this.lifeNum = lifeNum;

        this.attackNum = attackNum;

        this.untenNum = untenNum;

        this.fightername= fightername;

      

        System.out.println( fightername+id+"生产完毕了");

      

    }

 

    /******

    一般来说,生命值,攻击力,防御力等都属于对象的核心数据,对它们

    的访问必须要严格控制,所以设计出getLifeNum()getAttackNum()

    getUntenNum()这三个方法

    */

   

    //获取战士的剩余生命值

    public int getLifeNum()

    {

        return lifeNum;

    }

   

    //设置战士的生命值

    public void setLifeNum( int num )

    {

        lifeNum=num;

    }

   

    //获取战士的攻击力-->

作者:

抱歉!评论已关闭.