Jump to content

[1.8] [SOLVED] Spawning Particle Trail Along a Vector


Himself12794

Recommended Posts

I'm making a flamethrower spell, of sorts, and want it to generate a line of flames.

What I've done is create a projectile that leaves a trail of flames behind it. This works just as I'd like to. I have the entity set to die after a certain distance traveled.

My problem is that when the projectile is thrown, it is able to generate just a few particles before disappearing. If I drop the velocity, I get the fire trail I desire, but the fire is not traveling at the speed expected of a flamethrower.

 

I've tried to get the previous position, the current position, and take the velocity into account to spawn particles in the space between these two vectors, but it's just not working like I want it to, and they are spawning in a line, but not where I want them to.

 

Here's my flawed code:

	
    public void onUpdate(EntitySpell spell) {
	World world = spell.worldObj;
	float distTraveled = getSpellVelocity() * spell.getTicksInAir();

	for (float i = 0.0F; i < getSpellSpeed(); i += getSpellSpeed() * 0.1)
		world.spawnParticle(EnumParticleTypes.FLAME, spell.posX - spell.motionX + i, spell.posY - spell.motionY + i, spell.posZ - spell.motionZ + i, 0.0D, 0.0D, 0.0D, new int[0]);		
	//world.spawnParticle(EnumParticleTypes.FLAME, spell.posX, spell.posY, spell.posZ, 0.0D, 0.0D, 0.0D, new int[0]);

	if (distTraveled > 3) spell.setDead();
	if (spell.getTicksInGround() > 0) spell.setDead();


}

If you  need more context, the whole of my code can be found here: https://github.com/Himself12794/usefulthings/blob/master/src/main/java/com/himself12794/usefulthings/spell/Flames.java

This is the first time I've really messed with vector locations and movement, so I'm a bit new.

With all due respect, sir: I do, what I do, the way I do it. ~ MacGyver

Link to comment
Share on other sites

If you haven't already, it is very helpful to look through the vanilla examples e.g. the critical particles trailing arrows.

 

Gaussian values are also very nice for certain types of particles, but in this case I'd stick with rand.nextFloat() as an addition to each position value.

 

For example:

for (int i = 0; i < 4; ++i) {
world.spawnParticle(EnumParticleTypes.FLAME,
	x + 0.5F - world.rand.nextFloat(),
	y + 0.5F - world.rand.nextFloat(),
	z + 0.5F - world.rand.nextFloat(),
	0, 0, 0));
}

You can place whatever you want in the motion values; the more random, the better (usually). In the example above, I get x, y, and z by iterating along the player's look vector, so that whole section of code is actually in a loop that iterates as far along that vector as I want to go.

 

Each type of particle also has its own motion behavior, so an algorithm that works well for one particle type may not produce the same results with another.

Link to comment
Share on other sites

Sounds like you want to get the player's look vec, and multiply it by i to get various points along it?  I did a similar fire jet effect with my mod's Blaze Staff, but I had it do a for loop that added (rand.nextInt(3) - 1) * rand.nextFloat() to each coordinate, which of course generated a new random number each loop through, making a more organic looking, less perfect stream of fire particles.  I also threw in random rotations, just for good measure.

Link to comment
Share on other sites

Sounds like you want to get the player's look vec, and multiply it by i to get various points along it?  I did a similar fire jet effect with my mod's Blaze Staff, but I had it do a for loop that added (rand.nextInt(3) - 1) * rand.nextFloat() to each coordinate, which of course generated a new random number each loop through, making a more organic looking, less perfect stream of fire particles.  I also threw in random rotations, just for good measure.

I already have the vector, that is taken from the EntitySpell. That's similar to what I want to do, I'm just unsure how exactly to implement it. Trigonometry was not my strong suit.

With all due respect, sir: I do, what I do, the way I do it. ~ MacGyver

Link to comment
Share on other sites

If you haven't already, it is very helpful to look through the vanilla examples e.g. the critical particles trailing arrows.

 

Gaussian values are also very nice for certain types of particles, but in this case I'd stick with rand.nextFloat() as an addition to each position value.

 

For example:

for (int i = 0; i < 4; ++i) {
world.spawnParticle(EnumParticleTypes.FLAME,
	x + 0.5F - world.rand.nextFloat(),
	y + 0.5F - world.rand.nextFloat(),
	z + 0.5F - world.rand.nextFloat(),
	0, 0, 0));
}

You can place whatever you want in the motion values; the more random, the better (usually). In the example above, I get x, y, and z by iterating along the player's look vector, so that whole section of code is actually in a loop that iterates as far along that vector as I want to go.

 

Each type of particle also has its own motion behavior, so an algorithm that works well for one particle type may not produce the same results with another.

That does work similar to what I'm looking for, however I'd like the spread to be much tighter, and just a little less random. It doesn't seem to be generating a trail, just a bunch of particles where the EntitySpell is at that moment. That formula will be useful though once I figure out the best way to use it on about every 0.2 blocks. Perhaps I get a vector from the caster to the Spell, and maybe I can do something with that?

