只有当物体进入范围时才会触发接近探测器,而不是当它在范围内移动

时间:2013-08-01 18:48:33

标签: java minecraft

我正在为Minecraft制作基于文本的雷达。如果玩家距离你不到20个街区,它会在聊天中说出来。截至目前,它正在骚扰聊天。如何才能让它只写入关于该玩家ONCE的聊天?即使你不玩游戏,也应该很容易理解。

if (Camb.radar)
{
  for (Entity e: (List < Entity > ) mc.theWorld.loadedEntityList)
  {
    if (e instanceof EntityPlayer)
    {
      EntityPlayer player = (EntityPlayer) e;
      if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0)
        continue;
      mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName() + " has entered your 20 block radius!"); //Write to chat, only want this line done once for every player
    }
  }
}

6 个答案:

答案 0 :(得分:15)

你需要跟踪玩家何时离开范围并设置一个标志,这样你才能知道他们何时从“超出范围”过渡到“在范围内”。可能还想添加一个计时器,这样你每N秒只能提醒一次。

答案 1 :(得分:2)

如果你创建一个PlayerData类,它可以包含映射到布尔值的playernames的hashmap。你给每个玩家一个PlayerData对象,然后当有人进入该玩家的半径时,你切换他/她的布尔值。

public class PlayerData {
    public Player thePlayer;
    public HashMap<String,boolean> inRadius = new HashMap<String,boolean>();

    public PlayerData(Player thePlayer) {
       this.thePlayer = thePlayer;
    }

    public void checkRadius(P Entity player) {
    /**function that checks radius and if a new player is there, notify thePlayer*/
      if(inRadius.get(player.getEntityName()) == true || thePlayer == player || thePlayer.getDistanceToEntity(player) > 20.0) return;
      else {
        thePlayer.addChatMessage("whatever you want to say");
        inRadius.put(player.getEntityName(), true);
      }
      for(Iterator<String> key=inRadius.keySet().Iterator();key.hasNext()) {
        String name = key.next();
        /**Check to see if that player is still within 20 meters. If not, set value to false*/
        /** also be careful to check if player is online*/
      }
    }

}

答案 2 :(得分:2)

您可以尝试创建附近玩家的列表或数组,并在20个街区内将其添加到该列表中。当您在范围内找到实体时,请检查其是否在您的列表中。如果没有,请通知并将其添加到列表中,如果是,请游戏:)

要从列表中删除项目,请检查列表中的实体,并将其与玩家位置进行比较。如果它们超出范围,请将其删除。这可能需要在一个单独的循环中发生。

答案 3 :(得分:0)

您需要在该方法之外存储已提醒玩家的方法。 Map是完美的。如果你不想泄漏那些WeakHashMap

,那么Entities会更好
private final Set<EntityPlayer> playersInRange = Collections
        .newSetFromMap(new WeakHashMap<EntityPlayer, Boolean>());

void onMove() {
    if (Camb.radar) {
        for (Entity e : (List<Entity>) mc.theWorld.loadedEntityList) {
            if (e instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) e;

                if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0) {
                    // make sure player is (no longer) in set
                    playersInRange.remove(player);
                    continue;
                }

                if (!playersInRange.contains(player)) {
                    playersInRange.add(player);
                    mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName()
                            + " has entered your 20 block radius!");
                }
            }
        }
    }
}

您还可以与他们一起存储时间,每隔X次重新提醒一次。

private static final long WAIT_BETWEEN_ALERTS = 30000;
private final WeakHashMap<EntityPlayer, Long> map = new WeakHashMap<EntityPlayer, Long>();
void onMove() {
    if (Camb.radar) {
        for (Entity e : (List<Entity>) mc.theWorld.loadedEntityList) {
            if (e instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) e;

                if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0) {
                    // clear alerts
                    map.remove(player);
                    continue;
                }

                Long lastTimeAlerted = map.get(player);
                long minimumLastAlert = System.currentTimeMillis() - WAIT_BETWEEN_ALERTS;

                if (lastTimeAlerted == null || lastTimeAlerted < minimumLastAlert) {
                    map.put(player, System.currentTimeMillis());
                    mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName()
                            + " has entered your 20 block radius!");
                } // else, already alerted recently.
            }
        }
    }
}

答案 4 :(得分:0)

使用getter / setter方法向EntityPlayer detected添加布尔标志。

在你的循环中:

if (Camb.radar) {
    for (....) {
        if (e instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) e;
            if (player.isDetected() || player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0) {
                continue;
            }

            if (!player.isDetected()) {
                mc.thePlayer.addChatMessage(....); 
                player.setDetected(true); // reset this flag when player goes out of radar
            }
        }
    }
}    

答案 5 :(得分:0)

我建议做如下:

int radius = 0;
if (Camb.radar) for (Entity e : (List <Entity>) mc.theWorld.loadedEntityList)
    if (e instanceof EntityPlayer) {
        EntityPlayer player = (EntityPlayer) e;
        if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0)
            continue;
        while (radius < 1) {
            mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName() + " has
            entered your 20 block radius!");

        }    
    }