How do i change content inside function?

Hi out there!

I am having some trouble with getting inside a function to change psysics body on element.

I need to change:

physics.addBody( angel, “kinematic”, …

to

“dynamic”
Can somebody tell me what i am doing wrong in my code?

function angel (a,b,c)  
 local angel = display.newImage("assets/angelTest.png")  
 angel.x, angel.y = a, b  
 angel.rotation = c  
 angel.name = "angel"  
  
 angelShape1 = { -30, -30 , -50, -50 , 50, -50 , 50, -30 }  
 angelShape2 = { -30, -30 , -30, 50 , -50, 50 , -50, -50 }  
  
 physics.addBody( angel, "kinematic",  
 { density=3.0, friction=0.6, bounce=0.2, shape=angelShape1 },  
 { density=3.0, friction=0.6, bounce=0.2, shape=angelShape2 }  
 )  
end  
  
angel(300,400, 0)  
  
function onCollision( event )  
  
 if ((event.object1.name == "lou") and (event.object2.id == "evilRazorBalls") ) then  
  
 if ( event.phase == "began" ) then  
   
 print( "began: " .. event.object1.name .. " & " .. event.object2.name .. " - DIE " )  
  
 elseif ( event.phase == "ended" ) then  
   
 -- Nothing to do for now  
   
 end  
  
 end  
  
 if (event.object1.name == "angel") then  
 print("hit")  
 angel.bodyType = "dynamic"  
  
 end   
  
end  
  

[import]uid: 112262 topic_id: 29294 reply_id: 329294[/import]

Hi there,

Two things:

  1. You have two variables named angel. The first is the function. The second is a variable created within, and local to, that function, referring to the display/physics object. In your onCollision function, you refer to angel. Which angel is being referred to? It’s the function, not the display/physics object, because the display/physics variable angel was local to that function and is not visible outside it. I’d suggest first renaming your function to something like createAngel, to avoid confusion. Second, if you make angel a global variable, or pre-declare it as local outside the createAngel function, then it will be accessible within onCollision.

  2. Modifying the properties of a physics body during a collision can cause problems. Instead, you should use timer.performWithDelay, with a very slight delay (even 1 millisecond is fine), so that the change to the angel’s physics type occurs after all of the collision processing is complete.

Hope this helps.

  • Andrew [import]uid: 109711 topic_id: 29294 reply_id: 117804[/import]

If i make it global it works! To pre-declare the VAR outside does not work for me. Think i am doing something wrong.

But what is the best to do?

“Modifying the properties of a physics body during a collision can cause problems”

  • Preform issue? (hate doing something without knowing why)

Thank you very much for your reply! (: [import]uid: 112262 topic_id: 29294 reply_id: 117866[/import]

Hi there,

I’d suggest the following code (which is meant to address both issues I pointed out). The changes are:

  • Forward declared the angel variable ahead of both functions
  • Renamed the first function to createAngel and removed the “local” keyword in the first line
  • Used a timer.performWithDelay to slightly delay the modification of the angel’s bodyType until after the collision calculations are completed
  • Changed that if statement to test both object1 and object2
  • Added a listener for the collision function

[blockcode]
local angel

function createAngel (a,b,c)
angel = display.newImage(“assets/angelTest.png”)
angel.x, angel.y = a, b
angel.rotation = c
angel.name = “angel”

angelShape1 = { -30, -30 , -50, -50 , 50, -50 , 50, -30 }
angelShape2 = { -30, -30 , -30, 50 , -50, 50 , -50, -50 }

physics.addBody( angel, “kinematic”,
{ density=3.0, friction=0.6, bounce=0.2, shape=angelShape1 },
{ density=3.0, friction=0.6, bounce=0.2, shape=angelShape2 }
)
end

createAngel(300,400, 0)

function onCollision( event )

if ((event.object1.name == “lou”) and (event.object2.id == “evilRazorBalls”) ) then

if ( event.phase == “began” ) then

print( "began: " … event.object1.name … " & " … event.object2.name … " - DIE " )

elseif ( event.phase == “ended” ) then

– Nothing to do for now

end

end

if (event.object1.name == “angel” or event.object2.name == “angel”) then
print(“hit”)
timer.performWithDelay(1, function() angel.bodyType = “dynamic” end)

end

end

Runtime:addEventListener( “collision”, onCollision )

[/blockcode]

Let me know if it works.

  • Andrew [import]uid: 109711 topic_id: 29294 reply_id: 117943[/import]

It works!

“Changed that if statement to test both object1 and object2”

  • Wooops, missed that

Thank you for the awesome help (:
[import]uid: 112262 topic_id: 29294 reply_id: 117945[/import]