How do i write this function correctly?

so i have this function and it works but i needed to change it a bit and it doesnt works…

 local onCollision = function(self, event) if event.phase == "began" then local hit = self.value local other = event.other.value if other == 1 then -- "1" is the value of the floor.. display.remove(ball[hit]) -- hit is the self value for the ball end return true end end function spawnBall() spawn = math.random(display.contentWidth \* 0.05, display.contentWidth \* 0.95) ball[i] = display.newImageRect("snowball.png", 50, 50 ) ball[i].x = spawn ball[i].y = -100 ball[i].collision = onCollision ball[i]:addEventListener( "collision", ball[i] ) end startTimer = timer.performWithDelay( 700, spawnBall, -1 )

but i changed it to this so it fitted my needs and now it doesnt detect a collision

local tb1 = {} function tbl:onCollision( self, event ) if event.phase == "began" then local hit = self.value local other = event.other.value if other == 1 then display.remove(ball[hit]) end return true end end function spawnBall() spawn = math.random(display.contentWidth \* 0.05, display.contentWidth \* 0.95) ball[i] = display.newImageRect("snowball.png", 50, 50 ) ball[i].x = spawn ball[i].y = -100 ball[i].collision = onCollision ball[i]:addEventListener( "collision", ball[i] ) end startTimer = timer.performWithDelay( 700, spawnBall, -1 )

NOTE : I DID REMOVE ALOT OF CODE FOR THE BETTER UNDERSTANDING SO IF SOMETHINGS NOT THERE IT DOESNT MEAN I DONT HAVE IT IN THE ORIGINAL

Hi.  Unless I’m wrong, you’re trying to solve the problem of a function not being visible when you need it, and you’re following some advice that, while not wrong, is not exactly right.

First, 

Since you did this,

function tbl:onCollision( self, event )

you’re implying this:

tbl.onCollision = function( self, self, event ) -- Colon notation implies self

What you ‘meant’ to code was this:

function tbl:onCollision( event ) -- equivalent to this: -- tbl.onCollision = function( self, event) 

Second, even if you fix this, it is wrong.  To solve the problem of visibility as you would get here:

local function doit() doit2() end local function doit2() print("hi") end doit() -- Fails

Solve it with forward declaration like this (not by using tables like you’re doing):

-- Declare the functions before you refer to them or use them local doit local doit2 -- Define the functions doit = function() doit2() -- This was forward declared so now it works end doit2 = function() print("hi") end doit() -- Works

Please read this article so you can start to better understand scope and visibility:

https://coronalabs.com/blog/2015/06/16/tutorial-scope-for-beginners/

You’re running ahead of your understanding of these VERY important concepts and you’ll only encounter more problems if you don’t learn about them quickly.  

Also, you’re using globals and that’s not good:

function spawnBall() -- This function is global now; not a great practice

Oh, one more thing. 

Thanks a lot for trimming your code down and formatting.  You rock!

I know, another post, but I can’t leave this alone.

I know someone else told you to use tables, and I said it was kinda wrong.  It is wrong the way you’re trying to use it, but if you were writing a module, this would be perfectly OK:

-- awesome.lua local public = {} function public.doit() public.doit2() end function public.doit2() print("hi") end return public

Later we could use ‘awesome.lua’ like this:

local booya = require "awesome" booya.doit() -- prints "hi" by calling doit2() internally booya.doit2() -- prints "hi"

The reason the module worked is because ‘public’ (a table) was visible and defined everyplace we refer to it.  

While the method doit2() is not attached (yet) when defining doit(), it is attached when we call it, and because we had a valid handle to ‘public’ already, we can look up the method at execution time.

Again, read that article I pointed you at.

Haha the code trimming was cause you “yelled” at me that one time haha thanks(i really mean it) But im having this problem now… so this works

 function spawnBall() print("test") end startTimer = timer.performWithDelay( 700, spawnBall, -1 )

But this one doesnt…

 function tbOne:spawnBall() -- see the tbOne added? print("test") end startTimer = timer.performWithDelay( 700, spawnBall, -1 )

why doesnt it work? scope ? cause the other functions seem to be working but this one…

Me again.

The way you had it the first time was better.  Abandon that table stuff, fix the scope issues via forward declaration, fix that global function, and you’ll be golden.

-Ed

You’re goofing up the reference

Try this:

startTimer = timer.performWithDelay( 700, tbOne.spawnBall, -1 ) -- or this startTimer = timer.performWithDelay( 700, function() tbOne:spawnBall() end, -1 )

Hello again, now how do i make an event listener work? i have the drag body function here…

 function dragBody( self, event, params ) local body = event.target local phase = event.phase local stage = display.getCurrentStage() if "began" == phase then stage:setFocus( body, event.id ) body.isFocus = true if params and params.center then body.tempJoint = physics.newJoint( "touch", body, body.x, body.y ) else body.tempJoint = physics.newJoint( "touch", body, event.x, event.y ) end if params then local maxForce, frequency, dampingRatio if params.maxForce then body.tempJoint.maxForce = params.maxForce end if params.frequency then body.tempJoint.frequency = params.frequency end if params.dampingRatio then body.tempJoint.dampingRatio = params.dampingRatio end end elseif body.isFocus then if "moved" == phase then body.tempJoint:setTarget( event.x, event.y ) elseif "ended" == phase or "cancelled" == phase then stage:setFocus( body, nil ) body.isFocus = false body.tempJoint:removeSelf() end end return true end 

