Log In  


Heyo people!

So, I'm having some trouble getting my head around the timing of everything when it comes to Pico 8, Lua, and I guess programming in general. Something that troubles me is how for loops act when running a game.

Right now, I have a piece of code that displays several circles along a straight line, one circle being created for each pixel of distance between the player sprite and a mouse click location. Here is the code:

if band(mousebtn,1) > 0 then
 ropes={}
	mouseclick=true
end

if mouseclick==true then

	--get last mouse coords
	local lcursx=mousex
	local lcursy=mousey	
	--get last player coords
	local lpx=p.x+8
	local lpy=p.y

	local dist, angle = gettraj(lcursx,lcursy)

	for i=1,flr(dist) do
		local dirx=lpx+cos(angle)*i
		local diry=lpy+sin(angle)*i

		add(ropes, {x=dirx,y=diry})
	end

	mouseclick=false
end

Now, I've been messing around with this for loop for about 3 hours, trying to figure out how to create these 'rope' particles sequentially, one by one, over a specific span of time.

I've tried wrapping it in a timer...

t=time() -- upon button click get time

        for i=1,flr(dist) do
                if time()-t>1 then
		        local dirx=lpx+cos(angle)*i
		        local diry=lpy+sin(angle)*i

		        add(ropes, {x=dirx,y=diry})
                        t=time()
                end
	end

I've also tried wrapping the timer around the add(ropes)... statement alone, doing all sorts of timey wimey stuff that I'm seeing in tutorials and in the forums, and nothing has worked. I wish I could post all of the iterations of failure but that would be very boring.

I've also considered creating each rope particle, and then having them move incrementally towards the mouse location, before freezing the entire table of particles in place. Perhaps that would give me greater control over the 'extending rope' effect.

So, I guess I'm just wondering, how does the for loop really work? Does placing a timer within the loop mean that one second should be passing each time the loop runs? Does the loop finish its full duration before continuing with any code below? And also, if you have any suggestions on how to get these little ropey fellas to spawn based on a timed sequence, please let me know.

-- I feel like I'll be posting a lot here since I'm just starting, apologies if my questions begin to grate.



I'm not sure I understand the question but I can ramble a bit about how time works in PICO-8 and maybe that will help?


Mechanically, PICO-8 works around a game loop - every 30th of a second, PICO-8 will execute the _update() function, then (if it hasn't run out of CPU) the _draw() function. The function time() returns a number of theoretical seconds based on how many frames PICO-8 has rendered.

In order to have something happen over time, you have to keep track of the state of that thing between frames - that is, across multiple calls of _update(). For example, you might have a table called 'ropes', add items to it when appropriate, and, every single frame, go through the whole thing to see which entries are new enough to draw and which entries are old enough to remove.

Each for loop that occurs within a single call of _update() occurs during the same frame - at the same value of time().


If you plan to have other game elements going at the same time as the ropes or if you want a specific speed at which the ropes draw, then packbat's answer is what you need. Allowing the _update() function to finish is essential for making game time progress in any intentional manner.

However, if you only care about the ropes drawing in sequence, then you could also call your _draw() function followed by the flip() function at the end of those for loops. That would force pico-8 to draw the screen, so at least you'd get to see the effect of adding ropes to the table. You just wouldn't be able to control how quickly it happens.


1

@packbat, your rambling is actually super enlightening. So, when I use a for loop, it runs through the entire thing in a single frame? That helps me visualise what's going on a little better. I've used tables quite a bit now, and used time() properly (like with sprite animations), but trying to include trajectories and particles has confused things a bit for me.

@kimiyoribaka, I definitely see what I should do, yeah. Need to make sure _update() finishes. I'm just trying to find out the right method by which to implement it.

EDIT: OHMG thank you both, how you guys explained it actually helped so much. I ditched the for loop and tried something completely different with the frame/update info in mind. Working now! It was literally so much simpler than I thought it was, just a progress variable that counts up each update and ends at the pixel distance. I was definitely overthinking it.


Yay! Glad that we could help.



[Please log in to post a comment]