[Resolved] Need help understanding how Corona parses code (what order do things happen in?)

Hi,

Just before I dive in, I’ll make my apologies for unclear phrasing/ asking a dumb question!

So I have this function that gets fired when you “hit” a character. This function does a number of things (including triggering other functions) and I’m expecting these to be handled in the order that I write them within the function. (My only other exposure to programming languages is php and javascript where this is definitely the case).

A rough overview of my function:

in the “began” event.phase:

  1. fade out the various “hitting” buttons to give visual feedback that these cannot be re-hit until the action is complete
  2. swap the regular character sprite for the “hit” character animation sprite
  3. play the “hit” sound

in the “ended” even.phase:

  1. restore the regular character sprite
  2. run a few functions that update character health etc.
  3. fade the buttons back up to full opacity

From an amateur perspective, there’s absolutely no way that the hitting buttons can fade out before the hitting animation has finished running (these actions take place in different phases of the event, after all) however what happens is exactly that. Worse, it seems to be quite inconsistent - and jumpy too sometimes. It looks like it’s working way harder than it should. It’s almost as if Corona tries to do *everything at once*. Sometimes the animation swap doesn’t get triggered. Occasionally the buttons don’t fade back to full opacity.

Is there any way of basically saying “don’t do this next bit until this bit has run?”

Also, while we’re on the subject. Although I disable all other screen inputs during each “hitting” action (I don’t want users to be able to continually hit over and over), Corona seems to “queue up” inputs and then executes them all when my function unpauses everything. Is there a way to say “ignore all inputs while this is happening”?

Again, sorry for the vagueness. My full function is below, although the functions it links to aren’t in this block, all they do is retrieve and/or update data from various Ice tables.

Many many thanks for your help in advance,
Andrew

----- master characterAction function —

[blockcode]
local characterAction = function (actioncode,bonusamount,strengthadjust,willadjust)

local animation = nil
local actiontype = nil
local actionname = nil
local anisound = nil
local soundtype = nil

– what sort of action are we dealing with?
if actioncode <= 4 then
actiontype = “beating”
elseif actioncode >= 5 then
actiontype = “torture”
end
– PUNCHED
if actioncode == 1 then
animation = instance3
actionname = “P”
soundtype = “hit”
– KICKED
elseif actioncode == 2 then
animation = kicked
actionname = “K”
soundtype = “hit”
– OTHER ACTION TYPES (3-8) STILL TO DO
end
return function(event)

if “began” == event.phase then
– fade out all buttons
fadebuttons(actiontype)
– the above function fades out buttons like this: transition.to( submenuBeat, { time=100, delay=0, alpha=0.2 } )

– pause/ freeze interaction with other parts of the game until we’re done
paused = true
animation.isVisible = true
playsound(soundtype)
– ANIMATION SWAP (“instance2” is the cryptically-named default sprite)
instance2:pause()
instance2.isVisible = false
– sets focus on the button for all future events even if finger moved off
display.getCurrentStage():setFocus( event.target )
elseif “ended” == event.phase or event.phase == “cancelled” then
– ANIMATION SWAP
instance2.isVisible = true
animation.isVisible = false

– BONUS FOR NON-CONSECUTIVE ACTION –
– add a bonus damage if the last action was something different to this one
local bonus = 0
local lastaction = health:getlastaction()
if lastaction ~= actionname then
bonus = bonusamount
else
bonus = 0
end
– update last action with this current action
health:updatelastaction(actionname)

– UPDATE WILL AND STRENGTH METERS / LEVELS
health:adjusthealth( “strength”, -(strengthadjust+bonus) )
health:adjusthealth( “will”, -(willadjust+bonus) )
getstrength()
getwill()

– COUNT RUN OF SAME ACTION TYPE
– if this action is in a run of same action types, add 1 to run total
local lastactiontype = health:getlastactiontype()
if lastactiontype == actiontype then
– add to total; no need to update action type
health:addtorun(actiontype)
else
– reset actiontype count; update last action type
health:updatelastactiontype(actiontype)
health:resetrun(actiontype)
end

– FINISH BUTTON FOCUS
– removes focus for button
display.getCurrentStage():setFocus(nil)

– INVOKE COMMAND?
local actionrun = health:getruntotal(actiontype)

if actiontype == “beating” and actionrun >= 6 then
– suggest different approach (function not yet written)
health:resetrun(actiontype)
elseif actiontype == “torture” and actionrun >= 6 then
– called into meeting (function not yet written)
health:resetrun(actiontype)
end

