前言
这个功能是针对每个玩家以及每个技能或者事件的冷却去编写的。
测试使用时用的是spigot1.16.5的api。
文章中看到技能或者事件,可以理解为一个意思,只是有时候表达为事件有时候表达为技能
注
:此文章仅是展示代码及代码用法,并不是教程!!
1.理论
既然是针对每个玩家及其技能或事件来的话,那就需要一个表来存储数据用于判断。
2.实践
首先创建一个存储数据的Map表:
表
1
| private Map<UUID, Map<String, Long>> playerCooldowns;
|
类
这里的map键用的uuid会好区分,然后对应的值是另一个map,这个map存储的键是技能或事件名称,而值存储的是冷却所需要的时间,这样一个满足理论的变量就写好了。
然后创建一个类,就叫做CooldownSystem
吧,顺便把构造函数写好:
1 2 3 4 5 6 7 8
| public class CooldownSystem { private Map<UUID, Map<String, Long>> playerCooldowns;
public CooldownSystem() { playerCooldowns = new HashMap<>(); } } ## 接口
|
我们再创建一个接口用于这个类的某某事件的开放处理,这里这个接口我就叫做OnCooldownInterFace
了:
1 2 3 4 5
| public interface OnCooldownInterFace { void sendOnCooldownMsg(String skillName,long RemainingCooldownTime); void createCooldownSkill(String skillName); void sendLastCoolDownMsg(String skillName); }
|
sendOnCooldownMsg
这个方法用于处理事件处于冷却时发生的事情
createCooldownSkill
用于冷却开始时发生的事情
sendLastCoolDownMsg
用于冷却结时发生的事情
实际方法
接下来写创建一个冷却的方法startCooldown
:
1 2 3 4 5 6 7
| public void startCooldown(UUID playerId, String skillName, long cooldownSeconds) { long cooldownEndTime = System.currentTimeMillis() + cooldownSeconds * 1000L;
Map<String, Long> playerCooldownsMap = playerCooldowns.getOrDefault(playerId, new HashMap<>()); playerCooldownsMap.put(skillName, cooldownEndTime); playerCooldowns.put(playerId, playerCooldownsMap); }
|
再就是是否正在冷却期间的方法isOnCooldown
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public boolean isOnCooldown(UUID playerId, String skillName) { if (playerCooldowns.containsKey(playerId)) { Map<String, Long> playerCooldownsMap = playerCooldowns.get(playerId); if (playerCooldownsMap.containsKey(skillName)) { long cooldownEndTime = playerCooldownsMap.get(skillName); if (System.currentTimeMillis() < cooldownEndTime) { return true; } else { playerCooldownsMap.remove(skillName); if (playerCooldownsMap.isEmpty()) { playerCooldowns.remove(playerId); } } } } return false; }
|
然后可以根据需求附加一些需要的方法,例如获取剩余冷却描述,清除冷却之类的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public long getRemainingCooldownTime(UUID playerId, String skillName) { if (isOnCooldown(playerId, skillName)) { long cooldownEndTime = playerCooldowns.get(playerId).get(skillName); return (cooldownEndTime - System.currentTimeMillis()) / 1000L; } return 0; }
public void clearCooldown(UUID playerId, String skillName) { if (playerCooldowns.containsKey(playerId)) { Map<String, Long> playerCooldownsMap = playerCooldowns.get(playerId); playerCooldownsMap.remove(skillName); if (playerCooldownsMap.isEmpty()) { playerCooldowns.remove(playerId); } } }
public void clearAllCooldowns(UUID playerId) { playerCooldowns.remove(playerId); }
|
getRemainingCooldownTime
获取剩余描述
clearCooldown
清除某个事件的冷却
clearAllCooldowns
清除某个玩家的所有事件或者技能的冷却
活用
实际上到了这里这个冷却的方法已经算写好了,但为了更高的活用性别忘了之前创建的接口,根据之前的接口我们创建一个更简洁的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public void OnColldownMenu(UUID playerId, String skillName, long cooldownSeconds,OnCooldownInterFace onCooldownInterFace){ if (isOnCooldown(playerId,skillName)){ onCooldownInterFace.sendOnCooldownMsg(skillName,getRemainingCooldownTime(playerId,skillName)); return; } startCooldown(playerId,skillName,cooldownSeconds); onCooldownInterFace.createCooldownSkill(skillName); new BukkitRunnable() { @Override public void run() { onCooldownInterFace.sendLastCoolDownMsg(skillName); } }.runTaskLater(你插件的主类,20 * cooldownSeconds); }
|
这样这个类就变得比较活用了,完整的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| public class CooldownSystem { private Map<UUID, Map<String, Long>> playerCooldowns;
public CooldownSystem() { playerCooldowns = new HashMap<>(); } public void OnColldownMenu(UUID playerId, String skillName, long cooldownSeconds,OnCooldownInterFace onCooldownInterFace){ if (isOnCooldown(playerId,skillName)){ onCooldownInterFace.sendOnCooldownMsg(skillName,getRemainingCooldownTime(playerId,skillName)); return; } startCooldown(playerId,skillName,cooldownSeconds); onCooldownInterFace.createCooldownSkill(skillName); new BukkitRunnable() { @Override public void run() { onCooldownInterFace.sendLastCoolDownMsg(skillName); } }.runTaskLater(aom.plugin,20 * cooldownSeconds); } public interface OnCooldownInterFace { void sendOnCooldownMsg(String skillName,long RemainingCooldownTime); void createCooldownSkill(String skillName); void sendLastCoolDownMsg(String skillName); }
public void startCooldown(UUID playerId, String skillName, long cooldownSeconds) { long cooldownEndTime = System.currentTimeMillis() + cooldownSeconds * 1000L;
Map<String, Long> playerCooldownsMap = playerCooldowns.getOrDefault(playerId, new HashMap<>()); playerCooldownsMap.put(skillName, cooldownEndTime); playerCooldowns.put(playerId, playerCooldownsMap); }
public boolean isOnCooldown(UUID playerId, String skillName) { if (playerCooldowns.containsKey(playerId)) { Map<String, Long> playerCooldownsMap = playerCooldowns.get(playerId); if (playerCooldownsMap.containsKey(skillName)) { long cooldownEndTime = playerCooldownsMap.get(skillName); if (System.currentTimeMillis() < cooldownEndTime) { return true; } else { playerCooldownsMap.remove(skillName); if (playerCooldownsMap.isEmpty()) { playerCooldowns.remove(playerId); } } } } return false; }
public long getRemainingCooldownTime(UUID playerId, String skillName) { if (isOnCooldown(playerId, skillName)) { long cooldownEndTime = playerCooldowns.get(playerId).get(skillName); return (cooldownEndTime - System.currentTimeMillis()) / 1000L; } return 0; }
public void clearCooldown(UUID playerId, String skillName) { if (playerCooldowns.containsKey(playerId)) { Map<String, Long> playerCooldownsMap = playerCooldowns.get(playerId); playerCooldownsMap.remove(skillName); if (playerCooldownsMap.isEmpty()) { playerCooldowns.remove(playerId); } } }
public void clearAllCooldowns(UUID playerId) { playerCooldowns.remove(playerId); } }
|
使用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| CooldownSystem cooldownSystem = new CooldownSystem(); cooldownSystem.OnColldownMenu("玩家的uid", "技能或事件名称", 冷却时间L, new CooldownSystem.OnCooldownInterFace() { @Override public void sendOnCooldownMsg(String skillName, long RemainingCooldownTime) { }
@Override public void createCooldownSkill(String skillName) { }
@Override public void sendLastCoolDownMsg(String skillName) { } });
|