Sharp thruster trails

BlitzMax Forums/BlitzMax Programming/Sharp thruster trails

Yahfree(Posted 2008) [#1]
Hey, I'm trying to figure out how trails like these are done:
http://blitzbasic.com/logs/userlog.php?user=8862&log=1442

I have three problems:

- My current method doesn't end pointy like that (which is the effect i'm after)
- My current method doesn't have the nice color transition from white to the burn color, also an effect i'm after.
- My trails don't "Bend" as you fly around

Right now I stick a particle emitter emitting little fire sprites to the tail of my little ship and turn it on/off when thrusting. It looks decent, but not the sharp pointy gradual look I'm going for.

any ideas?

here's a image of my current method for a thruster trail:




MGE(Posted 2008) [#2]
Simple scale the particle sprites to get smaller in real time, that's how you will get that pointy look. ;)


Yahfree(Posted 2008) [#3]
ok, did so, now its more pointy, but another problem I have is a design for this game i'm working on, the player is stationary in the middle of the screen, so instead, the map scrolls, and the amount the map scrolls is added to the objects around the players(giving the illusion that the map is stationary, not the player), including the trail (so theres not a dot of particles not moving on the ships tail), because of this, the trail looks dotted when the player goes fast, I want it solid, is there any easy way to achieve this?

screen shot of player going maximum speed with scale as suggested:



Warpy(Posted 2008) [#4]
In the screenshot you linked the scaling is the other way round, ie smaller particles nearer the ship.

To avoid dotting, you could place more dots as the ship goes faster. Something like this, if the ship is moving from (ox#,oy#) to (newx#,newy#)

dx#=newx-ox
dy#=newy-oy
d#=sqr(dx*dx+dy*dy) 'this is how far the ship moved this frame)
dx:/d 'make (dx,dy) a unit vector in the direction of the ship's movement
dy:/d

t#=leftover
while t<d
   x#=ox+t*dx
   y#=oy+t*dy
   makedot(x,y)
   t:+dotspacing
wend
leftover#=t-d


This will place dots evenly, every 'dotspacing' units. The 'leftover' variable is so the evenness carries over from frame to frame. Obviously, you'll need to initialise it to zero.


Yahfree(Posted 2008) [#5]
hey, thanks for the help warpy, but i'm not quite sure how to implement your method. Here's my player update code:

the old method is the method I came to this thread with, the new method is me trying to implement yours.


thanks for all the help!


Warpy(Posted 2008) [#6]
Almost there. You just need to remember to initialise t, and make dotspacing and leftover globals.

Global leftover:Float=0
Const dotspacing:Float=10

Function UpdatePlayer()

	Local RadPx:Float
	Local RadPy:Float
	If KeyDown(KEY_SPACE)	
		If burning = False burning = True
		pdx:+AngleToDX(protation)*ACCELERATION
		pdy:+AngleToDY(protation)*ACCELERATION
	Else
		If burning = True burning = False
	End If
		
	protation = PointsToAngle(512,384,MouseX(),MouseY())+90
	If MouseHit(1) And Not dead
		PlaySound shoot_sound
		Local bul:TBullet = New TBullet.Create(512,384,protation)
	End If
	
	If MouseHit(2) And Not dead And BOMBS
		'PlaySound shoot_sound
		Local bom:TBomb = New TBomb.Create(512,384)
		BOMBS:-1
	End If
	
	'old method for thruster trail
	'If burning And Not dead
	'	EmitParticle(Cos(protation-90) * -9 + 512, Sin(protation-90) * -9 + 384, firepart2, 10, True, 180, 3, ,True)
	'End If
	
	If pdx > TOPSPEED pdx = TOPSPEED
	If pdx < -TOPSPEED pdx = -TOPSPEED
	If pdy > TOPSPEED pdy = TOPSPEED
	If pdy < -TOPSPEED pdy = -TOPSPEED

	If protation > 360 protation = protation - 360
	If protation < 0 protation = protation + 360
	
	'new method for thruster trail
	Local distance:Float=Sqr(pdx*pdx+pdy*pdy) 'this is how far the ship moved this frame)
	Local dx:Int = pdx:/d 'make (dx,dy) a unit vector in the direction of the ship's movement
	Local dy:Int = pdy:/d
	If burning And Not dead
               Local t:Float = 0
		While t<distance
	   		_x#=px+t*dx
	  		_y#=py+t*dy
	   		EmitParticle(_x, _y, firepart2, 10, True, 180, 3, ,True)
	   		t:+dotspacing
		Wend
	End If
	
	
	px :+ pdx
	py :+ pdy	

	If HEALTH < 1 PlayerDie()
	If deadtimer > 115
		ParticleExplosion(512,384,starpart,70,15,Rnd(2.11,3.99))
		dead = False
		deadtimer = 0
	End If

	If player_st = 20
		player_st = 1
		player_shield = False
	End If
	
	DrawImage landingpad,-px+1024,-py+768
	
	If Not dead
		SetRotation protation
		DrawImage player_img,512,384
		SetRotation 0
		If player_shield
			DrawImage shield_img,512,384
			player_st:+1
		End If
	Else
		SetAlpha .2
		SetRotation protation
		DrawImage player_img,512,384
		SetRotation 0
		SetAlpha 1
		deadtimer:+1
	End If
	
	targetrot:+5
	If targetrot > 360 targetrot = 0
	If targetrot < 0 targetrot = 360
	SetRotation targetrot
	DrawImage target_img,MouseX(),MouseY()
	SetRotation 0
	

End Function



Yahfree(Posted 2008) [#7]
thanks for all the help warpy, the effect appears to be working, but the fire trail blazes off into the distance instead of staying on the ship.

any ideas?




Warpy(Posted 2008) [#8]
No idea. What do you mean it blazes off into the distance?

Actually, you need to change the lines

Local _x#=px+t*dx
Local _y#=py+t*dy

to

Local _x#=px - t*dx
Local _y#=py - t*dy

so the fire appears *behind* the ship, but I don't think that's the problem you were describing, is it?


Yahfree(Posted 2008) [#9]
Fire seperates from the ship and goes further and further as relative to the player's "position".



This is because the players ship is (as far as pixels go) always draw in the middle of the screen, its the background/objects that move.

Your code helps, before the flame was going the oposite direction of the player, now it speeds past the player :)

any ideas?

Thanks for all the help warpy


MGE(Posted 2008) [#10]
If you're main sprite is always in the center, then your main ship's particles should as well. You may not want any world movement affecting your ship particles. Give that a shot, might be what you're looking for.

In my particle system, emitters can "rail" off a sprite meaning they are not affected by anything else so it's a constant motion originating from the sprite's position. Perfect for flames, etc.


Yahfree(Posted 2008) [#11]
MGE, that seemed to solve the problem, but now apon closer look, it seems this method didn't change the dotting of the particles, it simply made more particles, thus the dots are brighter as the particles are on light blend:

image at full speed(trail looks great at slow speeds):



current code:



MGE(Posted 2008) [#12]
I counted about 8 sprites in your trail, you may want to double that. Plus you may want to move them slower so they don't spread out so far. Also since you're using LIGHTBLEND, make the particle colors darker. Also create your flame particle image with dark reds and dark yellows in it. When they blend together they should make a better looking flame. ;)


Yahfree(Posted 2008) [#13]
they're bright because theres more than 8 sprites stacked ontop of eachother. - there's 45 but there in 8 concentrated groups thats the problem