Particle spiral around player

Discussion in 'Spigot Plugin Development' started by Rixterz, Jun 10, 2016.

  1. Hi

    I want to make a spiral of particles appear around the player but I can't get the calculations right. I want the spiral to continue being smooth, but I also want it to go upwards around the player, then reach a height of 2, then go back down. The result is hideous.

    Code (Text):
    double y = 0; //0 to height
        float radius = (float) 0.8;
       
        String upDown = "up";
       
        int height = 2;
       
        int squashFactor = 2;
       
        double increment = 0.05;
       
        @Override
        public void run()
        {
            Location loc = p.getLocation();
           
            double x = radius * Math.cos(y);
            double z = radius * Math.sin(y);
           
            PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(particle, false, (float) (loc.getX() + x), (float) (loc.getY() + (y / squashFactor)), (float) (loc.getZ() + z), 0, 0, 0, 0, 1, null);
            broadcastParticles(packet);
           
            if(upDown.equals("up"))
            {
                if(y >= height)
                {
                    upDown = "down";
                    y -= increment;
                }
                else
                {
                    y += increment;
                }
            }
            else
            {
                if(y <= 0)
                {
                    upDown = "up";
                    y += increment;
                }
                else
                {
                    y -= increment;
                }
            }
           
        }
     
  2. Calculate the circumference of a circle. Have it draw out a new point along the circumference every 'x' ticks and move the y value of the location correspondingly.

    How can you do this? Add sin(angle) + cos(angle) to get the point on the circle and increase the angle infinitely until you reach a the y-level you want. (make sure your angle is in radians)
     
  3. So I have
    Code (Text):
    double circumference = Math.PI * 2 * radius;
    , I have no idea how to do the rest

    That run() method is run every 2 ticks
     
  4. I'm writing out the code right now. Please give me a moment.
     
  5. To help, here's a video of the effect I want to achieve:
     
  6. Code (Text):

      public static void drawCircle(String effect, Player p, double radius,
          double offsetX, double offsetY, double offsetZ, int timesToDrawCircle,
          boolean playFromPlayerSight) {

        Location loc = p.getLocation().add(offsetX, offsetY, offsetZ);
        double x = 0;
        double y = 0;
        double z = 0;

        for (double θ = 0; θ < timesToDrawCircle * 360; θ++) {

          x = cos(θ) * radius;
          z = sin(θ) * radius;

          if (playFromPlayerSight) {
            x += loc.getDirection().normalize().getX();
            y += loc.getDirection().normalize().getY();
            z += loc.getDirection().normalize().getZ();
          } else {
            y = 0;
          }

          loc.add(x, y, z);
          p.getWorld().playEffect(loc, Effect.valueOf(effect), 1);
          loc.subtract(x, y, z);
          θ++;
        }
      }
    All you need to do now is just increase and decrease the y accordingly.
     
  7. I had to change that code a lot to get it working but this finally works:

    Code (Text):
    String upDown = "up";
       
        int height = 2;
        double yIncrement = 0.1;
       
        double a = 0;
       
        double x = 0;
        double y = 0;
        double z = 0;
       
        double radius = 0.8;
       
        @Override
        public void run()
        {
       

            Location loc = p.getLocation();
           
            x = Math.cos(a) * radius;
            z = Math.sin(a) * radius;

            PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(particle, false, (float) (loc.getX() + x), (float) (loc.getY() + y), (float) (loc.getZ() + z), 0, 0, 0, 0, 1, null);
            broadcastParticles(packet);

            a++;
           
            main.getServer().broadcastMessage(String.valueOf(a));
           
            if(upDown.equals("up"))
            {
                if(y >= height)
                {
                    upDown = "down";
                    y -= yIncrement;
                }
                else
                {
                    y += yIncrement;
                }
            }
            else
            {
                if(y <= 0)
                {
                    upDown = "up";
                    y += yIncrement;
                }
                else
                {
                    y -= yIncrement;
                }
            }
           
            if(a >= 360){a = 0;} //reset a to stop it getting too large
           
        }
       
        public void broadcastParticles(PacketPlayOutWorldParticles packet)
        {
            for(Player online : Bukkit.getOnlinePlayers())
            {
                ((CraftPlayer) online).getHandle().playerConnection.sendPacket(packet);
            }      
        }
     
    • Useful Useful x 1
  8. Awesome! Glad it works! :D
     
    • Friendly Friendly x 1