# Particle spiral around player

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

1. ### Rixterz

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. ### Rixterz

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. ### Rixterz

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. ### Rixterz

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 x 1
8. Awesome! Glad it works! • Friendly x 1