How to handle sequential and conditional touch events?

Hi everybody!

 

I am new to programming. I have downloaded Corona last week to learn to code and have fun with my son playing games.

We went through the “Getting Started” tutorial and now we are trying to experiment.

 

My setup: Version 2018.3326 (2018.6.25) on MacOS High Sierra.

 

Issue Summary.

I have n cats displayed on screen. If I tap on three cats, say cat_j, cat_k, cat_l, then only these cats should rotate 180.

Please observe: the touches  must be sequential and the order

is irrelevant (i.e., j -> k -> l, or j->l-> k … and so on on through all the 6 permutations).

 

Issue Details.

 

I skip the code I used to display the cats: basically I have as many local variables

cat_i as png images I have, i =1,…, n, and I have named them, i.e.

cat_i.name=“cat_i” for i=1,…,n.

 

 

I first tried with cat_1.

 

local function turn(event)

  event.target:rotate(180)

end

cat1:addEventListener(“touch”,turn)

 

It worked.

 

But then, when I tried with cat1 and cat2,  I realize it is above my very low skills.

 

  • -  First try.

 

local function turnA(event)

  if event.target.name==“cat1” then

  if event.target.name==“cat2" then

      cat1:rotate(180)

      cat2:rotate(180)

  end

  end

end

 

 

cat1:addEventListener(“touch”,turnA)

cat2:addEventListener(“touch”,turnA)

 

    • Nothing happens and I get no error.  :unsure:

 

    • Second try, (now with cat3 and cat4).

 

 

local function turnB(event)

if (event.target.name==“cat3") and (event.target.name==“cat4") then

    cat3:rotate(180)

    cat4:rotate(180)

  end

end

 

 

cat3:addEventListener(“touch”,turnB)

cat4:addEventListener(“touch”,turnB)

 

As above, nothing happens and I get no error.  :wacko:

 

Could you help me, please?

Welcome to the community!

You shouldn’t have skipped the code where you create the cats as I am guessing your problem lies with that part. When you created the variables, did you actually give them a name, like cat3.name = “cat3”?

In any case, apart from not using the code formatting, reading your post was refreshingly well drafted!

When it comes to programming, you want to reuse as much code as possible, so try to avoid rewriting almost identical functions.  I’m not 100% sure if I understood what you wanted to accomplish, but you should be able to get all that done with something as simple as:

local cat = {} local catN = 4 local startX = 60 local startY = 100 local padding = 60 local function rotateCat( event ) if event.phase == "ended" then for i = 1, event.target.id do cat[i]:rotate( 180 ) end end return true end for i = 1, catN do cat[i] = display.newPolygon( startX + (i-1)\*padding, startY, { 0,20,-20,-20,20,-20 } ) cat[i].id = i cat[i]:addEventListener( "touch", rotateCat ) end

Thank you very much for your reply!

 

This is the code I skipped in my previous post:

 

