Log In  


How do you draw a trail for a moving object?

I see this effect a ton of games but don't know enough about what to look for to find it in the code. Plus y'all seem to minify code into single letter variable names and that makes it even tougher. ;)

Say I shoot a missile or something, what's a good way to draw a trail behind it? But also define how long that trail is and its color, etc.

I mean, it seems like you should just be able to draw a pixel behind the x/y location of the object you want to follow but how do you know what that location is? Especially if the object is changing direction...it's not just x+1 and y+1 or whatever...I think...

Insight, thoughts and snippets are appreciated.



the trick is to make a list of every x,y position the object has been to. just use add(list,object.position), then render a pixel for each x,y position in the list.


The solution from catnipped is great, but you must delete old position in the list (swapping for a new one, or shifting the whole list). It can also become slow if you have a large number of trails.

Another solution is to draw a point (or circle) at the current position of the trail each frame, and not clearing the screen. That way you have an infinite trail and you can have a lot of them. To make it disapear after a while you can draw some circles with the background color at random position each frame. That will start to paint over the trails, making them disapear.
Of course you may want to draw other things that trails, so in this case you have to copy the screen in memory somewere else when you render the rest of the game, and then restore it at the begining of each frame.

Here is some code losly based on combo pool :

-- the copy is divided in two zone
local frame_chunk_0 = 0x1000 -- in the map2 section
local frame_chunk_1 = 0x4300 -- in the user data section

-- paste last frame buffer on the screen
memcpy(0x6000,frame_chunk_0,0x1000)
memcpy(0x7000,frame_chunk_1,0x1000)

-- draw your trails emiters
for b in all(balls) do
	circfill(b.x,b.y,1,b.c)
end

-- clear the screen progressively, tweak number and size to fade slower/faster
for i=0,100 do
	circfill(rnd(128),rnd(128),1,0)
end

-- copy back the frame somewhere in memory
memcpy(frame_chunk_0,0x6000,0x1000)
memcpy(frame_chunk_1,0x7000,0x1000)

2

Here I made a quick sample :

Cart #26837 | 2016-08-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
2


Thanks for both suggestions. I tried out using an array because it just made more sense to me. The paint trails is very cool but not what I'm after in this case.

I'm storing the last 8 x/y coordinates of the move and just loop through that trail array to draw a pixel at each point with pset().

However, because my lead object (bullet) is moving more than 1px/frame, the trail ends up dotted. It makes sense why this is happening, just wondering if there's nice way to fill in the gaps.


You could just draw a line from point to point.

e.g.

local p1=points[1]
for i=2,#points do
 local p2=points[i]
 line(p1[1],p1[2],p2[1],p2[2])
 p1=p2
end

This might be a good place to add some visual variety if you're going for different looks too. Adding a small random x/y value to the points as you draw them gets a more lightning-bolt effect, moving p1 closer to p2 each frame would get you a bit of a fade, etc.


When you swap those dots for lines, you totally need to make a little lookup table or something and have the color fade from hot-gases to dark smoke.


@seleb Point to point line...duh, geez...it was clearly a long day if I didn't think of that. I had tried a line from front to back but that obviously didn't get what I wanted. Sigh. Thanks for the tip and snippet.

@tyroney you know it. :) Needs to look bad ass.



[Please log in to post a comment]