Need some help with this code...

Hi,
I am trying my hand on framebased animation. When I use this code It executes but also gives me an error telling me I attempt to set property (rotation) with nil.
Thing is it happens at a different frame every time I run it. Also there is a small stutter in the anim.
Here is the code:

local Qsquare=display.newRect(100,100,50,100)  
  
local function QSquare(event)  
 if event.phase == "began" then  
  
  
 local rotater={}  
 rotater[01]={}  
 rotater[02]={}  
 rotater[03]={}  
 rotater[04]={}  
 rotater[05]={}  
 rotater[06]={}  
 rotater[07]={}  
 rotater[08]={}  
 rotater[09]={}  
 rotater[10]={}  
 rotater[11]={}  
 rotater[12]={}  
 rotater[13]={}  
 rotater[14]={}  
 rotater[15]={}  
 rotater[16]={}  
 rotater[17]={}  
 rotater[18]={}  
 rotater[19]={}  
 rotater[20]={}  
 rotater[21]={}  
 rotater[22]={}  
 rotater[23]={}  
 rotater[24]={}  
 rotater[25]={}  
  
 rotater[01].rotate=1  
 rotater[02].rotate=3  
 rotater[03].rotate=5  
 rotater[04].rotate=7  
 rotater[06].rotate=9  
 rotater[07].rotate=11  
 rotater[08].rotate=13  
 rotater[09].rotate=15  
 rotater[10].rotate=17  
 rotater[11].rotate=19  
 rotater[12].rotate=21  
 rotater[13].rotate=21  
 rotater[14].rotate=19  
 rotater[15].rotate=17  
 rotater[16].rotate=15  
 rotater[17].rotate=13  
 rotater[18].rotate=11  
 rotater[19].rotate=9  
 rotater[20].rotate=7  
 rotater[21].rotate=5  
 rotater[22].rotate=3  
 rotater[23].rotate=2  
 rotater[24].rotate=1  
 rotater[25].rotate=0  
  
  
 local animate  
 local posCount = 0  
  
 local function rotateObject()  
 print(posCount)  
 if posCount \<= 25 then  
 Qsquare.rotation = rotater[posCount].rotate  
  
 posCount = posCount + 1  
  
 else  
 posCount=1  
 timer.cancel(animate)  
 end  
 end  
  
  
 local function rotateAnim()  
 posCount = 1  
 animate = timer.performWithDelay( 1, rotateObject, #rotater )  
 end  
  
 rotateAnim()  
  
 end  
 return true  
end  
  
Qsquare:addEventListener("touch",QSquare)  

I am using rotation in this example cause it quicker than plotting out a path for position. I have no clue what i am doing wrong.

Any help is greatly appreciated. [import]uid: 100901 topic_id: 28492 reply_id: 328492[/import]

The problem you are running into is that you are using the variable Qsquare in two different ways.

  1. You make a display object out of it (Your square), but in the very next line
  2. You overwrite the display object with a function loosing the display object.

Because of this, the last line will need to change too.

Now besides that there are a couple of things you should think about/consider.

If you have multiple squares and want to reuse the animation function, you can’t because you have a hard reference to the Qsquare object. To avoid this, you can use the “target” value passed into the event handler. When your touch event fires and the function is called, a table called “event” is passed to it. That table contains a member called “target” which is the square you touched.

Try this:

local Qsquare=display.newRect(100,100,50,100)  
   
local function QSquareTouchHandler(event)  
 --  
 -- make a short cut to the object I touched  
 --  
 local target = event.target  
  
 if event.phase == "began" then  
 local rotater={}  
 rotater[01]={}  
 rotater[02]={}  
 rotater[03]={}  
 rotater[04]={}  
 rotater[05]={}  
 rotater[06]={}  
 rotater[07]={}  
 rotater[08]={}  
 rotater[09]={}  
 rotater[10]={}  
 rotater[11]={}  
 rotater[12]={}  
 rotater[13]={}  
 rotater[14]={}  
 rotater[15]={}  
 rotater[16]={}  
 rotater[17]={}  
 rotater[18]={}  
 rotater[19]={}  
 rotater[20]={}  
 rotater[21]={}  
 rotater[22]={}  
 rotater[23]={}  
 rotater[24]={}  
 rotater[25]={}  
  
 rotater[01].rotate=1  
 rotater[02].rotate=3  
 rotater[03].rotate=5  
 rotater[04].rotate=7  
 rotater[06].rotate=9  
 rotater[07].rotate=11  
 rotater[08].rotate=13  
 rotater[09].rotate=15  
 rotater[10].rotate=17  
 rotater[11].rotate=19  
 rotater[12].rotate=21  
 rotater[13].rotate=21  
 rotater[14].rotate=19  
 rotater[15].rotate=17  
 rotater[16].rotate=15  
 rotater[17].rotate=13  
 rotater[18].rotate=11  
 rotater[19].rotate=9  
 rotater[20].rotate=7  
 rotater[21].rotate=5  
 rotater[22].rotate=3  
 rotater[23].rotate=2  
 rotater[24].rotate=1  
 rotater[25].rotate=0  
  
 local animate  
 local posCount = 0  
  
 local function rotateObject()  
 print(posCount)  
 if posCount \<= 25 then  
 target.rotation = rotater[posCount].rotate  
 posCount = posCount + 1  
 else  
 posCount=1  
 timer.cancel(animate)  
 end  
 end  
  
  
 local function rotateAnim()  
 posCount = 1  
 animate = timer.performWithDelay( 1, rotateObject, #rotater )  
 end  
  
 rotateAnim()  
  
 end  
 return true  
end  
   
Qsquare:addEventListener("touch",QSquareTouchHandler)  

Next the way you are setting up your rotation is pretty inefficient. First you’re just doing a mathematical progression. In other words, what you are really doing is:

 rotateAmount = 2  
 target.rotation = target.rotation + rotateAmount.  
 if target.rotation \> 21 then  
 rotateAmount = -2  
 end  
 if target.rotation \< 1 then   
 rotateAmount = 2  
 end  

And something like that would replace that huge table structure. Like this:

local Qsquare=display.newRect(100,100,50,100)  
   
local function QSquareTouchHandler(event)  
 --  
 -- make a short cut to the object I touched  
 --  
 local target = event.target  
  
 if event.phase == "began" then  
  
 local animate  
 local rotateAmount = 2  
  
 local function rotateObject()  
 if target.rotation \<= 21 then  
 target.rotation = target.rotation + rotateAmount  
 else  
 target.rotation = target.rotation - rotateAmount  
 end  
 if target.rotation \< 1 then  
 timer.cancel(animate)  
 end  
 end  
  
  
 local function rotateAnim()  
 animate = timer.performWithDelay( 1, rotateObject, 25 )  
 end  
  
 rotateAnim()  
  
 end  
 return true  
end  
   
Qsquare:addEventListener("touch",QSquareTouchHandler)  

Now of course if your wanting to do something funky like rotate different amounts on each timer fire, like 4 degrees the first time, 7 the next, 1 the 3rd, 5 of the 5th, then you would need to keep the table structure. But even then you’re over complicating your table. Consider this instead:

 local rotater={}  
  
 rotater[01]=1  
 rotater[02]=3  
 rotater[03]=5  
 rotater[04]=7  
 rotater[06]=9  
 rotater[07]=11  
 rotater[08]=13  
 rotater[09]=15  
 rotater[10]=17  
 rotater[11]=19  
 rotater[12]=21  
 rotater[13]=21  
 rotater[14]=19  
 rotater[15]=17  
 rotater[16]=15  
 rotater[17]=13  
 rotater[18]=11  
 rotater[19]=9  
 rotater[20]=7  
 rotater[21]=5  
 rotater[22]=3  
 rotater[23]=2  
 rotater[24]=1  
 rotater[25]=0  

Then you would change this line:

target.rotation = rotater[posCount].rotate  

to:

target.rotation = rotater[posCount]  

Now of course if rotater ever needs more elements besides the rotation, then you would do what your doing with that, like having x, y coordinates to move it on a path. [import]uid: 19626 topic_id: 28492 reply_id: 114970[/import]

also in ur original code

[lua]rotater[04].rotate=7
??? < rotater[06].rotate=9[/lua] [import]uid: 12482 topic_id: 28492 reply_id: 115002[/import]

Hello,
Thanks all.
Hi Rob, thanks for the tips. For the naming, I am using Qsquare and Q S quare. one has one capital and the other has 2.
I actually use this table structure cause when I will use it I will be using positioning instead of rotation, or multiple values like rotation,scale position and opacity.
But your code will come in handy. I can use all the tips.

@hgvyas123,
That was my problem! thanks that was I was getting the nil error. You have no idea how long I looked at that code and kept missing that line.
I used print statements to see at what line it gave me the nil. But kept returning different lines.
So grateful.
[import]uid: 100901 topic_id: 28492 reply_id: 115185[/import]