Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Trail effect with emitter?
Started by Sig.g1 Jun 10 2018 02:59 AM

37 replies to this topic
trail effect emitter
[TOPIC CONTROLS]
Page 1 of 2 1 2
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

Hi 

 

I would like to put a trail effect like this(0:18-0:28):

 

I was thinking of using the emitters but I can not emulate it

 

someone with more experience can help me?



[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,291 posts
  • Corona SDK

I would do that with a series of display objects.  The problem I foresee is that the object is moving fast, so making a trail of discrete objects will  have gaps.

 

Here is an old game I never finished and you can see the idea:

 

 

Here are some old samples I made to answer other other questions.  They use the same principle for trails, but expressed differently.  Nonetheless, the concept is the same.

 

Finally, if you can't work this out, I could extract the trail code from the video example as a level-1 hit.

 

 

PS - I do think you could also make an emitter do this too.  I'll consider it a bit more and if something pop into my head I'll post it.

 

Do you have an emitter editor so you can experiment?


Edited by roaminggamer, 10 June 2018 - 04:10 PM.


[TOPIC: post.html]
#3

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

Thanks for the support!

 

I can only see one of the two sample codes(1 link don't work) and it is not very useful..

 

"Do you have an emitter editor so you can experiment?"

Yes I have an editor but I can not remove the termoli from the emitters.

 

In any case, in the video I see a good example even if time that what I had in mind is even more complex

Attached File  ball trail.png   79.49KB   1 downloads

 

I did not know about hitman. I will consider it if I can not do it within a short time.



[TOPIC: post.html]
#4

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

Doing tests with enterFrame function and/or emitter, the problem is mainly due to the speed of the ball.

 

I think I will have to completely change the approach to get a decent solution



[TOPIC: post.html]
#5

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,291 posts
  • Corona SDK

1. link fixed

 

2.  Yes, the speed of the ball will be the biggest issue.



[TOPIC: post.html]
#6

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,291 posts
  • Corona SDK

Hey this is a really interesting topic and if anyone is reading and has ideas on making nice trails, please pitch in.

 

This is a pretty common requirement and I know I always belabor how to best handle it (depending on the game).

 

Again, got an idea?  Please share.


  • Sig.g1 likes this

[TOPIC: post.html]
#7

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

I have an idea and it's hours that I try but I can not, I think with your experience and my idea we could succeed.

 

Doing a normal trail (with enterFrame function) everything works fine as long as the speed is not high.

 

So my idea is: whenever I enter into enterFrame to make a "copy" of the object, instead of just making a copy in the last position of the object, why not make a copy for each position between the last copy and the current position of the object?

 

I do not know if this is too expensive but it could work. A bit like when in drawing app. If the user drags too fast and leaves holes, we ring them.

 

edit : thanks to fix link


Edited by Sig.g1, 10 June 2018 - 05:15 PM.


[TOPIC: post.html]
#8

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,291 posts
  • Corona SDK

Yes, I've used this technique before (fixed intervals along the line from last position to current position). 

 

The trick/challenge is initial trail object size and shrink time.

 

When you produce one object per frame, then you can use transition.to() to shrink the object over a fixed time.  This gives a nice smooth effect.

 

If you create multiple objects in a frame for a contiguous trail, you need to modify the:

  • start size of the objects further back along the trail
  • time to shrink for the earlier objects

Otherwise, the trail will be chunky in places.



[TOPIC: post.html]
#9

david.ciaudo

[GLOBAL: userInfoPane.html]
david.ciaudo
  • Enthusiast

  • 46 posts
  • Corona SDK

Such effect is in fact a relatively complexe thing to do which requires you to draw your trail vertex per vertex. Fortunately Corona sdk allows you to do that, but I'm warning you, it's not straight forward. You'll have to deal with some 2D mathematics, and experiment the display.newMesh method. But it's worth the effort, especially regarding of performances.


  • roaminggamer likes this

[TOPIC: post.html]
#10

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

Well I do not think I can do all of this alone.

 

I thought it was easier and that corona had a solution ready as others plataforms.

 

however I really need this effect so I have to find a solution.....



[TOPIC: post.html]
#11

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,878 posts
  • Corona SDK

This is the easiest way...

 

On each frame create a clone of your ball and the same x,y and position it below your actual ball  Then simply transition it with something like

transition.to(ballCopy, {time=500, alpha=0, xScale=0.01, yScale=0.01, onComplete=function(target)  
  display.remove(target)
  target = nil
end})

You can vary the length of the trail by simply changing the time of the transition.



[TOPIC: post.html]
#12

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

@SGS

 

Yhis is what I do when I open the topic...

 

the problem is when the ball goes fast

 

The traileffect disappears and there are only ball distant from each other



[TOPIC: post.html]
#13

david.ciaudo

[GLOBAL: userInfoPane.html]
david.ciaudo
  • Enthusiast

  • 46 posts
  • Corona SDK

Just fix a minimal distance of void between your two balls and make a loop between the position of your ball in the previous frame and the position of your ball in your current frame.

 

For example, you want 3 pixels of void between your ball copies. If your ball position.x was 0 on the previous frame and your new ball position.x is 12, just iterate between 0 and 12 with a step of 3 and create a new copy each iteration. Here you will make 4 copies per frame at x = 0, 3, 6, 9.

 

But once again, using particles to draw this fx can be performance heavy.



[TOPIC: post.html]
#14

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,878 posts
  • Corona SDK

Based on your OP video and if you ran at 60fps this shouldn't be a problem with a bit of interpolation.  I use trails at 30fps using this method.



[TOPIC: post.html]
#15

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,239 posts
  • Enterprise

alternatively, imagine a "snake" game, where you're recording a history of positions.  but rather than render circles, consider them as vertices of a line, then extrude that line to create a mesh -- calc the delta to next position, take its perp to get a normal, extrude outward, probably decaying by age to get a "taper", for both sides, stitch it all up into a mesh.   (if you want to get "fancy" you could interpolate f.e.  catmull-clark across the extruded edge points) set the uv's to index into a texture that fades towards tail.  done right it'll resemble a fruit ninja -style trail.



[TOPIC: post.html]
#16

david.ciaudo

[GLOBAL: userInfoPane.html]
david.ciaudo
  • Enthusiast

  • 46 posts
  • Corona SDK

@davebollinger explained the expert way of doing it.

 

By the way dave, do you know how to get rid of this situation which causes artifact in the trail:

 

https://imgur.com/0i8Rr0i

 

As you can see there can be superposed vertices when you extrude the spline if your ball direction varies a lot suddenly. Will catmull-clark remove them?



[TOPIC: post.html]
#17

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,239 posts
  • Enterprise

@david.ciaudo - if your curve is smooth (like OP's, presumably) then this method is adequate.   if not, then you'll have to smooth it somehow. (unless such "crease" artifacts are tolerable)

 

the simplest approach is just to "chamfer" such vertices - think of it as turning "v"'s into "u"'s.  at each vertex you back off a little and create two vertices where there was only one. 

 

the distance you choose to chamfer at (or not chamfer at all) can be adjusted based on the sharpness of the angle.  (as only very acute angles need fixing)

 

one step "better" than that is to add yet a third midpoint vertex, halfway between the midpoint of the "u"'s base, and "v"'s tip.  (so each vertex becomes three, like a "u" but with it's base deformed into a "shallow v")

 

next step better - recurse that for a second pass, if any of your "u"'s are still sharp enough to look like "v"'s.

 

..or fit a spline.

 

no matter how you smooth the trade-off will be vs positional accuracy.  (the full solution involves creating proper rounded "buffers", rather than simple extrusion, but it's quite a bit more involved)


  • StarCrunch likes this

[TOPIC: post.html]
#18

david.ciaudo

[GLOBAL: userInfoPane.html]
david.ciaudo
  • Enthusiast

  • 46 posts
  • Corona SDK

Yes the trade-off vs positionnal accuracy is annoying. I wish I can I find a paper about this proper rounded "buffers" solution, just for curiosity.



[TOPIC: post.html]
#19

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,239 posts
  • Enterprise

think of "balls" at each vertex, connected at their tangents by "tubes" (ie a quad - a rect if radii same, else trapezoid) in between

 

visually equiv to layering a "black line" of stroke width "radius" under a white line of stroke width "radius-2"  (like within a vector illustration program where you can get nice rounded corner joins)

 

computationally, there are two general approaches:  literally ball-and-tube, then do a merge.  (requires you have good 2d compgeom support for merge), or incrementally "trace" around those outer curves at each ball for only the segment between the tangents, inner join won't have a curve, you'll be creating "fan" geometry, then connect up all tube edges to ball slices.

 

if doing this on desktop, maybe look for a binding to "clipper" library (which can do this offset operation with either square/miter/round joints)  but if need a pure-Lua solution for mobile, i'm not aware of a general-purpose one.


  • david.ciaudo likes this

[TOPIC: post.html]
#20

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 758 posts
  • Corona SDK

@david.ciaudo Off the top of my head, there's the offsetting paper here.

 

@Sig.g1 I've done a couple larger projects with trails (think Tron, with curves). I know these used some combination of Hermite and Catmull-Rom curves, but I forget the specifics... probably one to interpolate large-scale motion and the other to sculpt the shape of shorter segments in-shader.

 

A lot of that wound up, in updated form, here, here, and here, about half of it being different ways to smootly interpolate the curve. I should probably package it all up at some point.

 

Also, lots of good curve info here.


  • david.ciaudo likes this

[TOPIC: post.html]
#21

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 758 posts
  • Corona SDK

if doing this on desktop, maybe look for a binding to "clipper" library (which can do this offset operation with either square/miter/round joints)  but if need a pure-Lua solution for mobile, i'm not aware of a general-purpose one.

Working on it.  :D (See the text rendering plugin topic.)



[TOPIC: post.html]
#22

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

@ everyone

Thank you so much.

 

You have mainly described two approaches. Both are interesting and I'm going to try.

 

@StarCrunch

thanks also to the material.

 

I will investigate  thoroughly. 

My problem and I'm not a native speaker and I do not know many of these mathematical shortcuts.

I think it will take weeks to get a not too good effect. But still I do not give up!


  • StarCrunch likes this

[TOPIC: post.html]
#23

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,878 posts
  • Corona SDK

I think a simple interpolation between last frame and current frame should give you enough info to draw a trail.  I do this in one of my mini-games (in main app) and it works well enough to give a decent trail (like your op).



[TOPIC: post.html]
#24

Sig.g1

[GLOBAL: userInfoPane.html]
Sig.g1
  • Enthusiast

  • 98 posts
  • Corona SDK

I want to try this first then eventually I'll go on the hard.

 

So you can give me a tip?

I have p1 and p2. Then I derive the distance between the two points:


   local xFactor = p2.x - p1.x
   local yFactor = p2.y - p1.y
   local dist = math.sqrt( (xFactor*xFactor) + (yFactor*yFactor) )

and the number of "extra" pieces

local extraPiece = math.round(dist/mySpace)

now how to calculate a possible point p3,p4,... at a X distance from p1?

Attached File  example.png   3.39KB   0 downloads



[TOPIC: post.html]
#25

david.ciaudo

[GLOBAL: userInfoPane.html]
david.ciaudo
  • Enthusiast

  • 46 posts
  • Corona SDK

You almost got it there dude, here is a piece of code that is working as you want:

--constant you can modify
local SPEED_BALL = 10
local RADIUS_BALL = 20
local STEP = 3
local TRAIL_FADE_DURATION = 500

local ball = display.newCircle(0, 0, RADIUS_BALL)
ball.vx = SPEED_BALL
ball.vy = SPEED_BALL
ball:setFillColor(1,0,0)

local onUpdate = function(e)
	local A = {x = ball.x, y = ball.y}--previous position
	
	--move the ball
	ball.x = ball.x + ball.vx
	ball.y = ball.y + ball.vy
	
	local B = {x = ball.x, y = ball.y}--new position
	
	--get the distance
	local dx = B.x - A.x
	local dy = B.y - A.y
	local dist = math.sqrt(dx*dx + dy*dy)
	
        --draw trail particles
	local nbIterations = math.floor(dist / STEP)
	for i=0, nbIterations do
		local xx = A.x + i * STEP * dx/dist
		local yy = A.y + i * STEP * dy/dist
		
		local trailParticle = display.newCircle(xx, yy, RADIUS_BALL)
		transition.to(trailParticle, {time = TRAIL_FADE_DURATION, alpha = 0, onComplete = function()
			trailParticle:removeSelf()
		end})
	end
	
	--bounce on arena bounds
	if ball.x > 320 then
		ball.x = 320
		ball.vx = -ball.vx
	end
	if ball.x < 0 then
		ball.x = 0
		ball.vx = -ball.vx
	end
	if ball.y > 480 then
		ball.y = 480
		ball.vy = -ball.vy
	end
	if ball.y < 0 then
		ball.y = 0
		ball.vy = -ball.vy
	end
	
	--display ball over trail
	ball:toFront()
end


Runtime:addEventListener("enterFrame", onUpdate)

  • Sig.g1 likes this


[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]

Also tagged with one or more of these keywords: trail effect, emitter