local cat1 = display.newImageRect( “cat1.png",50,50)

cat1.x = display.contentCenterX-105

cat1.y = display.contentCenterY

cat1.name=“cat1”

 

and so on on for the other cats…

 

I am learning a lot from your code, thank you.

 

When I try it, four white triangles are displayed on the the top of my screen.

 

When I click on triangle j, all the triangles <=j rotate.

 

But what I’d like to get is different, i.e.,  if you click/touch three triangles, only these rotate. So, for example, if one touches 1, 3 and 4, these rotate and 2 doesn’t. If one touches  less than three triangles, nothing happens until three triangles are touched.

 

How could I do it?

Something like that can be handled like so.

local cat = {} local catN = 4 local catsTouched = 0 local touchThreshold = 3 local startX = 60 local startY = 100 local padding = 60 local function rotateCat( event ) if event.phase == "ended" then event.target.touched = not event.target.touched if event.target.touched then catsTouched = catsTouched+1 event.target:setFillColor( 1, 0, 0 ) else catsTouched = catsTouched-1 event.target:setFillColor( 1 ) end if catsTouched == touchThreshold then for i = 1, catN do if cat[i].touched then cat[i]:rotate( 180 ) cat[i]:setFillColor( 1 ) cat[i].touched = false end end catsTouched = 0 end end return true end for i = 1, catN do cat[i] = display.newPolygon( startX + (i-1)\*padding, startY, { 0,20,-20,-20,20,-20 } ) cat[i].touched = false cat[i]:addEventListener( "touch", rotateCat ) end

Since you are new to programming and Corona, you may want to have a look at the tutorials and sample projects here as well: https://docs.coronalabs.com/guide/programming/index.html

Fantastic!

It was really above my skills.

Thank you very very much. 

I’ll study the tutorial and the sample projects!

Best,

S.

No problem.

My solution wasn’t necessarily the easiest way to accomplish this and that’s the beauty of programming. There more solutions out there for each problem than there are programmers.

Welcome to the community!

You shouldn’t have skipped the code where you create the cats as I am guessing your problem lies with that part. When you created the variables, did you actually give them a name, like cat3.name = “cat3”?

In any case, apart from not using the code formatting, reading your post was refreshingly well drafted!

When it comes to programming, you want to reuse as much code as possible, so try to avoid rewriting almost identical functions.  I’m not 100% sure if I understood what you wanted to accomplish, but you should be able to get all that done with something as simple as:

local cat = {} local catN = 4 local startX = 60 local startY = 100 local padding = 60 local function rotateCat( event ) if event.phase == "ended" then for i = 1, event.target.id do cat[i]:rotate( 180 ) end end return true end for i = 1, catN do cat[i] = display.newPolygon( startX + (i-1)\*padding, startY, { 0,20,-20,-20,20,-20 } ) cat[i].id = i cat[i]:addEventListener( "touch", rotateCat ) end

Thank you very much for your reply!

 

This is the code I skipped in my previous post:

 

local cat1 = display.newImageRect( “cat1.png",50,50)

cat1.x = display.contentCenterX-105

cat1.y = display.contentCenterY

cat1.name=“cat1”

 

and so on on for the other cats…

 

I am learning a lot from your code, thank you.

 

When I try it, four white triangles are displayed on the the top of my screen.

 

When I click on triangle j, all the triangles <=j rotate.

 

But what I’d like to get is different, i.e.,  if you click/touch three triangles, only these rotate. So, for example, if one touches 1, 3 and 4, these rotate and 2 doesn’t. If one touches  less than three triangles, nothing happens until three triangles are touched.

 

How could I do it?

Something like that can be handled like so.

local cat = {} local catN = 4 local catsTouched = 0 local touchThreshold = 3 local startX = 60 local startY = 100 local padding = 60 local function rotateCat( event ) if event.phase == "ended" then event.target.touched = not event.target.touched if event.target.touched then catsTouched = catsTouched+1 event.target:setFillColor( 1, 0, 0 ) else catsTouched = catsTouched-1 event.target:setFillColor( 1 ) end if catsTouched == touchThreshold then for i = 1, catN do if cat[i].touched then cat[i]:rotate( 180 ) cat[i]:setFillColor( 1 ) cat[i].touched = false end end catsTouched = 0 end end return true end for i = 1, catN do cat[i] = display.newPolygon( startX + (i-1)\*padding, startY, { 0,20,-20,-20,20,-20 } ) cat[i].touched = false cat[i]:addEventListener( "touch", rotateCat ) end

Since you are new to programming and Corona, you may want to have a look at the tutorials and sample projects here as well: https://docs.coronalabs.com/guide/programming/index.html

Fantastic!

It was really above my skills.

Thank you very very much. 

I’ll study the tutorial and the sample projects!

Best,

S.

No problem.

My solution wasn’t necessarily the easiest way to accomplish this and that’s the beauty of programming. There more solutions out there for each problem than there are programmers.