Run-time spawned objects don't have physics attached to them.

Hi,

I have a method that creates a simple object (a food), I call this function two times and give it two positions and it creates those two foods for me at those places, adds them to physic and I have no problem touching and dragging them.

Thing is, at some point I want to generate some more of these foods, so I call this “makeOneFoodObject” code and give it position, but guess what, it creates the display object, shows it’s texture into it but it doesn’t have any physic body attached to it. And I confirm this because I put display in hybrid mode and I see physic objects.

It’s strange because I’m creating the food objects same way that I do in my main function.

[lua]local function onPurpleFoodCollision(self, event)

if ( event.phase == “began” ) then
if (event.other.myName == “PurpleMonster”) then
print( self.myName … ": collision ended with " … event.other.myName )
makeOneFoodObject(150, 150);
elseif (event.other.myName == “YellowMonster”) then
makeOneFoodObject(150, 150);
end
elseif ( event.phase == “ended” ) then
–print( self.myName … ": collision ended with " … event.other.myName )
end
end

function makeOneFoodObject(x,y)

– foodElement = { friction=0.4, bounce=0.2, filter=borderCollisionFilter }

– local purpleFoodCollisionFilter = { categoryBits = 2, maskBits = 3 } – collides with (2 & 1) only
local purpleFoodCollisionFilter = { categoryBits = 2, maskBits = 1 } – collides with (1) only
local purpleFoodPhysicSettings = { density=0.2, friction=0, bounce=0.95, radius=20.0, filter=purpleFoodCollisionFilter }

– local yellowFoodCollisionFilter = { categoryBits = 4, maskBits = 5 } – collides with (4 & 1) only
– local yellowFoodPhysicSettings = { density=0.2, friction=0, bounce=0.95, radius=23.0, filter=yellowFoodCollisionFilter }

local foodObject = display.newImageRect(“food_purple.png”, 25, 33);
foodObject:setReferencePoint(display.TopLeftReferencePoint);
foodObject.myName = “PurpleFoodObject”;

– foodObject.x = display.contentCenterX;
– foodObject.y = display.contentCenterY;

foodObject.x = x;
foodObject.y = y;

foodObject:setReferencePoint(display.CenterReferencePoint); --we need to revert reference point to center physic will move it by center.
foodObject:addEventListener(“touch”, localDrag);

foodObject.collision = onPurpleFoodCollision;
foodObject:addEventListener(“collision”, monster_yellow)

physics.addBody( foodObject, “dynamic”, purpleFoodPhysicSettings)

end

function main()
initializeGame();
makeOneFoodObject(150, 150);
makeOneFoodObject(250, 150);
makeOneFoodObject(250, 180);
end[/lua] [import]uid: 206803 topic_id: 34449 reply_id: 334449[/import]

Are you sure your physics engine is started? I plugged in your code and included some blank functions for your events as well as the physics.start() and it worked fine for me. [import]uid: 147305 topic_id: 34449 reply_id: 136991[/import]

Thanks, problem was that I was instantiating a new object in the collision detection code. [import]uid: 206803 topic_id: 34449 reply_id: 137022[/import]

I got into another problem with gameUI’s drag code.

If two of my objects are on each other and I drag one of them, the other one will stuck to the background. It’s like it generates a false joint due to some bug and I can drag around the stuck object around that joint.

Anyone witnessed such thing? [import]uid: 206803 topic_id: 34449 reply_id: 137137[/import]

Add “return true” to the end of the touch function.

At least that’s what’s worked for me before. [import]uid: 147322 topic_id: 34449 reply_id: 137140[/import]

Thanks Caleb for your reply. If you are referring to touch function in gameUI, last line before the end is “return true”.

I’m using version 2.0 of gameUI:

[lua]-- gameUI library

– Version 2.0 (updated for new audio API)

– Copyright © 2010 Corona Labs Inc. All Rights Reserved.

– Permission is hereby granted, free of charge, to any person obtaining a copy of
– this software and associated documentation files (the “Software”), to deal in the
– Software without restriction, including without limitation the rights to use, copy,
– modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
– and to permit persons to whom the Software is furnished to do so, subject to the
– following conditions:

– The above copyright notice and this permission notice shall be included in all copies
– or substantial portions of the Software.

– THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
– INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
– PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
– FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
– OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
– DEALINGS IN THE SOFTWARE.

module(…, package.seeall)

– A general function for dragging physics bodies

