因为作者是从事游戏开发相关的 在这里安利一篇关于道具开相关的设计,不足之处敬请谅解
当然每个游戏都会有不同的设计逻辑 但是总体的设计思想还都是大同小异 这里 先提供一个简易的道具系统 (没有格子,没有叠加) 后面再慢慢提供复杂的设计
设计思路 :首先我们启动服务器就会去注册对应的道具 每个道具都会具备某种或者多种用途 那么一定会有一个物品行为(使用)的基类 基类包括判断是否可以使用 正常使用等相关的接口方法
import com.gameart.backpack.enums.ActionType;
import com.gameart.g1.config.utils.ItemPair;
import java.util.List;
/**
* 物品行为
*/
public interface IItemAction {
ActionType getActionType();
/**
* 能否够执行行为
*
* @param playerId
* @param itemId
* @param itemCount
* @return
*/
boolean canAct(long playerId, int itemId, long itemCount);
/**
* 行为
*
* @param playerId
* @param itemId
* @param itemCount
*/
void act(long playerId, int itemId, long itemCount);
/**
* 行为 返会相应的奖励
*
* @param playerId
* @param itemId
* @param itemCount
*/
List<ItemPair<Integer, Long>> actReward(long playerId, int itemId, long itemCount);
}
@TypeManagered
public abstract class AbstractItemAction implements IItemAction {
private ActionType actionType;
public AbstractItemAction(ActionType actionType) {
this.actionType = actionType;
}
@Override
public ActionType getActionType() {
return this.actionType;
}
@Override
public boolean canAct(long playerId, int itemId, long itemCount) {
return true;
}
@Override
public void act(long playerId, int itemId, long itemCount) {
}
public List<ItemPair<Integer, Long>> actReward(long playerId, int itemId, long num) {
return null;
}
}
在我们这里 道具使用只会出现2种效果 一个是走掉落 一个是走奖励 那么枚举如下
import java.util.HashMap;
import java.util.Map;
public enum ActionType {
/**
* ------------------------ 玩家道具------------------------------------
*/
ITEM_DROP(7),//道具掉落
ITEM_REWARD(15),//道具(奖励道具)
;
private static final Map<Integer, ActionType> map = new HashMap<>();
static {
ActionType[] types = ActionType.values();
for (ActionType type : types) {
map.put(type.value, type);
}
}
private final int value;
private ActionType(int value) {
this.value = value;
}
public static ActionType type(int value) {
return map.get(value);
}
public static Map<Integer, ActionType> getMap() {
return map;
}
public int getValue() {
return value;
}
}
当然 我们还需要来一个对应枚举的实现类
掉落的实现:
@TypeManagered
public class ItemResourceAction extends AbstractItemAction {
@Autowired
private IItemResourceManager itemResourceManager;
@Autowired
private RandDropManager randDropManager;
@Autowired
private DataCenterManager dataCenterManager;
public ItemResourceAction() {
super(ActionType.ITEM_DROP);//对应掉落的实现
}
@Override
public boolean canAct(long playerId, int itemId, long itemCount) {
PlayerDataCenter playerDataCenter = dataCenterManager.getPlayerDataCenter(playerId);
CacheItem cacheItem = playerDataCenter.getData(CacheItem.class);
Item item = cacheItem.getItemMap().get(itemId);
if (item == null) {
return false;
}
return item.getNum() >= itemCount;
}
@Override
public void act(long playerId, int itemId, long itemCount) {
}
@Override
public List<ItemPair<Integer, Long>> actReward(long playerId, int itemId, long itemCount) {
CItem cItem = ConfigManager.getConfig(CItem.class, itemId);
itemResourceManager.ductItem(playerId, new ItemPair<>(itemId, itemCount), ReasonType.USE_ITEM);
return randDropManager.reward(playerId, cItem.getActionParameters(), itemCount, 1);
}
}
奖励的实现:
@TypeManagered
public class ItemRewardAction extends AbstractItemAction {
public ItemRewardAction() { super(ActionType.ITEM_REWARD); }
@Autowired
private IItemResourceManager itemResourceManager;
@Autowired
private DataCenterManager dataCenterManager;
@Override
public boolean canAct(long playerId, int itemId, long itemCount) {
PlayerDataCenter playerDataCenter = dataCenterManager.getPlayerDataCenter(playerId);
CacheItem cacheItem = playerDataCenter.getData(CacheItem.class);
Item item = cacheItem.getItemMap().get(itemId);
if (item == null) {
return false;
}
return item.getNum() >= itemCount;
}
@Override
public boolean canAct(long playerId, int itemId, long itemCount) {
PlayerDataCenter playerDataCenter = dataCenterManager.getPlayerDataCenter(playerId);
CacheItem cacheItem = playerDataCenter.getData(CacheItem.class);
Item item = cacheItem.getItemMap().get(itemId);
if (item == null) {
return false;
}
return item.getNum() >= itemCount;
}
@Override
public void act(long playerId, int itemId, long itemCount) {
}
@Override
public List<ItemPair<Integer, Long>> actReward(long playerId, int itemId, long itemCount) {
CItem cItem = ConfigManager.getConfig(CItem.class, itemId);
boolean flag= itemResourceManager.ductItem(playerId, new ItemPair<>(itemId, itemCount), ReasonType.USE_ITEM);
if(!flag){
return null;
}
CReward cReward=ConfigManager.getConfig(CReward.class,cItem.getActionParameters());
if(cReward==null || cReward.getReward()==null){
return null;
}
List<ItemPair<Integer, Long>> rewardResult =cReward.getReward();
itemResourceManager.reward(playerId, cReward.getReward(),ReasonType.USE_ITEM_REWARD);
return rewardResult;
}
}
以上就是使用的效果 那么我们还需要根据策划配置表拿到道具进行注册行为 如下:
public class ItemActionService extends ManagerAdapter {
private static Map<ActionType, IItemAction> aClassitemActions = new HashMap<>();
/**
* 获取所有的行为
*
* @return 行为对象列表
*/
public static IItemAction getItemActions(int subType) {
return aClassitemActions.get(ActionType.type(subType));
}
/**
* 注册item行为
*/
private static void registerActionClass(ActionType actionType, IItemAction itemActionClass) {
if (!aClassitemActions.containsKey(actionType)) {
aClassitemActions.put(actionType, itemActionClass);
}
}
@Override
public void awake() {
List<AbstractItemAction> beans = TypeManager.getInstance().getTypes(AbstractItemAction.class);
for (AbstractItemAction acction : beans) {
registerActionClass(acction.getActionType(), acction);
}
}
}
到此为止 我们已经完成了配置表 现有道具所具备的功能的注册 。