Solved Missile pathfind algorithm

Discussion in 'Plugin Development' started by Marsi77, Oct 14, 2014.

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

    Marsi77

    Hi Guys,
    I need our help, I want to create a rocket launcher with target system. I want that an entity flys up to 200 Blocks flys over the target and come down but I have no idea how I made the missle find the right way.
    Oh I forgot I want that the rocket is not super duper fast. ^^
    Can someone help me?
     
  2. Offline

    Gamecube762

    MATH!
    Algebra will help you with this one!
    ---------------------------------------------------------------------I forgot all math I did in HS...

    Edit: Look into parabolas, they will give you what you want.
     
  3. Offline

    Marsi77

  4. Offline

    blablubbabc

    Well, cut the movement of the rocket into pieces and implement each of those separately:

    We have a start position and a target position, 'position could either be Location's or Vector's:
    * You can get the direction from start towards the target by: targetPos.subtract(startPos)

    Flying a few blocks forward:
    * If you set the y-value of that direction to zero you get a vector pointing forwards to the target on the x-z-plane
    * Spawn your rocket entity at the start position and apply some velocity vector to it which has the same forward direction as we have just found. The magnitude of that vector will equal the speed your rocket will fly at.
    * Either repeat applying that velocity vector for the next few ticks or simply wait a few ticks. With that it can fly a few blocks forward (take a look into bukkit's scheduler for figuring this out).

    Flying steep up into the air:
    * After those few ticks check if your entity is still valid (hasn't hit any walls/other entities/was removed for some reason/..). If it is continue.
    * Now simply do the same as above but with a different velocity vector and maybe give the rocket more time to fly into the air. This new velocity vector should now point into the air as steep as you want it to. You could for example use the direction vector in x-z-plane which we have calculated in the beginning, normalize it (so it has length 1) and set the y-value depending on how steep the rocket shall fly. A value of 5 should be pretty steep. Normalize that vector again (it's still pointing steep into the air but has length 1 again) and multiply it with the speed you want your rocket to fly.
    * Repeat applying that velocity vector for the next few ticks. Depending on how much time you want to give your rocket to fly into the air before coming down to the target.

    Flying down towards the target:
    * After those few ticks have passed, the rocket entity is still valid and your target is also still valid (didn't die or teleport far way in the meantime) continue.
    * One possibility now could be to directly start flying towards the target. In order to do that get a fresh direction vector pointing from your rockets current position in the air towards the target, just like we did in the beginning.
    * Use that vector to create a vector which you use as new velocity for your rocket.
    * Repeat those last 2 steps (getting the direction from the rocket towards the target and aplying the updated velocity to the rocket) for the next ticks in order to let your rocket constantly fly towards the target (and update it's flight direction -> good if your want your rocket to follow a moving target). Abort if your rocket becomes invalid (becasue it hits something/gets removed) or your target becomes invalid for some reason.
     
  5. Offline

    Marsi77

  6. Offline

    teej107

    Use BlockIterators
     
  7. Offline

    jpjunho

    Marsi77
    Get the location 200 blocks above the start, then the location 200 blocks above the end and make the missile go through every location.
     
  8. Offline

    Marsi77

    teej107
    Can you give me an example?
    jpjunho
    I have try it with vectors, but this was a lot too fast
     
  9. Offline

    blablubbabc

    Even easier then:

    // if you want it to be slow experiment with the speed value here, values between 0.0 and 1.0 are possible as well:
    Vector upwardsVelocity = new Vector(0.0D, speed, 0.0D);
    Entity rocket = .. // spawn the rocket entity at start location

    inside a BukkitRunnable which gets run as repeating task each tick:
    rocket.setVelocity(upwardsVelocity);
    if (rocket.getLocation().getY() >= 200) {
    this.cancle();
    rocket.teleport(startLocation.setY(200)); // to make sure our rocket is in the correct place (needed if speed is very high)
    startAirMovement();
    }

    Vector toTarget = targetPos.subtract(startPos).setY(0);
    double distanceXZ = toTarget.length();
    int steps = (int) (distanceXZ / speed) + 1;
    Vector toTargetInAir = toTarget.setY(0).normalize().multiply(speed);

    inside a BukkitRunnable which gets run repeatingly each tick:
    rocket.setVelocity(toTargetInAir);
    steps--;
    if (steps == 0) {
    this.cancle();
    rocket.teleport(targetLocation.setY(200));
    startDownMovement();
    }

    Vector downwardsVelocity = new Vector(0.0D, -speed, 0.0D);
    .. same as in the first step but with this downward velocity now ..
    detect hit either via
    * rocket.isValid() // return false if the rocket was removed due to hitting something for example
    * if the rocket is not a projectile: maybe compare old location to new location each tick -> if those don't change the entity is probably being blocked by something.
    * remove entity and create explosion
     
  10. Offline

    Marsi77

Thread Status:
Not open for further replies.

Share This Page