– Simple example:
– local dragBody = gameUI.dragBody
– object:addEventListener( “touch”, dragBody )

function dragBody( 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

– Create a temporary touch joint and store it in the object for later reference
if params and params.center then
– drag the body from its center point
body.tempJoint = physics.newJoint( “touch”, body, body.x, body.y )
else
– drag the body from the point where it was touched
body.tempJoint = physics.newJoint( “touch”, body, event.x, event.y )
end

– Apply optional joint parameters
if params then
local maxForce, frequency, dampingRatio

if params.maxForce then
– Internal default is (1000 * mass), so set this fairly high if setting manually
body.tempJoint.maxForce = params.maxForce
end

if params.frequency then
– This is the response speed of the elastic joint: higher numbers = less lag/bounce
body.tempJoint.frequency = params.frequency
end

if params.dampingRatio then
– Possible values: 0 (no damping) to 1.0 (critical damping)
body.tempJoint.dampingRatio = params.dampingRatio
end
end

elseif body.isFocus then
if “moved” == phase then

– Update the joint to track the touch
body.tempJoint:setTarget( event.x, event.y )

elseif “ended” == phase or “cancelled” == phase then
stage:setFocus( body, nil )
body.isFocus = false

– Remove the joint when the touch ends
body.tempJoint:removeSelf()

end
end

– Stop further propagation of touch event
return true
end[/lua] [import]uid: 206803 topic_id: 34449 reply_id: 137142[/import]

Edited…

I think I see where you are running into problems, but not sure since I’ve never played with physics joints or this drag code for physics objects. I guess it’s for dragging an active physics body into another physics body causing a collision.

You’re creating multiple foodObjects without differentiating them from each other.

I don’t believe you can do this successfully without causing a variety of strange behavior.

I believe you need to first create a table to hold your spawned objects.

local foodObjects = {}

Then you need to spawn the new objects with an individual index number into the table foodObjects.

You’ve got to tap into the power of lua tables.

foodObjects[1], foodObjects[2], etc.

When spawning the new objects, I’d also give them an easily referenced ID, something like…

foodObjects[i].ID = i

Then when you go to drag your object you can focus your touch on the single object, differentiating it from other similar objects and you can reference that object with it’s event.target.ID.

You can then do whatever you’d like to that object, move it, destroy it, scale it or whatever and you can reference it for other purposes with it’s ID.

Lua tables, table creation, table manipulation, and table referencing are where you want to focus some effort IMO.

Once you get a handle on lua tables, your only limited by you imagination.

Nail

[import]uid: 106779 topic_id: 34449 reply_id: 137143[/import]

Here’s some behind-the-screen info as to what’s happening:

When you touch something with something else behind it, it’s creating two joints - one for the top object and one for the bottom object. Then, when you move your touch, it’s only registering one object to be moved. So it’s adjusting the top joint, but not adjusting the bottom joint. Then, when you touch the bottom object, it’s already got a joint, so it creates another, and now you have two. When you move the touch, the two joints fight for control, and it goes between them like a slingshot without any launch power.

This also happens if you have a touch listener that does not return true at the end and you release the touch on top of something that does have return true at the end - it doesn’t register an “ended” phase. That’s why I told you to add “return true”.

So that’s some background information so that you can know what exactly is happening. [import]uid: 147322 topic_id: 34449 reply_id: 137201[/import]

Are you sure your physics engine is started? I plugged in your code and included some blank functions for your events as well as the physics.start() and it worked fine for me. [import]uid: 147305 topic_id: 34449 reply_id: 136991[/import]

Thanks, problem was that I was instantiating a new object in the collision detection code. [import]uid: 206803 topic_id: 34449 reply_id: 137022[/import]

@xnailbender: Why would I need to differentiate them? Whenever any of them is called, it will be called by reference and I’ll have pointer to the actual object.

@Caleb: I didn’t totally understand your first paragraph but I think you are right. So what do you think I can do to solve this? [import]uid: 206803 topic_id: 34449 reply_id: 137438[/import]

Aidin wrote:

@xnailbender: Why would I need to differentiate them? Whenever any of them is called, it will be called by reference and I’ll have pointer to the actual object.

Newb here, so understand I’m not an expert on anything. Just trying to help and hope I’m not creating confusion. As I stated, I haven’t used the physics drag module before either.

I’m not really sure what your “pointer” actually is. I probably just don’t see the obvious.

From my “newbish” viewpoint, it seems to me your only “pointer” is “foodObject”.

I just don’t see how 1 “foodObject” is differentiated from another “foodObject”,

I can see how “foodObject[1]” is differentiated from “foodObject[2]” as the index values are different.

It seems to me the event.target is “foodObject”, unless the event.target can somehow differentiate 1 similar object from another, really not sure how that works if it does.

It seems to me, foodObject.x = event.target.x will move both similar foodObject’s at the same time when 1 of them is dragged, causing unexpected behavior.

I can see how foodObject[1].x = event.target.x will move only foodObject[1].x when dragged and foodObject[2] will be unaffected.

I’m thinking this is why both of your foodObjects are moving simultaneously when dragged, but not really sure because every similar object I spawn has an index reference.

If your get your issue resolved, I’d like to know what the solution was if you’d post it here.

Hope this helps,

Nail

[import]uid: 106779 topic_id: 34449 reply_id: 137506[/import]

@Nail/xnailbender:

If it was what you described, then if you drag any object, any (and perhaps all) other object would move with it or cause the bug I described in the very first post. But it’s not. As I tried to explain earlier, you do not need to ID objects because you do not access them with code, so you would not know which is which.

The way you find which object is under touch is via touch event. Because each object is registered with touch event, then if you touch any of them, the only one that is affected by touch event will be called. So no need for an ID.

I believe problem is perhaps the gameUI’s drag code. As far as I understood, when you drag an object with dragUI’s drag code, it temporarily makes a joint and uses that [somehow] to make that joint follow your finger around. And I believe it’s in this process of making a temporary joint that the bug occurs.

Somehow when there is another object under the designated/touched object, the under object gets stuck to the background.

I can be totally wrong about this as I’m new to Corona and have very little understanding of it and other areas such as gameUI.

Thanks. [import]uid: 206803 topic_id: 34449 reply_id: 137542[/import]

The gameUI code is not wrong. It’s worked many times for me before.

I’ll describe it again, see if you understand now:
To dragBody something from gameUI, it creates a joint attached to 1) the touch point and 2) the object. When you move your mouse (or finger), the joint is updated to connect 1) your touch point and 2) the object. So the object is pulled towards your click (or touch). When you touch something with something else underneath it, for some reason the touch registers to the bottom object, too. So now we have two joints, one attached from your touch point to object 1 (in the front) and one attached from your touch point to object 2 (in the back). When you move your touch, it does not pick up the bottom object as being touched (that should have been what it did from the start). So it only updates the top object’s joint. And an extra joint is still attached to the previous object - going towards the original touch point. So when you move your touch, object 1 moves and object 2 doesn’t. Then, when you try to move object 2, it’s already got a joint attached to it. So both joints fight with each other and you get what you thought was “stuck to the background”.