– restart standing animation
instance2:play()
paused = false
– restore buttons
restorebuttons(actiontype)
– above function is basically: transition.to( submenuBeat, { time=100, delay=50, alpha=1 } )
end
end
end
[/blockcode]
[import]uid: 132606 topic_id: 31220 reply_id: 331220[/import]

You can fire a function after a transition has finished like this:

[lua]transition.to( submenuBeat, { time=100, delay=0, alpha=0.2, onComplete = doThisNow} )[/lua]

I think the problem that you are having is that an ‘ended’ phase is going to be triggered pretty soon after the ‘began’ phase unless you hold the button down. A quick tap is only going to be a few ms.

I would move everything in your ‘ended’ phase code into a separate function that is triggered by a timer or after a transition has finished.

[lua]timer.performWithDelay(300, postAction)[/lua]

[import]uid: 93133 topic_id: 31220 reply_id: 124860[/import]

Hi Nick,

Thank you so much. That’s very useful to know (and now you point it out makes perfect sense). I’ll try that and will report back.

Many thanks,
Andrew [import]uid: 132606 topic_id: 31220 reply_id: 124861[/import]

I’ll see if I can explain this… First in full disclosure, I did not look at your code, only your description of the problem, I don’t have much time this morning to do a full analysis of your code.

Basically any function should fire its code in a linear fashion like you expect.

function a()  
 b()  
 c()  
 i = i + 1  
end  

But there are two exceptions to this: events and asynchronous actions

Let’s look at events first. You have a touch function like:

function someButtonHandler(event)  
 if event.phase == "began" then  
 -- do stuff  
 elseif event.phase == "ended" then  
 -- do other stuff  
 end  
end  

Sure enough, what goes on in “do stuff"will happen in a linear fashion once the button has been touched. But as soon as the button is released, someButtonHandler gets called a 2nd time with the “ended” phase. If “do stuff” isn’t done, “do other stuff” will start. You can think of it like running in a separate process or thread. That 2nd call is independent of the first call. Depending on how long your player has the button held down for will determine how much of the 'began” block finishes before the “ended” block kicks off. In other words, you have to think of them as two completely separate operations working on their own time line.

The second thing that will mess with you’re linear thinking are asynchronous handlers.

Things like timer.performWithDelay, transition.to, network.request, audio.play, all return immediately after they are called. They do their functions in the background and either quietly end when done, or “call back” to a function in your code when they are done to finish up things you are expecting.

In you’re case (again I’ve not looked at your code), I wouldn’t even pay attention to the “began” phase and then just wait until the “ended” phase. Let it trigger your actions, and I’m assuming since you are fading things, you are doing a transition.to. Put an onComplete=finishUp in the parameters to transition.to (which I did go look through you code and I don’t see where you’re animations are happening) and provide a function called “finishUp” that will fade the buttons back in do your damage and set a flag allowing the button to be pressed again.

Hope this makes sense.
[import]uid: 19626 topic_id: 31220 reply_id: 124877[/import]

Awesome, Rob. That was very clearly explained, thank you. Essentially it was my misunderstanding of how those touch events are fired and that they are more or less happening at the same time, rather than waiting for one to be completed before the other is begun.

I feel much happier knowing this now :slight_smile:

p.s. What an awesome community this is. I’ve posted two problems (both of which are pretty stupid things) and not only have I got comprehensive replies within just a couple of hours, but no one’s said “RTFM” (which they’d be fairly justified to do). Thanks for being so helpful + patient, everyone.

[import]uid: 132606 topic_id: 31220 reply_id: 124879[/import]

It is a wonderful community, no doubt :slight_smile: I think the best dev community around by far, though of course I’m naturally somewhat biased :wink: [import]uid: 52491 topic_id: 31220 reply_id: 124934[/import]

Peach, your (very generous) tutorials are what helped me get started in the first place. Thank you x100!

App development has always been a dark art to me and I’m quite amazed at how things are falling into place and I’m actually programming my own app when 6 months ago I knew nothing. That’s definitely thanks to you and the support that this community gives.

I also can’t overstate enough the value of reading everyone else’s threads and comments. These forums are amazing.

/gush [import]uid: 132606 topic_id: 31220 reply_id: 124940[/import]

Awww, thank you! That’s lovely to hear :slight_smile: I do my best.

