Pawn中基于枚举的三维数组实现方案在Java中是否有类似替代方法?
Question
本人曾使用Pawn语言编写代码,目前转用其他编程语言。此前在Pawn中,我通过枚举实现了一种三维数组结构,用于存储玩家相关信息,具体代码如下:
enum healthHack { Float:acHealth, bool:hImmune, bool:aImmune, Float:acArmour, hcTimer, pTick, bool:afkImmune, bool:hasSpawned }; new hcInfo[MAX_PLAYERS][healthHack];假设player_id为5、MAX_PLAYERS为500,访问数组元素时可采用如下方式:
hcInfo[player_id][hasSpawned] = false; hcInfo[player_id][acHealth] = 100;现咨询:Java语言中是否存在类似的、可通过枚举实现便捷访问的三维数组方案?
Answer
Java里没有和Pawn这种「枚举直接作为数组维度索引」完全一致的语法,但我们可以通过枚举+面向对象设计实现类似的便捷、类型安全的玩家信息存储方案,下面给你两种可行的思路:
1. 枚举+自定义索引(贴近Pawn的数组访问风格)
Pawn的枚举本质是给数组的第二维字段分配了别名索引,我们可以在Java里用枚举自定义索引来模拟这种逻辑,但要注意Java数组是单一类型的,所以如果你的属性有多种类型(float、boolean、int),建议拆分多个类型数组(避免Object数组的类型不安全问题)。
先定义带自定义索引的枚举:
enum PlayerAttribute { AC_HEALTH(0), H_IMMUNE(1), A_IMMUNE(2), AC_ARMOUR(3), HC_TIMER(4), P_TICK(5), AFK_IMMUNE(6), HAS_SPAWNED(7); private final int index; PlayerAttribute(int index) { this.index = index; } public int getIndex() { return index; } }
然后创建对应类型的数组:
// 定义常量 private static final int MAX_PLAYERS = 500; // 按属性类型拆分数组,类型更安全 private static float[] playerHealth = new float[MAX_PLAYERS]; private static boolean[] playerHImmune = new boolean[MAX_PLAYERS]; private static boolean[] playerAImmune = new boolean[MAX_PLAYERS]; private static float[] playerArmour = new float[MAX_PLAYERS]; private static int[] playerTimer = new int[MAX_PLAYERS]; private static int[] playerTick = new int[MAX_PLAYERS]; private static boolean[] playerAfkImmune = new boolean[MAX_PLAYERS]; private static boolean[] playerHasSpawned = new boolean[MAX_PLAYERS];
访问方式示例:
int playerId = 5; // 设置属性 playerHasSpawned[playerId] = false; playerHealth[playerId] = 100.0f; // 获取属性 boolean hasSpawned = playerHasSpawned[playerId]; float acHealth = playerHealth[playerId];
⚠️ 注意:不建议用枚举的ordinal()来作为索引,因为枚举的顺序一旦修改(比如插入新属性到中间),ordinal()的值会变化,导致数组访问出错,自定义索引更稳定。
2. 面向对象封装(更符合Java最佳实践)
这种方式比数组+枚举更优雅,类型安全且可读性更高,本质是把每个玩家的所有属性封装成一个类,然后用数组存储每个玩家的实例:
首先创建玩家信息类:
class PlayerInfo { private float acHealth; private boolean hImmune; private boolean aImmune; private float acArmour; private int hcTimer; private int pTick; private boolean afkImmune; private boolean hasSpawned; // Getter和Setter方法 public float getAcHealth() { return acHealth; } public void setAcHealth(float acHealth) { this.acHealth = acHealth; } public boolean isHImmune() { return hImmune; } public void setHImmune(boolean hImmune) { this.hImmune = hImmune; } public boolean isHasSpawned() { return hasSpawned; } public void setHasSpawned(boolean hasSpawned) { this.hasSpawned = hasSpawned; } // 其他属性的Getter/Setter自行补充 }
然后初始化和访问:
private static final int MAX_PLAYERS = 500; private static PlayerInfo[] hcInfo = new PlayerInfo[MAX_PLAYERS]; // 初始化所有玩家的信息实例 static { for (int i = 0; i < MAX_PLAYERS; i++) { hcInfo[i] = new PlayerInfo(); } } // 访问示例 int playerId = 5; hcInfo[playerId].setHasSpawned(false); hcInfo[playerId].setAcHealth(100.0f); boolean playerSpawned = hcInfo[playerId].isHasSpawned(); float health = hcInfo[playerId].getAcHealth();
这种方式完全不需要枚举,但实现了比Pawn更安全的属性访问,也是Java开发中存储这类结构化数据的标准做法。
内容的提问来源于stack exchange,提问作者Sunehildeep Singh
相关产品推荐
相关产品推荐