So in the end, I don’t believe gameUI is wrong - I think it’s something in your code. Can you post the part where you add the dragBody listener to the foods? [import]uid: 147322 topic_id: 34449 reply_id: 137546[/import]

Thanks Caleb,
I don’t do anything fancy here, I just register my foodObject with a localDrag function to control and experiment with different types of dragBody configs, so essentially localDrag is just one line of code:

[lua]local function localDrag( event )
– foodObject:addEventListener(“touch”, foodOnTouch);
– gameUI.dragBody( event, {} )
– gameUI.dragBody(event, {maxForce = 100, frequency = 2} ) – slow, elastic dragging
– gameUI.dragBody(event, {maxForce = 100, frequency = 2, center = true } ) – slow, elastic dragging
gameUI.dragBody(event, {maxForce = 20000, frequency = 10, dampingRatio = 0.2, center = true }) --very tight

– isTouched is a flag to indicate that player previously touched this food object and if later on this
– object hits with a monster, then that collision is valid. So this prevents foods to get eaten by
– monsters when they move freely and accidentally collide with a monster.
– (We can toggle this to false after some time, if we want)
event.target.isTouched = true;
end[/lua]

And in the creation of a foodObject, somewhere in the end I do this:
[lua] foodObject:setReferencePoint(display.CenterReferencePoint); --we need to revert reference point to center physic will move it by center.
foodObject:addEventListener(“touch”, localDrag);[/lua]

Hope that helps. [import]uid: 206803 topic_id: 34449 reply_id: 137547[/import]

I got into another problem with gameUI’s drag code.

