为了将玩家伪装成另一个实体,我做了一个伪装课程,你可以在这里看到:
public class Disguise
{
private static HashSet<Disguise> disguises = new HashSet<>();
private net.minecraft.server.v1_8_R2.EntityLiving nmsEntity;
private Player disguise;
public Disguise(Player disguise, EntityLiving entity, boolean affectLogin)
{
if(affectLogin)
disguises.add(this);
this.disguise = disguise;
this.nmsEntity = entity;
}
public Disguise(Player disguise, EntityLiving entity)
{
this(disguise, entity, true);
}
public void send(Player visible)
{
if(visible == disguise)
return;
EntityPlayer player = NMSUtils.getNMSPlayer(visible);
nmsEntity.setPosition(player.locX, player.locY, player.locZ);
nmsEntity.d(disguise.getEntityId());
nmsEntity.setCustomName(disguise.getDisplayName());
nmsEntity.setCustomNameVisible(true);
PacketPlayOutSpawnEntityLiving spawn = new PacketPlayOutSpawnEntityLiving(nmsEntity);
PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(disguise.getEntityId());
player.playerConnection.sendPacket(destroy);
player.playerConnection.sendPacket(spawn);
}
public void send(List<Player> visible)
{
for(Player player : visible)
send(player);
}
public void send(Player... visible)
{
send(Arrays.asList(visible));
}
public void send()
{
send(new ArrayList<>(Bukkit.getOnlinePlayers()));
}
public Player getDisguised()
{
return disguise;
}
public static HashSet<Disguise> getDisguises()
{
return disguises;
}
}
我还有一个静态HashSet,它存储所有实例。我这样做是因为我希望登录的玩家能够看到伪装,并且我想在玩家退出时从玩家身上移除伪装。静态HashSet是这样做的方式(就像我做的那样)?如果没有,应该怎么做?
答案 0 :(得分:3)
static
正在要求它。就其性质而言,它很容易“滥用”,但这只是挑战的一部分。
如果说完了所有内容,如果你的mod做了你需要做的事情而没有懈怠,不要过分强调这个粒度级别(特定变量)的最佳实践。它不可能在范围上扩展到设计不良会给您带来问题的程度。毕竟,它不是生命支持系统。
如果你想练习好形式以获得乐趣,我的第一直觉就是将你的管理逻辑从Disguise转移到(例如)DisguiseManager类,并通过manager类处理所有伪装创建/破坏。不太复杂的是隐私上的私有构造函数和静态创建/销毁方法。像你发布的构造函数中的全局副作用通常是不好的形式。
答案 1 :(得分:2)
基本上每次调用构造函数时,都希望将this
添加到全局位置。
没关系,但有两个问题:
this
是危险的,需要仔细分析。 (你的代码在这方面有问题)this
在并发环境中更成问题)答案 2 :(得分:2)
当代码增长时,使用静态对象会变得非常令人沮丧,并且所述对象有许多访问器。如果您要调试代码,那么如何捕获操作HashSet的确切代码?
为什么不使用HashSet重构客户端,以通过getter获取它?将HashSet实例封装为Singleton怎么样?听起来好像只创建了一个HashSet来存储玩家/伪装。
通过Singleton,有了任何类型的getter方法,您可以在访问HashSet之前或之后轻松添加其他代码。例如,在每次使用返回HashSet的方法之后,您可以打印HashSet的内容。你也可以用静态对象做到这一点,但是找到静态对象的所有用法的噩梦......