i added the table  to the drag body as you can see above… now in my spawnCircle function when i try adding the event listener it gives an error… here the listener

ball[i]:addEventListener( "touch", dragBody )

And yes im listening to you on that i should remove the table and all but i have to fix this first and then ill make a video on what im trying to do and accomplish so you understand better and could maybe help me out further 

  1. Fix this:

    local function dragBody( self, event, params )  

  2. Be sure you’re creating the ‘balls’ after you’ve defined dragBody

  3. Make this change:

    ball[i].touch = dragBody ball[i]:addEventListener( “touch” )

Note

There is nothing wrong with storing references to objects in tables.  

I don’t mean stop using tables.  I was saying, don’t use them like magic scope solvers.  

Instead understand scope and visibility, and you’ll be in a much better position to code.  Just trying to take the mystery out of stuff is all.

Hey, Another question… so i have this…

 function movePlayBtn1() transition.to( playBtn,{time=1000, x = 60, y = 350, onComplete=movePlayBtn} ) end function movePlayBtn() transition.to( playBtn,{time=1000, x = 60, y = 355, onComplete=movePlayBtn1} ) end movePlayBtn()

how do i remove the 

movePlayBtn()

like how do i stop it when the scene changes? Thanks!

You don’t actually remove functions.  You can re-define them (override original), or nill them, but you’re thinking about it sideways.

You need to make it a local function instead of a global one.

This is why I told you global functions are bad, unless they must be global for a specific reason.

Wait, I missed it.  You’ve got two functions calling each other.
 
Try something like this:

-- At top of scene file local isRunning = false -- Forward declare your functions (Stop it with the globals) local movePlayBtn1 local movePlayBtn

Then, in the will or did phase of scene ‘hide()’ method: 

isRunning = false

Then, modify your functions:

movePlayBtn1 = function() if( not isRunning ) then return end transition.to( playBtn,{time=1000, x = 60, y = 350, onComplete=movePlayBtn} ) end movePlayBtn = function() if( not isRunning ) then return end transition.to( playBtn,{time=1000, x = 60, y = 355, onComplete=movePlayBtn1} ) end

Then, when you first start the ‘cycle’ do this:

isRunning = true movePlayBtn()

Hi.  Unless I’m wrong, you’re trying to solve the problem of a function not being visible when you need it, and you’re following some advice that, while not wrong, is not exactly right.

First, 

Since you did this,

function tbl:onCollision( self, event )

you’re implying this:

tbl.onCollision = function( self, self, event ) -- Colon notation implies self

What you ‘meant’ to code was this:

function tbl:onCollision( event ) -- equivalent to this: -- tbl.onCollision = function( self, event) 

Second, even if you fix this, it is wrong.  To solve the problem of visibility as you would get here:

local function doit() doit2() end local function doit2() print("hi") end doit() -- Fails

Solve it with forward declaration like this (not by using tables like you’re doing):

-- Declare the functions before you refer to them or use them local doit local doit2 -- Define the functions doit = function() doit2() -- This was forward declared so now it works end doit2 = function() print("hi") end doit() -- Works

Please read this article so you can start to better understand scope and visibility:

https://coronalabs.com/blog/2015/06/16/tutorial-scope-for-beginners/

You’re running ahead of your understanding of these VERY important concepts and you’ll only encounter more problems if you don’t learn about them quickly.  

Also, you’re using globals and that’s not good:

function spawnBall() -- This function is global now; not a great practice

Oh, one more thing. 

Thanks a lot for trimming your code down and formatting.  You rock!

I know, another post, but I can’t leave this alone.

I know someone else told you to use tables, and I said it was kinda wrong.  It is wrong the way you’re trying to use it, but if you were writing a module, this would be perfectly OK:

-- awesome.lua local public = {} function public.doit() public.doit2() end function public.doit2() print("hi") end return public

Later we could use ‘awesome.lua’ like this:

local booya = require "awesome" booya.doit() -- prints "hi" by calling doit2() internally booya.doit2() -- prints "hi"

The reason the module worked is because ‘public’ (a table) was visible and defined everyplace we refer to it.  

While the method doit2() is not attached (yet) when defining doit(), it is attached when we call it, and because we had a valid handle to ‘public’ already, we can look up the method at execution time.

Again, read that article I pointed you at.

Haha the code trimming was cause you “yelled” at me that one time haha thanks(i really mean it) But im having this problem now… so this works

 function spawnBall() print("test") end startTimer = timer.performWithDelay( 700, spawnBall, -1 )

But this one doesnt…

 function tbOne:spawnBall() -- see the tbOne added? print("test") end startTimer = timer.performWithDelay( 700, spawnBall, -1 )

why doesnt it work? scope ? cause the other functions seem to be working but this one…

Me again.

The way you had it the first time was better.  Abandon that table stuff, fix the scope issues via forward declaration, fix that global function, and you’ll be golden.

-Ed

You’re goofing up the reference

Try this:

startTimer = timer.performWithDelay( 700, tbOne.spawnBall, -1 ) -- or this startTimer = timer.performWithDelay( 700, function() tbOne:spawnBall() end, -1 )