If two of my objects are on each other and I drag one of them, the other one will stuck to the background. It’s like it generates a false joint due to some bug and I can drag around the stuck object around that joint.

Anyone witnessed such thing? [import]uid: 206803 topic_id: 34449 reply_id: 137137[/import]

Add “return true” to the end of the touch function.

At least that’s what’s worked for me before. [import]uid: 147322 topic_id: 34449 reply_id: 137140[/import]

Thanks Caleb for your reply. If you are referring to touch function in gameUI, last line before the end is “return true”.

I’m using version 2.0 of gameUI:

[lua]-- gameUI library

– Version 2.0 (updated for new audio API)

– Copyright © 2010 Corona Labs Inc. All Rights Reserved.

– Permission is hereby granted, free of charge, to any person obtaining a copy of
– this software and associated documentation files (the “Software”), to deal in the
– Software without restriction, including without limitation the rights to use, copy,
– modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
– and to permit persons to whom the Software is furnished to do so, subject to the
– following conditions:

– The above copyright notice and this permission notice shall be included in all copies
– or substantial portions of the Software.

– THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
– INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
– PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
– FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
– OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
– DEALINGS IN THE SOFTWARE.

module(…, package.seeall)

– A general function for dragging physics bodies

– Simple example:
– local dragBody = gameUI.dragBody
– object:addEventListener( “touch”, dragBody )

function dragBody( 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

– Create a temporary touch joint and store it in the object for later reference
if params and params.center then
– drag the body from its center point
body.tempJoint = physics.newJoint( “touch”, body, body.x, body.y )
else
– drag the body from the point where it was touched
body.tempJoint = physics.newJoint( “touch”, body, event.x, event.y )
end

– Apply optional joint parameters
if params then
local maxForce, frequency, dampingRatio

if params.maxForce then
– Internal default is (1000 * mass), so set this fairly high if setting manually
body.tempJoint.maxForce = params.maxForce
end

if params.frequency then
– This is the response speed of the elastic joint: higher numbers = less lag/bounce
body.tempJoint.frequency = params.frequency
end

if params.dampingRatio then
– Possible values: 0 (no damping) to 1.0 (critical damping)
body.tempJoint.dampingRatio = params.dampingRatio
end
end

elseif body.isFocus then
if “moved” == phase then

– Update the joint to track the touch
body.tempJoint:setTarget( event.x, event.y )

elseif “ended” == phase or “cancelled” == phase then
stage:setFocus( body, nil )
body.isFocus = false

– Remove the joint when the touch ends
body.tempJoint:removeSelf()

end
end

– Stop further propagation of touch event
return true
end[/lua] [import]uid: 206803 topic_id: 34449 reply_id: 137142[/import]

Edited…

I think I see where you are running into problems, but not sure since I’ve never played with physics joints or this drag code for physics objects. I guess it’s for dragging an active physics body into another physics body causing a collision.

You’re creating multiple foodObjects without differentiating them from each other.

I don’t believe you can do this successfully without causing a variety of strange behavior.

I believe you need to first create a table to hold your spawned objects.

local foodObjects = {}

Then you need to spawn the new objects with an individual index number into the table foodObjects.

You’ve got to tap into the power of lua tables.

foodObjects[1], foodObjects[2], etc.

When spawning the new objects, I’d also give them an easily referenced ID, something like…

foodObjects[i].ID = i

Then when you go to drag your object you can focus your touch on the single object, differentiating it from other similar objects and you can reference that object with it’s event.target.ID.

You can then do whatever you’d like to that object, move it, destroy it, scale it or whatever and you can reference it for other purposes with it’s ID.

Lua tables, table creation, table manipulation, and table referencing are where you want to focus some effort IMO.

Once you get a handle on lua tables, your only limited by you imagination.

Nail

[import]uid: 106779 topic_id: 34449 reply_id: 137143[/import]

@Aidin wrote:

The way you find which object is under touch is via touch event

Got it, I see how it is working now, at least for now anyways as long as their is an event to handle the object.

I’d still spawn into a table as it’s so versatile, but realize it’s not part of your issue now.

Like Caleb says, “return true” and stop the touch propagation (I think that’s the term anyways).

The drag code works, it’s pretty cool, I’ve never played with it.

I’ve also never passed a “touch” event through an event listener before, I didn’t even know that could be done.

Hope this helps,

Nail

[import]uid: 106779 topic_id: 34449 reply_id: 137576[/import]