美文网首页java电竞·游戏
王者荣耀与Java策略模式

王者荣耀与Java策略模式

作者: HaleyLiu | 来源:发表于2017-10-23 02:14 被阅读57次

    一.什么是策略模式

    (1)策略模式属于对象的行为模式。其用意是针对一组算法,将每一  
    个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替  
    换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
    
    (2)策略模式是对算法的包装,是把使用算法的责任和算法本身分  
    割开来,委派给不同的对象管理。策略模式通常把一个系列的算法  
    包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句  
    话来说,就是:“准备一组算法,并将每一个算法封装起来,使得  
    它们可以互换”。
    

    二.策略模式的结构

    (1)这个模式涉及到三个角色:
        环境(Context)角色:持有一个Strategy的引用。
        抽象策略(Strategy)角色:这是一个抽象角色,通常由一个  
    接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
        具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
    
    (2)策略模式的重心
      策略模式的重心不是如何实现算法,而是如何组织、调用这些算  
    法,从而让程序结构更灵活,具有更好的维护性和扩展性。
    
    (3)算法的平等性
      策略模式一个很大的特点就是各个策略算法的平等性。对于一  
    系列具体的策略算法,大家的地位是完全一样的,正因为这个平等  
    性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。
      所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。
    
    (4)运行时策略的唯一性
      运行期间,策略模式在每一个时刻只能使用一个具体的策略实现  
    对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。
    
    (5)公有的行为
      经常见到的是,所有的具体策略类都有一些公有的行为。这时候  
    ,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。  
    当然这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。
      这其实也是典型的将代码向继承等级结构的上方集中的标准做法。
    

    三.以王者荣耀为例说明

    UML类图.JPG

    王者荣耀里面召唤师技能(Summoner Spells)有:


    召唤师技能.png
    惩戒:对身边的野怪和小兵造成真实伤害并眩晕1秒(30秒的CD,1级解锁) 
    斩杀:立即对身边敌军英雄造成其已损失生命值14%的真实伤害(90秒CD,3级解锁)  
    狂暴:增加攻击速度60%,并增加物理攻击力10%持续5秒(60秒CD,5级解锁)
    疾跑:增加30%移动速度持续10秒(100秒CD,7级解锁)
    治疗术:回复自己与附近队友15%生命值,提高附近友军移动速度15%持续2秒(120秒CD,9级解锁)
    干扰:沉默机关持续5秒(60秒CD,11级解锁)
    眩晕:晕眩身边所有敌人0.75秒,并附带持续1秒的减速效果(90秒CD,13级解锁)
    净化:解除自身所有负面和控制效果并免疫控制持续1.5秒(120秒CD,15级解锁)
    弱化:减少身边敌人伤害输出30%持续2.5秒(90秒CD,17级解锁)
    闪现:向指定方向位移一段距离(120秒CD,19级解锁)
    
    将里面的召唤师技能抽象出来有(攻击方式,效果持续时间,冷却  
    时间,解锁等级等规则),而这些规则算法封装起来使得它们可以  
    互换。
    
    建立一个抽象策略(Strategy)角色类SummonerSpells:
    public interface  SummonerSpells{
         public void use(Self self,Enermy enermy){
              //do something  
        }
    }
    实体类:
    package com.lrq.test;
    
    public class Enermy {
        private int cd;
        private  int level;
        private  boolean lock;
        private  double  currentHp;
        private  double  fullHp;
        private  double attack;
        private  String controlEffect;
        private  String  shift;
        private  double moveSpeed;
        
        public Enermy() {
            super();
        }
        public int getCd() {
            return cd;
        }
        public void setCd(int cd) {
            this.cd = cd;
        }
        public int getLevel() {
            return level;
        }
        public void setLevel(int level) {
            this.level = level;
        }
        public boolean isLock() {
            return lock;
        }
        public void setLock(boolean lock) {
            this.lock = lock;
        }
        public double getCurrentHp() {
            return currentHp;
        }
        public void setCurrentHp(double currentHp) {
            this.currentHp = currentHp;
        }
        public double getFullHp() {
            return fullHp;
        }
        public void setFullHp(double fullHp) {
            this.fullHp = fullHp;
        }
        public double getAttack() {
            return attack;
        }
        public void setAttack(double attack) {
            this.attack = attack;
        }
        public String getControlEffect() {
            return controlEffect;
        }
        public void setControlEffect(String controlEffect) {
            this.controlEffect = controlEffect;
        }
        public String getShift() {
            return shift;
        }
        public void setShift(String shift) {
            this.shift = shift;
        }
        public double getMoveSpeed() {
            return moveSpeed;
        }
        public void setMoveSpeed(double moveSpeed) {
            this.moveSpeed = moveSpeed;
        }
        @Override
        public String toString() {
            return "Enermy [cd=" + cd + ", level=" + level + ", lock=" + lock
                    + ", currentHp=" + currentHp + ", fullHp=" + fullHp
                    + ", attack=" + attack + ", controlEffect=" + controlEffect
                    + ", shift=" + shift + ", moveSpeed=" + moveSpeed + "]";
        }
        
        
    }
    --------------------------------------------------------------------------
    package com.lrq.test;
    
    public class  Self {
        private int cd;
        private  int level;
        private  boolean lock;
        private  double  currentHp;
        private  double  fullHp;
        private  double attack;
        private  String controlEffect;
        private  String  shift;
        private  double moveSpeed;
        public Self() {
            super();
        }
        public int getCd() {
            return cd;
        }
        public void setCd(int cd) {
            this.cd = cd;
        }
        public int getLevel() {
            return level;
        }
        public void setLevel(int level) {
            this.level = level;
        }
        public boolean isLock() {
            return lock;
        }
        public void setLock(boolean lock) {
            this.lock = lock;
        }
        public double getCurrentHp() {
            return currentHp;
        }
        public void setCurrentHp(double currentHp) {
            this.currentHp = currentHp;
        }
        public double getFullHp() {
            return fullHp;
        }
        public void setFullHp(double fullHp) {
            this.fullHp = fullHp;
        }
        public double getAttack() {
            return attack;
        }
        public void setAttack(double attack) {
            this.attack = attack;
        }
        public String getControlEffect() {
            return controlEffect;
        }
        public void setControlEffect(String controlEffect) {
            this.controlEffect = controlEffect;
        }
        public String getShift() {
            return shift;
        }
        public void setShift(String shift) {
            this.shift = shift;
        }
        public double getMoveSpeed() {
            return moveSpeed;
        }
        public void setMoveSpeed(double moveSpeed) {
            this.moveSpeed = moveSpeed;
        }
        @Override
        public String toString() {
            return "Self [cd=" + cd + ", level=" + level + ", lock=" + lock
                    + ", currentHp=" + currentHp + ", fullHp=" + fullHp
                    + ", attack=" + attack + ", controlEffect=" + controlEffect
                    + ", shift=" + shift + ", moveSpeed=" + moveSpeed + "]";
        }
        
    }
    ---------------------------------------------------------------------------------
    然后建立几个具体策略(Strategy)角色类:
    1.惩戒Discipline(打野专用)
    public interface  Discipline{
         public void use(Self self,Enermy enermy){
                enermy.currentHp - = 850;
                enermy.controlEffect = "眩晕1秒";
        }
    }
    
    2.斩杀(前排专用)
    public interface  Beheaded{
         public void use(Self self,Enermy enermy){
                 enermy.currentHp-= (enermy.fullHp-enermy.currentHp)*14%;
             
        }
    }
    
    3.闪现(adc)
    
    public interface  Flash{
         public void use(Self self,Enermy enermy){
              self.shif+=100;       
              self.controlEffect="向前闪现一小段";
        }
    }
    
    
    4.治疗(adc或者辅助)
    public interface  Treatment{
         public void use(Self self,Enermy enermy){
              self.currentHp+=self.fullHp*15%; 
              self.moveSpeed+= self.moveSpeed*15%;
              self.controlEffect="回复自己与附近队友15%生命值,提高附近友军移动速度15%持续2秒";
        }
    }
    --------------------------------------------------------------------------------------------------------
    然后环境(Context)角色:Summoner----召唤师
    
    public class Summoner{
        //持有一个具体的策略对象
        private  SummonerSpells  summonerSpells;//召唤师技能
        /**
         * 构造函数,传入一个具体的策略对象
         * @param strategy    具体的策略对象
         */
        public Summoner(SummonerSpells  summonerSpells){
            this.summonerSpells= summonerSpells;
        }
        
        /**
         * 计算生命值,控制效果,移速等
         * @param Enermy,Self    敌人,自己
         * @return    
         */
        public void quote(Self self,Enermy enermy){
            return summonerSpells.use(Self self,Enermy enermy);
        }
    }
    --------------------------------------------------------------------------------------------------------
    最后客户端Client :
    public class Client {
    
        public static void main(String[] args) {
            //选择并创建需要使用的策略对象
            Flash flash= new flash(new Self(),new Enermy());
            //创建环境
            Summoner summoner= new Summoner(flash);
            //计算属性
            flash.use();
        }
    
    }
    

    四.策略模式的优缺点

    1. 策略模式的优点:
    
      (1)策略模式提供了管理相关的算法族的办法。策略类的等级结构  
    定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里  
    面,从而避免代码重复。
    
      (2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件  
    语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或  
    行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承  
    的办法还要原始和落后。
    
    2.策略模式的缺点:
    
      (1)客户端必须知道所有的策略类,并自行决定使用哪一个策略  
    类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当  
    的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
    
      (2)由于策略模式把每个具体的策略实现都单独封装成为类,  
    如果备选的策略很多的话,那么对象的数目就会很可观。
    

    相关文章

      网友评论

        本文标题:王者荣耀与Java策略模式

        本文链接:https://www.haomeiwen.com/subject/przguxtx.html