Explanation regarding collisions - CodeandWeb Physics editor

Hi guys,

I have one question  :rolleyes:

I am using CodeAndWeb Physics editor.

When you look at collision boundaries in physics “debug” mode (please see attached jpg), you will see the inner circle (which is basically collision shape loaded/created by Physics editor - smaller in size than actual PNG I am loading).

And you will also see outer Rectangle shape (whole PNG basically).

My problem is: Collisions are registered even when outer Rectangle shape is collided with another dynamic object. This should not happen, collisions should be registered only when dynamic object hits inner circle ?

So this is the case where static object (above mentioned PNG) is collided with dynamic object.

Waiting your reply.

Many thanks!

Ivan 

Need to see the code really to see what’s going wrong…

Hi Nick,

Here is the chunk that regulates collision.

display.setStatusBar(display.HiddenStatusBar) -- most commonly used screen coordinates local centerX = display.contentCenterX local centerY = display.contentCenterY local screenLeft = display.screenOriginX local screenWidth = display.viewableContentWidth - screenLeft \* 2 local screenRight = screenLeft + screenWidth local screenTop = display.screenOriginY local screenHeight = display.viewableContentHeight - screenTop \* 2 local screenBottom = screenTop + screenHeight local physics = require("physics") physics.start() physics.setDrawMode( "debug" ) physics.setGravity( 0, 0 ) local spriteObstacles = require "spriteObstacles" --- TABLE THAT CONTAINS MULTIPLE OBSTACLE OBJECTS local randomObstacle = spriteObstacles[math.random(#spriteObstacles)] local physicsData = randomObstacle.image\_sheet.physicsData() --- SUBTABLE THAT CONTAINS PHYSICS DATA local function playersCollision(event) print("COLLIDED") end local  obstacle = display.newImageRect(randomObstacle.img, randomObstacle.wi, randomObstacle.he)        obstacle.x = centerX        obstacle.y = math.random(screenHeight\*0.1, screenHeight\*0.9)        obstacle.typ = "obstacle" --- .nam is just a string like "obstacle24", used to identify specific obstacle       physics.addBody(obstacle, "static", physicsData:get(randomObstacle.nam), {density=1.0, friction=0.2, bounce=0 })        obstacle.collision = playersCollision        obstacle:addEventListener( "collision", obstacle )                    local ball = display.newCircle( screenLeft, (obstacle.y+obstacle.height\*0.65), 30 )           ball:setFillColor(0, 1, 0)           physics.addBody ( ball, "dynamic", {density=1.0, friction=0.2, bounce=0 })           ball:setLinearVelocity(100, 0)

Ball does not even enter Obstacle area, it does not penetrate inside the smaller area where collision should occur.

Ball immediately gets bounced off the outside Obstacle boundaries…

Nope. if that is debug mode, (you should really use hybrid), the issue is that you have two bodies attached to the object.  That is what I’m seeing in the picture.

I think this call:

physicsData:get(randomObstacle.nam)

is returning a multi-part body.  You should check it out in you editor.  You should also check out the file “spriteObstacles” to see if any multi-part bodies are defined.

Hi Ed,

I got that code ( physicsData:get(randomObstacle.nam) ) from official tutorial:

https://www.codeandweb.com/texturepacker/tutorials/example-with-coronasdk-using-physicseditor-texturepacker

— .nam is just a string like “obstacle24”, used to identify specific obstacle

No multipart bodies are defined in file “spriteObstacles”

Check out one obstacle example that I am loading (attached).

It was created by Physics Editor tool.

I had to change spike1.lua to spike1.doc in order to upload it here…

Sorry don’t know what to tell you then.  I’ll let someone who also uses this tool chime in.  I’m afraid I do all my collisions using basic bodies or manually.  :frowning:

OK Ed.

I hope somebody will take a look at this for me?  :blink:

***UPDATE***

I found one solution.

I apply neutral newFilter to obstacle like this:

local newFilter = {categoryBits = 8, maskBits = 4} physics.addBody(obstacle, "static", physicsData:get(randomObstacle.nam), {density=1.0, friction=0.2, bounce=0, filter = newFilter })

This takes care that ball does not collide with obstacle, i.e ball only collides with inner circle (because newFilter apparently does not apply to inner circle).

I would still like to know what is going on here (despite this solution) !  :smiley:

You are currently not creating a “inner circle”:

          local ball = display.newCircle( screenLeft, (obstacle.y+obstacle.height*0.65), 30 )

          ball:setFillColor(0, 1, 0)
          physics.addBody ( ball, “dynamic”, {density=1.0, friction=0.2, bounce=0 })
          ball:setLinearVelocity(100, 0)

You are creating a circle shape and set the colors.

After that you create a physics body for this shape - but you are not specifying any shape at all. Corona now uses the shape’s bounding box. https://docs.coronalabs.com/api/library/physics/addBody.html - see “Examples -> Rectangular Body”.

You can either create the ball’s outlines in PhysicsEditor - or specify it manually by adding the radius parameter:

        physics.addBody( ball, { density=1.0, friction=0.3, bounce=0.2, radius=30  } )

Hi Andreas,

Thanks for your input.

I think you misunderstood me.

Ball is the dynamic object that collides with the obstacle (static object).

I am using Physics Editor only for the obstacle (not for the ball).

I am initializing physics shape created by Physics Editor for the obstacle - please see my first post in this thread.

Like this:

local  obstacle = display.newImageRect(randomObstacle.img, randomObstacle.wi, randomObstacle.he)        obstacle.x = centerX        obstacle.y = math.random(screenHeight\*0.1, screenHeight\*0.9)        obstacle.typ = "obstacle" --- .nam is just a string like "obstacle24", used to identify specific obstacle       physics.addBody(obstacle, "static", physicsData:get(randomObstacle.nam), {density=1.0, friction=0.2, bounce=0 }) 

I think I have it.

When you call physics.addBody, you pull in the data for randomObstacle.nam. This includes radius, density, friction, bounce etc which are set the editor. So this creates the ‘inner circle’ physics object.

[lua]

physics.addBody(obstacle, “static”, physicsData:get(randomObstacle.nam)

   – CIRCLE PHYSICS OBJECT CREATED

[/lua]

You then added this code:

[lua]

, {density=1.0, friction=0.2, bounce=0 }

– RECTANGLE PHYSICS OBJECT CREATED

[/lua]

Which creates another rectangular physics object the size of the obstacle image.

So I think the code should just be:

[lua]

physics.addBody(obstacle, “static”, physicsData:get(randomObstacle.nam))

[/lua]

I am such an idiot!  :smiley:

Thanks Nick!

One last question please.

How to change precreated filter bits on the fly (later on)?

-- This file is for use with Corona(R) SDK -- -- This file is automatically generated with PhysicsEdtior (http://physicseditor.de). Do not edit -- -- Usage example: --                local scaleFactor = 1.0 --                local physicsData = (require "shapedefs").physicsData(scaleFactor) --                local shape = display.newImage("objectname.png") --                physics.addBody( shape, physicsData:get("objectname") ) -- -- copy needed functions to local scope local unpack = unpack local pairs = pairs local ipairs = ipairs local M = {} function M.physicsData(scale)       local physics = { data =       {                         ["spike1"] = {                                                                                 {                     pe\_fixture\_id = "", density = 2, friction = 0.30000000000000004, bounce = 0.20000000000000001,                     filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 },                     radius = 17.000                     }                                                     }                   } }         -- apply scale factor         local s = scale or 1.0         for bi,body in pairs(physics.data) do                 for fi,fixture in ipairs(body) do                     if(fixture.shape) then                         for ci,coordinate in ipairs(fixture.shape) do                             fixture.shape[ci] = s \* coordinate                         end                     else                         fixture.radius = s \* fixture.radius                     end                 end         end             function physics:get(name)             return unpack(self.data[name])       end       function physics:getFixtureId(name, index)                 return self.data[name][index].pe\_fixture\_id       end             return physics; end return M

I am aiming at this line:

filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 },

 

You could create a table that holds over-ride parameters.

[lua]

local override = {{spike1 = {categoryBits = 2, maskBits = 12345, groupIndex = 1}}}

[/lua]

Then check this table before you add the physics body.

[lua]

local data = physicsData:get(randomObstacle.nam)

if override[randomObstacle.nam] ~= nil then

  data.filter = override[randomObstacle.nam]

end

  1. physics.addBody(obstacle, “static”, data)

[/lua]

 

If you need to do this to an already created obstacle, you’ll need to removeBody and then immediately addBody again.

  1.  

Need to see the code really to see what’s going wrong…

Hi Nick,

Here is the chunk that regulates collision.

display.setStatusBar(display.HiddenStatusBar) -- most commonly used screen coordinates local centerX = display.contentCenterX local centerY = display.contentCenterY local screenLeft = display.screenOriginX local screenWidth = display.viewableContentWidth - screenLeft \* 2 local screenRight = screenLeft + screenWidth local screenTop = display.screenOriginY local screenHeight = display.viewableContentHeight - screenTop \* 2 local screenBottom = screenTop + screenHeight local physics = require("physics") physics.start() physics.setDrawMode( "debug" ) physics.setGravity( 0, 0 ) local spriteObstacles = require "spriteObstacles" --- TABLE THAT CONTAINS MULTIPLE OBSTACLE OBJECTS local randomObstacle = spriteObstacles[math.random(#spriteObstacles)] local physicsData = randomObstacle.image\_sheet.physicsData() --- SUBTABLE THAT CONTAINS PHYSICS DATA local function playersCollision(event) print("COLLIDED") end local  obstacle = display.newImageRect(randomObstacle.img, randomObstacle.wi, randomObstacle.he)        obstacle.x = centerX        obstacle.y = math.random(screenHeight\*0.1, screenHeight\*0.9)        obstacle.typ = "obstacle" --- .nam is just a string like "obstacle24", used to identify specific obstacle       physics.addBody(obstacle, "static", physicsData:get(randomObstacle.nam), {density=1.0, friction=0.2, bounce=0 })        obstacle.collision = playersCollision        obstacle:addEventListener( "collision", obstacle )                    local ball = display.newCircle( screenLeft, (obstacle.y+obstacle.height\*0.65), 30 )           ball:setFillColor(0, 1, 0)           physics.addBody ( ball, "dynamic", {density=1.0, friction=0.2, bounce=0 })           ball:setLinearVelocity(100, 0)

Ball does not even enter Obstacle area, it does not penetrate inside the smaller area where collision should occur.

Ball immediately gets bounced off the outside Obstacle boundaries…

Nope. if that is debug mode, (you should really use hybrid), the issue is that you have two bodies attached to the object.  That is what I’m seeing in the picture.

I think this call:

physicsData:get(randomObstacle.nam)

is returning a multi-part body.  You should check it out in you editor.  You should also check out the file “spriteObstacles” to see if any multi-part bodies are defined.

Hi Ed,

I got that code ( physicsData:get(randomObstacle.nam) ) from official tutorial:

https://www.codeandweb.com/texturepacker/tutorials/example-with-coronasdk-using-physicseditor-texturepacker

— .nam is just a string like “obstacle24”, used to identify specific obstacle

No multipart bodies are defined in file “spriteObstacles”

Check out one obstacle example that I am loading (attached).

It was created by Physics Editor tool.

I had to change spike1.lua to spike1.doc in order to upload it here…

Sorry don’t know what to tell you then.  I’ll let someone who also uses this tool chime in.  I’m afraid I do all my collisions using basic bodies or manually.  :frowning:

OK Ed.

I hope somebody will take a look at this for me?  :blink:

***UPDATE***

I found one solution.

I apply neutral newFilter to obstacle like this:

local newFilter = {categoryBits = 8, maskBits = 4} physics.addBody(obstacle, "static", physicsData:get(randomObstacle.nam), {density=1.0, friction=0.2, bounce=0, filter = newFilter })

This takes care that ball does not collide with obstacle, i.e ball only collides with inner circle (because newFilter apparently does not apply to inner circle).

I would still like to know what is going on here (despite this solution) !  :smiley:

You are currently not creating a “inner circle”:

          local ball = display.newCircle( screenLeft, (obstacle.y+obstacle.height*0.65), 30 )

          ball:setFillColor(0, 1, 0)
          physics.addBody ( ball, “dynamic”, {density=1.0, friction=0.2, bounce=0 })
          ball:setLinearVelocity(100, 0)

You are creating a circle shape and set the colors.

After that you create a physics body for this shape - but you are not specifying any shape at all. Corona now uses the shape’s bounding box. https://docs.coronalabs.com/api/library/physics/addBody.html - see “Examples -> Rectangular Body”.

You can either create the ball’s outlines in PhysicsEditor - or specify it manually by adding the radius parameter:

        physics.addBody( ball, { density=1.0, friction=0.3, bounce=0.2, radius=30  } )