维系一个游戏的交易系统,货币和道具系统是密不可分的。那么我们这一样来学习一个货币系统。
货币存储类型com.server.game.scene.currency.CurrencyStore
/**
* 货币自定义储存
*/
public interface CurrencyStore {
/**货币增加操作*/
ResultCode add(Long roleId, int size);
/** 货币减少操作 */
ResultCode reduce(Long roleId, int size);
/**获取货币的数量*/
int getCurrency(Long roleId);
/**是否足够数量*/
boolean isEnough(Long roleId, int number);
}
继承这个类的是具体的货币
子类的操作就可以将具体的自定义货币类型放入到自定义的地方去(如自己定义的数据表中的某个地方)
而具体的货币类型则放在com.server.game.scene.currency.Currency。如钻石、绑定钻石、银币、金币等。
/**
* 货币类
*/
public class Currency {
// 货币当前数量
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public synchronized boolean add(int addNum) {
if (addNum < 0)
addNum = 0;
if (num > Integer.MAX_VALUE - addNum) {
num = Integer.MAX_VALUE;
} else {
num += addNum;
}
return true;
}
public synchronized boolean reduce(int reduceNum) {
if (reduceNum < 0)
reduceNum = 0;
if (num < reduceNum) {
return false;
}
num -= reduceNum;
return true;
}
public synchronized boolean clear() {
if (num < 0) {
return false;
}
num = 0;
return true;
}
}
定义货币的类型在一个枚举中,集中管理各种货币。
/**
* 货币类型
*/
public enum CurrencyType {
/**
* 钻石
*/
CURRENCY_1001(1001, "钻石"),
/**
* 绑定钻石
*/
CURRENCY_1002(1002, "绑定钻石"),
}
货币重定向处理类
/**
*
* 特殊货币重定向处理
* 用于自己特殊处理的货币储存/获取方式
*
*/
public enum CurrencyRedirectType {
/** 仙玉 */
XIANYU(CurrencyType.CURRENCY_1001, "仙玉") ,;
CurrencyRedirectType(CurrencyType type, String name, CurrencyStore currencyStore, AdditionCal additionCal) {
this.type = type;
this.currencyStore = currencyStore;
this.additionCal = additionCal;
}
//货币类型
protected final CurrencyType type;
//自定义储存获取方式(每个自定义货币都要继承这个接口)
protected final CurrencyStore currencyStore;
//加成计算器(用于对货币的加成计算,如经验)
protected final AdditionCal additionCal;
}
当然还有一个重要的类就是货币的管理类com.server.game.scene.currency.manager.CurrencyMgr
第一步:客户端请求,服务端查看配置信息(是一个四段式的方式如2:100002&10&0 主类:道具id&数量&是否绑定)
第二步:调用增加资源接口com.server.game.scene.item.manager.ResourceLogic#addResource
第三步:跳过了背包的操作(原因我后门讲述),并进入调用
ResultCode resultCode = ItemTypeEnum.Currency_Type.addResource(roleId, itemConfigs, reason);
CurrencyMgr.getInstance().addCurrency(roleId, itemConfigs, reason);
第四步:查看是什么类型的货币
CurrencyType type = CurrencyType.getCurrencyType(itemConfig.getItemModelId());
第五步:通过货币类型去找特殊货币重定向处理CurrencyRedirectType,并调用对应的钩子方法
CurrencyRedirectType redirectType = CurrencyRedirectType.getType(type);
第六步:增加货币资源
最重要的增加货币的代码如下
/**
* 增加资源
*/
public ResultMsgConst.ResultCode addCurrency(CurrencyType type, int size) {
//是否走自己一套的处理
CurrencyRedirectType redirectType = CurrencyRedirectType.getType(type);
if (redirectType != null) {
CurrencyStore currencyStore = redirectType.getCurrencyStore();
if (currencyStore != null) {
//这里才是真正走自定义逻辑的地方
ResultMsgConst.ResultCode resultCode = currencyStore.add(getId(), size);
if (resultCode.isSuccess()) {
PushEventLogic.pushEvent(getId(), MsgModuleType.CurrencyDataMsg.getSource());
}
return resultCode;
}
}
//走真实货币逻辑
Currency currency = getAndCreateCurrency(type);
if (currency.add(size)) {
if (redirectType == null || redirectType.getCurrencyStore() == null) {
PushEventLogic.pushEvent(getId(), MsgModuleType.CurrencyDataMsg.getSource());
}
return ResultMsgConst.ResultCode.SUCCESS;
}
return ResultMsgConst.ResultCode.DATA_ERROR;
}
以上就是真实货币和自定义货币的一些设计方式。大家有更好的设计方式可以沟通一下。