隨筆-95  評論-31  文章-10  trackbacks-0

                玩游戲的時候,會有關(guān)卡以及boss,通過boss戰(zhàn)后,獲得新裝備,新開啟關(guān)卡,并會提示存儲當(dāng)前進(jìn)度,以便以后可以再重玩當(dāng)前boss戰(zhàn),比如生化危機(jī),鬼泣等等殺完一個boss爽了,然后存儲下當(dāng)前進(jìn)度,但是這種存儲都是需要介質(zhì)持久化,如果需要在內(nèi)存中長久駐留,那么就要采用一些方式存儲。
                當(dāng)玩家創(chuàng)建一個角色的時候,與該角色相關(guān)的東西都會附加上,比如裝備,角色外貌,場景等等,這些東西封裝為一個對象,然后將對象狀態(tài)保存在外部,就是備忘錄模式了,下面為第一版簡略類圖:
          Roll是角色,RollState是角色附加的東西:裝備,場景,殺了幾個boss,獲得的新裝備等等也就是當(dāng)前角色的狀態(tài),GameState是用來存儲角色狀態(tài)的類,GameStateManager是角色狀態(tài)管理類,但是這種方式,只能針對不同角色存儲一種狀態(tài)的情況,
          比如鬼泣主角:但丁  當(dāng)?shù)谝魂P(guān)通過后,獲得新裝備,新關(guān)卡,此時存儲下來,即GameStateManager.setGameState()方法,內(nèi)部用map存儲即manager.put("但丁",gameState),但是用map只能存儲但丁的一個狀態(tài),如果再有另外一個角色:惡魔但丁,同樣會只能存儲一個狀態(tài),上面類圖只針對不同角色,當(dāng)前狀態(tài),以及上一個狀態(tài)之間的切換。如果一個角色有多個狀態(tài),狀態(tài)之間跳躍,比如打完第6關(guān),玩家想切換回第3關(guān)玩,如果遇見這種情況,那么將GameStateManager的map泛型第二個參數(shù)改為聚集即可。第二版類圖如下:

          GameStateManager成員變量第二個泛型參數(shù)改為Collection<GameState>,里面參數(shù)即可根據(jù)角色名字和第幾個關(guān)卡獲取狀態(tài),代碼如

          package designpattern.memento;

          public class Roll
          {
              
          private RollState rollState = new RollState("默認(rèn)裝備""默認(rèn)樣子""出生場景");

              
          private String name;

              
          public Roll(String name)
              
          {
                  
          this.name = name;
              }


              
          public void killBossA()
              
          {
                  System.out.println(
          "殺了boss1,獲得新裝備,開啟關(guān)卡2");
                  rollState.setEquipment(
          "新裝備");
                  rollState.setAppearance( 
          "獲得新外型");
                  rollState.setScene(
          "開啟關(guān)卡2");
              }


              
          public void killBossB()
              
          {
                  System.out.println( 
          "殺了boss2,獲得更好的裝備,開啟更難關(guān)卡");
                  rollState.setEquipment( 
          "更強(qiáng)裝備");
                  rollState.setAppearance( 
          "獲得更酷外型");
                  rollState.setScene(name 
          + "開啟關(guān)卡3");
              }


              
          public RollState getRollState()
              
          {
                  
          return rollState;
              }


              
          public void setRollState(RollState rollState)
              
          {
                  
          this.rollState = rollState;
              }


              
          public String getName()
              
          {
                  
          return name;
              }


              
          public void setName(String name)
              
          {
                  
          this.name = name;
              }


              
          /**
               * 創(chuàng)建備份點
               * 
               * 
          @return
               
          */

              
          public GameState createGameState()
              
          {
                  
          return new GameState(rollState);
              }


              
          /**
               * 獲得上次備份點
               * 
               * 
          @param gameState
               
          */

              
          public void restoreGameState(GameState gameState)
              
          {
                  
          this.rollState = gameState.getRollState();
              }


              @Override
              
          public String toString()
              
          {
                  
          return name+":"+this.getRollState().getEquipment()+""+this.getRollState().getAppearance()+""+this.getRollState().getScene();
              }

          }

           

          package designpattern.memento;

          /**
           * 
          @author Administrator 角色狀態(tài)類
           
          */

          public class RollState
          {

              
          private String equipment;
              
          private String appearance;
              
          private String scene;

              
          public RollState()
              
          {
              }


              
          public RollState(String equipment, String appearance, String scene)
              
          {
                  
          this.equipment = equipment;
                  
          this.appearance = appearance;
                  
          this.scene = scene;
              }


              
          public String getEquipment()
              
          {
                  
          return equipment;
              }


              
          public void setEquipment(String equipment)
              
          {
                  
          this.equipment = equipment;
              }


              
          public String getAppearance()
              
          {
                  
          return appearance;
              }


              
          public void setAppearance(String appearance)
              
          {
                  
          this.appearance = appearance;
              }


              
          public String getScene()
              
          {
                  
          return scene;
              }


              
          public void setScene(String scene)
              
          {
                  
          this.scene = scene;
              }


          }

           

          package designpattern.memento;

          public class GameState
          {
              
          private RollState rollState;

              
          public GameState(RollState rollState)
              
          {
                  
          this.rollState = rollState;
              }


              
          public RollState getRollState()
              
          {
                  
          return rollState;
              }


              
          public void setRollState(RollState rollState)
              
          {
                  
          this.rollState = rollState;
              }


          }

           

          package designpattern.memento;

          import java.util.ArrayList;
          import java.util.Arrays;
          import java.util.HashMap;
          import java.util.Map;

          public class GameStateManager
          {
              
          private Map<String, ArrayList<GameState>> managers = new HashMap<String,ArrayList<GameState>>();

              
          public GameState getGameState(String rollName, int indexBoss)
              
          {
                  
          return managers.get(rollName).get(indexBoss);
              }


              
          public void setGameState(String rollName, GameState gameState)
              
          {
                  ArrayList
          <GameState> list = null;
                  
          if ((list = managers.get(rollName)) != null)
                  
          {
                      list.add(gameState);
                  }
           else
                  
          {
                      managers.put(rollName,
          new ArrayList<GameState>(Arrays.asList(gameState)));
                  }

                  System.err.println(managers.get(rollName));
              }

              
          }

           

          package designpattern.memento;

          public class Client
          {
              
          public static void main(String[] args)
              
          {
                  Roll roll 
          = new Roll( "但丁");
                  GameStateManager states 
          = new GameStateManager();
                  
          //玩家初始場景,即出生點
                  states.setGameState(roll.getName(), roll.createGameState());
                  
                  
                  roll.killBossA();
                  
          //殺完bossA 存儲
                  states.setGameState(roll.getName(), roll.createGameState());
                  
                  roll.killBossB();
                  
          //殺完bossB存儲
                  states.setGameState(roll.getName(), roll.createGameState());
                  
                  
          //玩家想返回殺bossA之前場景  內(nèi)部使用線性表存儲 0即代表玩家出生點,初始場景,一般游戲里面會對每個boss戰(zhàn)場景標(biāo)記
                  roll.restoreGameState(states.getGameState(roll.getName(), 0));
                  System.out.println(roll.toString());
                  
                  roll.restoreGameState(states.getGameState(roll.getName(), 
          1));
                  System.out.println(roll.toString());
                  
                  
              }

          }


          這跟事物原理一致 
          上面有個bug,Roll類里面killBossA方法應(yīng)該改為:
          //  rollState.setEquipment("新裝備A");
          //  rollState.setAppearance("獲得新外型A");
          //  rollState.setScene("開啟關(guān)卡2");
          rollState = new RollState("新裝備A","獲得新外型A","開啟關(guān)卡2");
          killBossB方法應(yīng)該改為:
            rollState = new RollState("更強(qiáng)裝備B","獲得更酷外型B","開啟關(guān)卡3");
          //  rollState.setEquipment("更強(qiáng)裝備B");
          //  rollState.setAppearance("獲得更酷外型B");
          //  rollState.setScene(name + "開啟關(guān)卡3");

          否則都傳遞的是引用,修改的是同一個引用,保存的都是同一個狀態(tài)。
          因為roll角色的狀態(tài)是通過RollState引用來保存,而不是基本變量和string類型



           




           
           
                    


          posted on 2013-09-28 14:57 朔望魔刃 閱讀(264) 評論(0)  編輯  收藏 所屬分類: 設(shè)計模式&&數(shù)據(jù)結(jié)構(gòu)
          主站蜘蛛池模板: 安陆市| 沂南县| 桂林市| 内乡县| 抚远县| 明星| 东宁县| 丰县| 崇信县| 舟曲县| 西昌市| 宿松县| 葫芦岛市| 六安市| 贵南县| 巢湖市| 渝北区| 邯郸县| 龙岩市| 安平县| 灵宝市| 宁陕县| 庄河市| 松江区| 紫阳县| 察雅县| 鸡西市| 舞阳县| 兴安县| 兰考县| 京山县| 南安市| 策勒县| 廊坊市| 浪卡子县| 拉孜县| 长泰县| 循化| 林芝县| 团风县| 乳山市|