I know the feeling; I knew nothing about programming before Corona, of course that was a lot more than 6 months ago but I remember the feeling well.

You seem like you’ll fit in well around here :wink: [import]uid: 52491 topic_id: 31220 reply_id: 124964[/import]

You can fire a function after a transition has finished like this:

[lua]transition.to( submenuBeat, { time=100, delay=0, alpha=0.2, onComplete = doThisNow} )[/lua]

I think the problem that you are having is that an ‘ended’ phase is going to be triggered pretty soon after the ‘began’ phase unless you hold the button down. A quick tap is only going to be a few ms.

I would move everything in your ‘ended’ phase code into a separate function that is triggered by a timer or after a transition has finished.

[lua]timer.performWithDelay(300, postAction)[/lua]

[import]uid: 93133 topic_id: 31220 reply_id: 124860[/import]

Hi Nick,

Thank you so much. That’s very useful to know (and now you point it out makes perfect sense). I’ll try that and will report back.

Many thanks,
Andrew [import]uid: 132606 topic_id: 31220 reply_id: 124861[/import]

I’ll see if I can explain this… First in full disclosure, I did not look at your code, only your description of the problem, I don’t have much time this morning to do a full analysis of your code.

Basically any function should fire its code in a linear fashion like you expect.

function a()  
 b()  
 c()  
 i = i + 1  
end  

But there are two exceptions to this: events and asynchronous actions

Let’s look at events first. You have a touch function like:

function someButtonHandler(event)  
 if event.phase == "began" then  
 -- do stuff  
 elseif event.phase == "ended" then  
 -- do other stuff  
 end  
end  

Sure enough, what goes on in “do stuff"will happen in a linear fashion once the button has been touched. But as soon as the button is released, someButtonHandler gets called a 2nd time with the “ended” phase. If “do stuff” isn’t done, “do other stuff” will start. You can think of it like running in a separate process or thread. That 2nd call is independent of the first call. Depending on how long your player has the button held down for will determine how much of the 'began” block finishes before the “ended” block kicks off. In other words, you have to think of them as two completely separate operations working on their own time line.

The second thing that will mess with you’re linear thinking are asynchronous handlers.

Things like timer.performWithDelay, transition.to, network.request, audio.play, all return immediately after they are called. They do their functions in the background and either quietly end when done, or “call back” to a function in your code when they are done to finish up things you are expecting.

In you’re case (again I’ve not looked at your code), I wouldn’t even pay attention to the “began” phase and then just wait until the “ended” phase. Let it trigger your actions, and I’m assuming since you are fading things, you are doing a transition.to. Put an onComplete=finishUp in the parameters to transition.to (which I did go look through you code and I don’t see where you’re animations are happening) and provide a function called “finishUp” that will fade the buttons back in do your damage and set a flag allowing the button to be pressed again.

Hope this makes sense.
[import]uid: 19626 topic_id: 31220 reply_id: 124877[/import]

Awesome, Rob. That was very clearly explained, thank you. Essentially it was my misunderstanding of how those touch events are fired and that they are more or less happening at the same time, rather than waiting for one to be completed before the other is begun.

I feel much happier knowing this now :slight_smile:

p.s. What an awesome community this is. I’ve posted two problems (both of which are pretty stupid things) and not only have I got comprehensive replies within just a couple of hours, but no one’s said “RTFM” (which they’d be fairly justified to do). Thanks for being so helpful + patient, everyone.

[import]uid: 132606 topic_id: 31220 reply_id: 124879[/import]

It is a wonderful community, no doubt :slight_smile: I think the best dev community around by far, though of course I’m naturally somewhat biased :wink: [import]uid: 52491 topic_id: 31220 reply_id: 124934[/import]

Peach, your (very generous) tutorials are what helped me get started in the first place. Thank you x100!

App development has always been a dark art to me and I’m quite amazed at how things are falling into place and I’m actually programming my own app when 6 months ago I knew nothing. That’s definitely thanks to you and the support that this community gives.

I also can’t overstate enough the value of reading everyone else’s threads and comments. These forums are amazing.

/gush [import]uid: 132606 topic_id: 31220 reply_id: 124940[/import]

Awww, thank you! That’s lovely to hear :slight_smile: I do my best.

I know the feeling; I knew nothing about programming before Corona, of course that was a lot more than 6 months ago but I remember the feeling well.

You seem like you’ll fit in well around here :wink: [import]uid: 52491 topic_id: 31220 reply_id: 124964[/import]