Give a constant speed to an entity

Discussion in 'Spigot Plugin Development' started by Jaume, Oct 13, 2017 at 1:21 PM.

  1. Hello! As the title says, I need to give an entity a constant speed. I've tried setting it's velocity every 2 or 3 ticks to the desired one and disabling its AI and it works, but I need to move LOTS of entities simultaneously and that's not an efficient way; when there are over 30 or so entities, they start taking longer to spawn and move, even though the TPS don't drop at all. I make sure to end each runnable and kill all instances of the entity once they reach the desired location, so I don't think it's because of a memory leak (moreover, the memory doesn't get used to its max either).

    As an example of what I'm trying to achieve, you can look at how the mobs move at CubeCraft's Tower Defence (play.cubecraft.net). Keep in mind some of them have to fly straight (e.g. slimes), so I don't think setting a path is the way!
     
  2. How are you setting the speed every 2-3 ticks? Creating a runnable per entity??

    If you create a single scheduled repeating task that runs every 2-3 ticks you can add all the entities to a hash map with their final destination or desired velocity in it, Then when it runs iterate over every object in the map, reset the velocity and repeat.

    A single timer should handle this with 30 objects no problem at all.

    If you need more Info than a hash map can provide you could create a custom class object with all the fields you need, including a timestamp of when the entity should stop moving


    Sent from my iPhone using Tapatalk
     
  3. Thanks for answering! I'm actually using the method you described as good; a single runnable that moves all the entities that need to be moved every 2 or 3 ticks. But having to check if each entity has reached its destination on each iteration, probably makes it too hard to handle.
    This is the code I currently have for moving the entities (invisible armor stands with a slime as a passenger).
    Code (Java):
        @Override
        public void run() {
            if (armorStands.size() > 0) {
                for (ArmorStand armorStand : armorStands) { //armorStands contains all the armorStands that need to be moved.
                    if (armorStand.getLocation().getX() > 60) { //armorStands (with a Slime as a passenger) need to move towards X and 60 blocks. Checking if the armorstand has reached its destination.
                        for (Entity entity : armorStand.getPassengers()) {
                            entity.remove(); //remove the slime from the world
                        }
                        armorStand.remove(); //remove the armorstand from the world
                        armorStandsToRemove.add((ArmorStand) armorStand); //add the armorstand to another list because it can't be removed from the list you are iterating through.
                    } else {
                        armorStand.setVelocity(velocity); //if it hasn't reached its destination, set its velocity to the predefined velocity.
                    }
                }

                for (ArmorStand armorStand : armorStandsToRemove) {
                    armorStands.remove(armorStand); //after moving all the armorstands and removing the ones that reached their destination from the map, remove them from the list.
                }

                armorStandsToRemove.clear(); //clear the temporal list.
            }
        }
    There's another runnable that spawns armorstands with slimes every 3 seconds and puts them on the list so the other runnable can move them.
     
  4. I don't think there is any other way than using a repeating task to have entities move at a constant speed, make sure that you have gravity disabled for the armor stands, I don't think there is much more you can do except for spawning less entities or make the task repeat slower than 3 ticks.
     
  5. Are you sure about it? D:

    So do you think that's how they're doing it in CubeCraft Games? Is it just a matter of a better CPU?
     
  6. I'm not 100% sure, but with the way you're doing it I don't think there is. Perhaps you could try having a task repeat ever 2 ticks but only doing half of the armorstands, and after 2 ticks the other half, etc. But it would probably not look very smooth since some of the armorstands will be moving earlier than the others. Maybe someone else has a better idea / different approach
     

Share This Page