Best way to check if there is a player in a certain radius from a location

Discussion in 'Plugin Development' started by mine-care, Sep 3, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    mine-care

    When I was creating my plugin today I thought to myself "What is the best way to check if someone is in a 16 block radius". I can think of 3 ways to do it.
    The 3 ways I have thought of are
    spawn an entity, check nearby entities, remove
    Loop through players and check distance
    distance squared method

    If you have another one or think one of those are the best please say which and why.

    Thanks.
     
  2. Offline

    Synapz

    player#getNearbyEntities(16, 16, 16). Loop through all the Entities it returns, check if they are an instanceof Player if thy are check if it matches the player you want to check for

    Player extends LivingEntity which extends Entity, so you should be able to use that method instead of having to spawn an entity...
     
  3. Offline

    bwfcwalshy Retired Staff

    @Synapz That wont work it's a block not a player.
     
    mine-care likes this.
  4. Offline

    Synapz

    Oh! Thanks I misread... I will think of another possibility
     
  5. Offline

    DuaneTheDev_

    @mine-care

    If you're using 1.8, I'd say the first option with an invisible armour stand.
     
  6. Offline

    FisheyLP

    [​IMG]
    Yes, you read it right. Bounding box. Not radius. If you want to check the radius the best way is distanceSquared(loc) <= radius*radius
     
  7. Offline

    Hawktasard

    @mine-care
    The best one by far is to do something like this:
    Code:java
    1. for(Entity entity : block.getWorld().getEntities())
    2. {
    3. if(entity.getLocation().distanceSquared(block.getLocation()) <= radius * radius)
    4. {
    5. // TODO Do something with the entity.
    6. }
    7. }

    This is pretty much what getNearbyEntities does so there's no reason to spawn an entity to do it, doing so would in no way make it faster (that I am aware of, at least). Another problem I have is that it the entity could possibly be seen by players for a couple of milliseconds. It also looks bad in code in my opinion so I think you should use "my" method.
     
  8. Offline

    mine-care

    @Hawktasard mhm, well still considering the ammount of entities that could be potentially on a world, i wouldnt really thing that this is the best method :/ i am looking for players afterall but thanks, the condition inside the loop seems efficient :- )


    @FisheyLP You have realised by now that reading is clearly not my speciality :p Thanks a lot! to both you and @Hawktasard for this condition :D
     
  9. Offline

    Hawktasard

    @mine-care
    It really shouldn't slow down your server but you can use World#getPlayers() if you only want to check the players.
     
  10. Offline

    mine-care

    @Hawktasard thats what i am going to do :/ entities are overkill. And yeah no guarantee that it wont slow it down, it all goes down to how many players are on the world, how many chunks are loaded, how many entities are spawned or droped and so on. the ammounts may be massive and that i want to avoid.
     
  11. Offline

    Hawktasard

    @mine-care
    I'm pretty sure calling distanceSquared isn't performance heavy. You should be able to do it with 200+ players online no problem. Try something like this (I don't have an IDE atm so you may have to change it a little bit):
    Code:java
    1.  
    2. long start = System.currentTimeMillis();
    3. int inRange;
    4. int entities;
    5. for(Entity entity : world.getEntities())
    6. {
    7. if(entity.getLocation().distanceSquared(anotherLocation) <= radius * radius)
    8. {
    9. inRange++;
    10. entities++; // You could probably do world.getEntities().size()
    11. }
    12. }
    13. System.out.println("Looped through " + entities + " entities and checked distance. That took " + (System.currenttTimeMillis() - start) + "ms. Found " + inRange);
    14.  
     
  12. Offline

    mine-care

    @Hawktasard It doesnt apear to be heavy, cant try it at the moment, but i will later! thanks!! :D
     
  13. Offline

    Xerox262

    You realise that the World#getPlayers() method just does getEntities then get world then return the players that matched and that Java is a powerful language, It wont have problems iterating through your entities, unless you get like upwards of a million
     
  14. Offline

    mine-care

    @Xerox262 I was going to loop throught online players as provided by Bukkit#getOnlinePlayers() that as you can see from the CraftServer class, has a Collection or array (Depending on the version) of all online players being returned directly.
    I have realised that from my experience on multythreading and after a class about mass data processing and handling. But that doesnt mean that i will have to follow the inefficient or slow way when there is a much better one.
    Also
    Blocking-wise (or lag wise) that isnt right, it all goes down to the code executed in the loop, that piece of code may be blocking for significant ammounts of time and therefore issues will arise for small amounts of entities.
    But i assume you where talking of an empty loop, and yes in this sort of values a delay is becoming noticable.
     
  15. Offline

    Hawktasard

    @mine-care
    Xerox is right. I didn't want to make any claims without doing research and I had to go when I posted that so I couldn't look it up or test. You should not have any problems with my method, computers today are faster than you might think they are. As I said before, check how long it takes, it wouldn't surprise me if we're talking about a couple of milliseconds here.
     
  16. Offline

    mine-care

    @Hawktasard
    i wasnt born in 1960's i am fully aware of the capabilities of modern computers
    I am not saying your code is inefficient. i am just seeking for all the posibilities of doing this. The thing is that your code above only does the check. in the loop, if i was to perform a time consuming action it would decrese the speed. I got to do the performance test after i got the entire loop as i want it to be. For now ill gather ideas and later on check what is the fastest based on my code.
     
Thread Status:
Not open for further replies.

Share This Page