玩游戏的时候,会有关卡以及boss,通过boss战后,获得新装备,新开启关卡,并会提示存储当前进度,以便以后可以再重玩当前boss战,比如生化危机,鬼泣等等杀完一个boss爽了,然后存储下当前进度,但是这种存储都是需要介质持久化,如果需要在内存中长久驻留,那么就要采用一些方式存储。
当玩家创建一个角色的时候,与该角色相关的东西都会附加上,比如装备,角色外貌,场景等等,这些东西封装为一个对象,然后将对象状态保存在外部,就是备忘录模式了,下面为第一版简略类图:
Roll是角色,RollState是角色附加的东西:装备,场景,杀了几个boss,获得的新装备等等也就是当前角色的状态,GameState是用来存储角色状态的类,GameStateManager是角色状态管理类,但是这种方式,只能针对不同角色存储一种状态的情况,
比如鬼泣主角:但丁 当第一关通过后,获得新装备,新关卡,此时存储下来,即GameStateManager.setGameState()方法,内部用map存储即manager.put("但丁",gameState),但是用map只能存储但丁的一个状态,如果再有另外一个角色:恶魔但丁,同样会只能存储一个状态,上面类图只针对不同角色,当前状态,以及上一个状态之间的切换。如果一个角色有多个状态,状态之间跳跃,比如打完第6关,玩家想切换回第3关玩,如果遇见这种情况,那么将GameStateManager的map泛型第二个参数改为聚集即可。第二版类图如下:
:
GameStateManager成员变量第二个泛型参数改为Collection<GameState>,里面参数即可根据角色名字和第几个关卡获取状态,代码如
package designpattern.memento;
public class Roll
{
private RollState rollState = new RollState("默认装备", "默认样子", "出生场景");
private String name;
public Roll(String name)
{
this.name = name;
}
public void killBossA()
{
System.out.println("杀了boss1,获得新装备,开启关卡2");
rollState.setEquipment("新装备");
rollState.setAppearance( "获得新外型");
rollState.setScene("开启关卡2");
}
public void killBossB()
{
System.out.println( "杀了boss2,获得更好的装备,开启更难关卡");
rollState.setEquipment( "更强装备");
rollState.setAppearance( "获得更酷外型");
rollState.setScene(name + "开启关卡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;
}
/** *//**
* 创建备份点
*
* @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 角色状态类
*/
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之前场景 内部使用线性表存储 0即代表玩家出生点,初始场景,一般游戏里面会对每个boss战场景标记
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方法应该改为:
// rollState.setEquipment("新装备A");
// rollState.setAppearance("获得新外型A");
// rollState.setScene("开启关卡2");
rollState = new RollState("新装备A","获得新外型A","开启关卡2");
killBossB方法应该改为:
rollState = new RollState("更强装备B","获得更酷外型B","开启关卡3");
// rollState.setEquipment("更强装备B");
// rollState.setAppearance("获得更酷外型B");
// rollState.setScene(name + "开启关卡3");
否则都传递的是引用,修改的是同一个引用,保存的都是同一个状态。
因为roll角色的状态是通过RollState引用来保存,而不是基本变量和string类型
posted on 2013-09-28 14:57
朔望魔刃 阅读(253)
评论(0) 编辑 收藏 所属分类:
设计模式&&数据结构