With all due respect, sir: I do, what I do, the way I do it. ~ MacGyver

Link to comment
Share on other sites

That's what I was saying, while the spell is in use, get the player's lookvec, multiply it by a finely stepped number that's above 1, and you have near infinite control over how small the spacing between the particles is, that's how you extend a normalized vector's magnitude.  The more decimal places, the smaller the individual step will be.

 

Edit: didn't see the last bit, you would do something like: (pseudocode)

Vec3 lookVec = player.getLookVec();
for(float i = blahblahblah)
{
    world.spawnParticles(EnumParticleTypes.FLAME, player.posX + (lookVec.xCoord * i),  player.posY + (lookVec.yCoord * i), player.posZ + (lookVec.zCoord * i), 0, 0, 0);
}

Link to comment
Share on other sites

If you haven't already, it is very helpful to look through the vanilla examples e.g. the critical particles trailing arrows.

 

Gaussian values are also very nice for certain types of particles, but in this case I'd stick with rand.nextFloat() as an addition to each position value.

 

For example:

for (int i = 0; i < 4; ++i) {
world.spawnParticle(EnumParticleTypes.FLAME,
	x + 0.5F - world.rand.nextFloat(),
	y + 0.5F - world.rand.nextFloat(),
	z + 0.5F - world.rand.nextFloat(),
	0, 0, 0));
}

You can place whatever you want in the motion values; the more random, the better (usually). In the example above, I get x, y, and z by iterating along the player's look vector, so that whole section of code is actually in a loop that iterates as far along that vector as I want to go.

 

Each type of particle also has its own motion behavior, so an algorithm that works well for one particle type may not produce the same results with another.

That does work similar to what I'm looking for, however I'd like the spread to be much tighter, and just a little less random. It doesn't seem to be generating a trail, just a bunch of particles where the EntitySpell is at that moment. That formula will be useful though once I figure out the best way to use it on about every 0.2 blocks. Perhaps I get a vector from the caster to the Spell, and maybe I can do something with that?

Please read more carefully - I already said I use the player's look vector to determine the x/y/z and iterate along that, I just left that out of the code example. Of course if you just copy/paste the above without changing anything all of the particles spawn roughly in one location.

 

To get a tighter pattern, reduce the randomness:

coordinate + 0.25F - (rand.nextFloat() * 0.5F) // now the random value can only be +/- 0.25F in either direction

Whereas in my previous example, it was +/- 0.5F in either direction. Random#nextFloat() returns a value between -1.0F and 1.0F, inclusive.

Link to comment
Share on other sites

 

Please read more carefully - I already said I use the player's look vector to determine the x/y/z and iterate along that, I just left that out of the code example. Of course if you just copy/paste the above without changing anything all of the particles spawn roughly in one location.

 

To get a tighter pattern, reduce the randomness:

coordinate + 0.25F - (rand.nextFloat() * 0.5F) // now the random value can only be +/- 0.25F in either direction

Whereas in my previous example, it was +/- 0.5F in either direction. Random#nextFloat() returns a value between -1.0F and 1.0F, inclusive.

Ah yes, I apologize. I was able to tighten the spread by doing what you did. I was also able to spawn along the line and achieve my desired effect using this code:

			for(float j = 0.0F; j < 1.0F; j += 0.05F) {
			for (int i = 0; i < 10; ++i) {
				world.spawnParticle(EnumParticleTypes.FLAME,
					spell.prevPosX + (spell.motionX * j) - world.rand.nextFloat() * 0.5F,
					spell.prevPosY + (spell.motionY * j) - world.rand.nextFloat() * 0.5F,
					spell.prevPosZ + (spell.motionZ * j) - world.rand.nextFloat() * 0.5F,
					0, 0, 0);
			}
		}

With all due respect, sir: I do, what I do, the way I do it. ~ MacGyver

Link to comment
Share on other sites

That's what I was saying, while the spell is in use, get the player's lookvec, multiply it by a finely stepped number that's above 1, and you have near infinite control over how small the spacing between the particles is, that's how you extend a normalized vector's magnitude.  The more decimal places, the smaller the individual step will be.

 

Edit: didn't see the last bit, you would do something like: (pseudocode)

Vec3 lookVec = player.getLookVec();
for(float i = blahblahblah)
{
    world.spawnParticles(EnumParticleTypes.FLAME, player.posX + (lookVec.xCoord * i),  player.posY + (lookVec.yCoord * i), player.posZ + (lookVec.zCoord * i), 0, 0, 0);
}

That would work, but I've been trying to keep the code tied to the entity spell, and not to the player, so perhaps I could fire the spells without there necessarily being a caster. I found a code that works for me, taking into account your and coolAlias'scode. I posted it at the end, if you're interested.

With all due respect, sir: I do, what I do, the way I do it. ~ MacGyver

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.