游戏开发中奖励领取与发放再普遍不过了,服务需要记录玩家领取的宝箱状态,以免造成重复领取的现象;
记录的方式有很多种,主要还是与客户端沟通,采取合适的方法。
主要使用的一般是两种方法:
1 记录已领取的宝箱id
服务端只需要使用一个集合,记录玩家已领取的宝箱id,每次玩家领取时,客户端把宝箱id传给服务器,服务器先判断该id是否领取。
这个逻辑比较简单,就不细说了。
2 使用一个整数的二进制位来表示宝箱的领取状态
这种方式只需要用一个int
值,就可以表示所有的状态。用起来也比较高大上,不过逻辑上比上一种复杂点,需要掌握位运算。
public class BoxStatus {
/**
* 宝箱领取状态
*/
private int status;
public BoxStatus() {
}
/**
* 初始化宝箱状态
* @param initStatus 初始值
*/
public BoxStatus(int initStatus) {
status = initStatus;
}
/*
如果 status = 0, pos = 2
status = 0000
1 << pos ---> 0001 << 2 = 0100
status = 0000 | 0100 = 0100 = 4
*/
/**
* 领取宝箱
* @param pos 宝箱位置 从1开始
*/
public void openBox(int pos) {
status |= (1 << pos); // 将对应宝箱的状态位置为1
}
/**
* 判断宝箱是否已领取
* @param pos 宝箱位置 从1开始
*/
public boolean isBoxOpened(int pos) {
return ((status >> pos) & 1) == 1; // 判断对应宝箱的状态位是否为1
}
// 返回当前宝箱状态
public int getStatus() {
return status;
}
/**
* 转二进制 0未领取 1领取
*/
public String toBinary() {
return Integer.toBinaryString(status);
}
@Override
public String toString() {
return "{" +
"status = " + status +
", binaryStatus = " + toBinary() +
'}';
}
}
@Test
public void test() {
BoxStatus boxStatus = new BoxStatus();
System.out.println("初始宝箱状态 = " + boxStatus);
boxStatus.openBox(1);
System.out.println("领取第1号宝箱 = " + boxStatus);
boxStatus.openBox(2);
System.out.println("领取第2号宝箱 = " + boxStatus);
System.out.println("2号宝箱状态:" + boxStatus.isBoxOpened(2));
System.out.println("8号宝箱状态:" + boxStatus.isBoxOpened(8));
/*
初始宝箱状态 = {status = 0, binaryStatus = 0}
领取第1号宝箱 = {status = 2, binaryStatus = 10}
领取第2号宝箱 = {status = 6, binaryStatus = 110}
2号宝箱状态:true
8号宝箱状态:false
*/
}
在示例代码中,我们使用一个整数变量 status
来表示宝箱的领取状态。status
的每一位代表一个宝箱,当对应位为1
时表示该宝箱已经领取,为0
时表示未领取。通过位操作,我们可以高效地对宝箱的领取状态进行更新和查询。
在 openBox
方法中,我们使用位操作 |=
来将对应宝箱的状态位置为1
。在 isBoxOpened
方法中,我们使用位操作 >>
和 &
来判断对应宝箱的状态位是否为1
。
总结
以上两种方式我在项目中都使用过,具体用哪种要根据实际情况选择。
比如我的第一家公司客户端是Cocos2d-lua
引擎,开发语言是lua
,不支持直接使用位运算,需要另外写逻辑实现,那不如直接用第一种方式简单。
第二家公司客户端是Unity
引擎,开发语言是C#
,可以直接使用位运算,并且客户端愿意这么做,那就采用第二种方式。