swapping in alternative physics shapes on the fly

I need to swap in new physics properties on the fly. This , so nearly does it,
and yet, only in the y direction, it seems to have some glitch.
All the shapes are symmetrical in both X and Y so I don’t understand
the jumping in Y only.

Can anyone explain?

display.setStatusBar( display.HiddenStatusBar )  
  
local physics = require("physics")  
  
math.randomseed(os.time())  
mr = math.random  
sf = string.format  
\_G.W = display.contentWidth  
\_G.H = display.contentHeight  
  
physics.start()  
  
--------------------------------------------------------------------------  
  
function mkReboundCushions(tin, bin, lin, rin,r,g,b,a)  
 local DG\_cushions = display.newGroup()  
 local \_H = display.contentHeight  
 local \_W = display.contentWidth  
 local OSthickness = 5  
  
 local top = display.newRect(0,0,\_W,tin+OSthickness+9)  
 local bot = display.newRect(0,\_H-bin,\_W,\_H-OSthickness)  
 local left = display.newRect(0,0,lin,\_H)  
 local rght = display.newRect(\_W-rin,0,\_W+OSthickness,\_H)  
  
 DG\_cushions:insert(top)  
 DG\_cushions:insert(bot)  
 DG\_cushions:insert(left)  
 DG\_cushions:insert(rght)  
  
 top:setFillColor(r,g,b,a)  
 bot:setFillColor(r,g,b,a)  
 left:setFillColor(r,g,b,a)  
 rght:setFillColor(r,g,b,a)  
 top.y = -1\* OSthickness  
  
 top.name = "top"  
 bot.name = "bot"  
 left.name = "left"  
 rght.name = "rght"  
  
 physics.addBody( top, "static", { friction=0.5, bounce= 1.0 } )  
 physics.addBody( bot, "static", { friction=0.5, bounce= 1.0 } )  
 physics.addBody( left, "static", { friction=0.5, bounce= 1.0 } )  
 physics.addBody( rght, "static", { friction=0.5, bounce= 1.0 } )  
 return DG\_cushions  
end  
  
--------------------------------------------------------------------------  
--------------------------------------------------------------------------  
  
function isMemberOfList(candidate,list)  
 local result = false  
 for i=1,#list do  
 if candidate == list[i] then  
 result = true  
 end  
 end  
 return result  
end  
  
--------------------------------------------------------------------------  
  
local function swapInNewShape( self, shapeChoice )  
 local legalChoices = { "square", "circle", "ellipse" , "ellipseSmall" }  
 local checkOK = isMemberOfList(shapeChoice,legalChoices)  
 if checkOK then  
 local xPos, yPos = self.x, self.y  
 local xVel, yVel = self:getLinearVelocity()  
  
 -- FIRST, REMOVE PHYSICS BODY, THEN ADD THE REPLACEMENT WHICH HAS A NEW SHAPE  
 physics.removeBody( self )  
  
 if shapeChoice == "square" then  
 physics.addBody(self,"dynamic", {density=0.5,friction=0.1, bounce=0.9} )  
 print(sf("swapping in %s", shapeChoice))  
  
 elseif shapeChoice == "circle" then  
 physics.addBody(self,"dynamic", {density=0.5,friction=0.1, bounce=0.9, radius = 25} )  
 print(sf("swapping in %s", shapeChoice))  
  
 elseif shapeChoice == "ellipse" then  
 local ellipseShape = defineEllipseShape(30, 15)  
 physics.addBody(self,"dynamic", {density=0.5,friction=0.1, bounce=0.9, shape = ellipseShape} )  
 print(sf("swapping in %s", shapeChoice))  
  
 elseif shapeChoice == "ellipseSmall" then  
 local ellipseShape = defineEllipseShape(15, 7.5)  
 physics.addBody(self,"dynamic", {density=0.5,friction=0.1, bounce=0.9, shape = ellipseShape} )  
 print(sf("swapping in %s", shapeChoice))  
  
 else  
 print("Your shape choice is not one of: square,circle or ellipse")  
 end  
  
  
 --self.x, self.y = xPos + xVel, yPos + yVel  
 --self.x, self.y = xPos + xVel/100, yPos + yVel/100  
 self:setLinearVelocity(xVel, yVel)  
 self.isFixedRotation=true  
 self.linearDamping = 0.01  
 else  
 print(sf("Failed to swap shape to %s" , shapeChoice))  
 end -- of CheckOK  
  
end  
  
--------------------------------------------------------------------------  
  
function defineEllipseShape(radiusX,radiusY)  
 --print("in defineEllipseShape)")  
 -- THIS ELLIPSE VERT CREATING FUNCTION DIFFERS FROM mkListVertsEllipse BELOW IN THAT IT'S SPECIFICALLY  
 -- FOR SHAPES INTENTED FOR COLLISIONS, THUS #=8 AND CLOCK-WISE.  
 local x,y  
 local pi = math.pi  
 local ellipseShape = {}  
 for i=8,1,-1 do  
 x = radiusX \* math.sin(i\*2\*pi/8)  
 y = radiusY \* math.cos(i\*2\*pi/8)  
 --print(string.format("x and y are %s and %s", x,y))  
 table.insert(ellipseShape,x)  
 table.insert(ellipseShape,y)  
 end  
 return ellipseShape  
end  
  
---------------------------------------------------------------------------------------------------------------  
---------------------------------------------------------------------------------------------------------------  
  
local function makePlayer(playerName,diskRad)  
 local randVel = 150  
 local player = display.newCircle(math.random(0,240), math.random(0,360), diskRad)  
 --player:setReferencePoint(display.CenterReferencePoint)  
 player.xScale = 1  
 player.yScale = 1/2  
  
 player.name=playerName  
 player.x = mr(20,300)  
 player.y = mr(20,460)  
  
 local ellipseShape = defineEllipseShape(diskRad,diskRad\*0.5)  
 physics.addBody(player,"dynamic", {density=1,bounce=0.5, shape = ellipseShape})  
 player.isFixedRotation=true  
 player.linearDamping = 0.01  
  
 -- METHODS...  
 player.swapInNewShape = swapInNewShape  
  
 -- LOCAL LISTENERS --  
 player:addEventListener( "collision", player)  
  
 --player:setLinearVelocity( mr(-randVel,randVel), mr(-randVel,randVel) )  
 player:setLinearVelocity( 100,0 )  
 --player:setLinearVelocity( 1,100 )  
  
 return player  
end  
  
--------------------------------------------------------------------------  
--------------------------------------------------------------------------  
--------------------------------------------------------------------------  
--------------------------------------------------------------------------  
  
physics.setDrawMode("hybrid")  
physics.setGravity(0,0)  
  
mkReboundCushions(1,35,1,1,45,45,45,255)  
  
playerRed1 = makePlayer("playerRed1",30)  
playerRed1:setFillColor(255,99,99,255)  
myclosureSwapSquare = function() return playerRed1:swapInNewShape( "square" ) end  
myclosureSwapCircle = function() return playerRed1:swapInNewShape( "circle" ) end  
myclosureSwapEllipse = function() return playerRed1:swapInNewShape( "ellipse" ) end  
myclosureSwapEllipseSmall = function() return playerRed1:swapInNewShape( "ellipseSmall" ) end  
  
timer.performWithDelay( 4000, myclosureSwapSquare, 1 )  
timer.performWithDelay( 6000, myclosureSwapCircle, 1 )  
timer.performWithDelay( 8000, myclosureSwapEllipse, 1 )  
timer.performWithDelay(10000, myclosureSwapEllipseSmall, 1 )  
  
timer.performWithDelay( 12000, myclosureSwapSquare, 1 )  
timer.performWithDelay( 14000, myclosureSwapCircle, 1 )  
timer.performWithDelay( 16000, myclosureSwapEllipse, 1 )  
timer.performWithDelay( 18000, myclosureSwapEllipseSmall, 1 )  
  
timer.performWithDelay( 22000, myclosureSwapSquare, 1 )  
timer.performWithDelay( 24000, myclosureSwapCircle, 1 )  
timer.performWithDelay( 26000, myclosureSwapEllipse, 1 )  
timer.performWithDelay( 28000, myclosureSwapEllipseSmall, 1 )  
  

Many thanks
[import]uid: 125741 topic_id: 36052 reply_id: 336052[/import]

To be honest, I think you’re going about this the wrong way.

Probably the best way is to create the physics shapes first and deactivate the shapes you don’t want. Not as composite bodies, but complete bodies.

The swap in function will still be a little complex, but certainly not as difficult as destroying and re-creating the actual physics bodies - certainly much more performant, due to the time it takes to create a physics body.

Also, be aware that if you are going to destroy and recreate the physics bodies, when you create one you will get collision events (if it’s colliding with another body, at least.) However, when you destroy the body prior to recreating it, you will NOT get a collision ended event. This means that if the body is in the middle of a collision and you recreate it, you’ll get an odd collision began but no preceding collision ended events.

I can’t say what will happen if you do the same with disabling/re-enabling physics bodies using the .isBodyActive property. [import]uid: 8271 topic_id: 36052 reply_id: 143231[/import]

Ooooo! I like that: A bend in in my line of thinking!
Thanks Horacebury.

(and I agree, the probability of collisions coinciding with destroy/re-create is a real concern.)

I assume a single physics body cannot have more than one shape.
I don’t think that’s what you mean.

I think you mean pre-building a stack of physics bodies.
At swap, a hidden one is passed x,y and xVel,yVel and un-hidden and activated.

BTW, your posts in the past have been most helpful, so,
a belated multi-thanks

Tim Waddy.
[import]uid: 125741 topic_id: 36052 reply_id: 143245[/import]

Yes, it’s a bit tricky, tbh. But pre-create the bodies and move them in to replace the one currently on screen. There’s no elegant way, as far as I’ve found.

The typical problem example is the case of bubbles which join together effectively get destroyed and a larger bubble replaces them. If you can solve that problem, you’ve got your solution, I think.

Let us all know what you find out! [import]uid: 8271 topic_id: 36052 reply_id: 143287[/import]

To be honest, I think you’re going about this the wrong way.

Probably the best way is to create the physics shapes first and deactivate the shapes you don’t want. Not as composite bodies, but complete bodies.

The swap in function will still be a little complex, but certainly not as difficult as destroying and re-creating the actual physics bodies - certainly much more performant, due to the time it takes to create a physics body.

Also, be aware that if you are going to destroy and recreate the physics bodies, when you create one you will get collision events (if it’s colliding with another body, at least.) However, when you destroy the body prior to recreating it, you will NOT get a collision ended event. This means that if the body is in the middle of a collision and you recreate it, you’ll get an odd collision began but no preceding collision ended events.

I can’t say what will happen if you do the same with disabling/re-enabling physics bodies using the .isBodyActive property. [import]uid: 8271 topic_id: 36052 reply_id: 143231[/import]

Ooooo! I like that: A bend in in my line of thinking!
Thanks Horacebury.

(and I agree, the probability of collisions coinciding with destroy/re-create is a real concern.)

I assume a single physics body cannot have more than one shape.
I don’t think that’s what you mean.

I think you mean pre-building a stack of physics bodies.
At swap, a hidden one is passed x,y and xVel,yVel and un-hidden and activated.

BTW, your posts in the past have been most helpful, so,
a belated multi-thanks

Tim Waddy.
[import]uid: 125741 topic_id: 36052 reply_id: 143245[/import]

Yes, it’s a bit tricky, tbh. But pre-create the bodies and move them in to replace the one currently on screen. There’s no elegant way, as far as I’ve found.

The typical problem example is the case of bubbles which join together effectively get destroyed and a larger bubble replaces them. If you can solve that problem, you’ve got your solution, I think.

Let us all know what you find out! [import]uid: 8271 topic_id: 36052 reply_id: 143287[/import]

To be honest, I think you’re going about this the wrong way.

Probably the best way is to create the physics shapes first and deactivate the shapes you don’t want. Not as composite bodies, but complete bodies.

The swap in function will still be a little complex, but certainly not as difficult as destroying and re-creating the actual physics bodies - certainly much more performant, due to the time it takes to create a physics body.

Also, be aware that if you are going to destroy and recreate the physics bodies, when you create one you will get collision events (if it’s colliding with another body, at least.) However, when you destroy the body prior to recreating it, you will NOT get a collision ended event. This means that if the body is in the middle of a collision and you recreate it, you’ll get an odd collision began but no preceding collision ended events.

I can’t say what will happen if you do the same with disabling/re-enabling physics bodies using the .isBodyActive property. [import]uid: 8271 topic_id: 36052 reply_id: 143231[/import]

Ooooo! I like that: A bend in in my line of thinking!
Thanks Horacebury.

(and I agree, the probability of collisions coinciding with destroy/re-create is a real concern.)

I assume a single physics body cannot have more than one shape.
I don’t think that’s what you mean.

I think you mean pre-building a stack of physics bodies.
At swap, a hidden one is passed x,y and xVel,yVel and un-hidden and activated.

BTW, your posts in the past have been most helpful, so,
a belated multi-thanks

Tim Waddy.
[import]uid: 125741 topic_id: 36052 reply_id: 143245[/import]

Yes, it’s a bit tricky, tbh. But pre-create the bodies and move them in to replace the one currently on screen. There’s no elegant way, as far as I’ve found.

The typical problem example is the case of bubbles which join together effectively get destroyed and a larger bubble replaces them. If you can solve that problem, you’ve got your solution, I think.

Let us all know what you find out! [import]uid: 8271 topic_id: 36052 reply_id: 143287[/import]

To be honest, I think you’re going about this the wrong way.

Probably the best way is to create the physics shapes first and deactivate the shapes you don’t want. Not as composite bodies, but complete bodies.

The swap in function will still be a little complex, but certainly not as difficult as destroying and re-creating the actual physics bodies - certainly much more performant, due to the time it takes to create a physics body.

Also, be aware that if you are going to destroy and recreate the physics bodies, when you create one you will get collision events (if it’s colliding with another body, at least.) However, when you destroy the body prior to recreating it, you will NOT get a collision ended event. This means that if the body is in the middle of a collision and you recreate it, you’ll get an odd collision began but no preceding collision ended events.

I can’t say what will happen if you do the same with disabling/re-enabling physics bodies using the .isBodyActive property. [import]uid: 8271 topic_id: 36052 reply_id: 143231[/import]

Ooooo! I like that: A bend in in my line of thinking!
Thanks Horacebury.

(and I agree, the probability of collisions coinciding with destroy/re-create is a real concern.)

I assume a single physics body cannot have more than one shape.
I don’t think that’s what you mean.

I think you mean pre-building a stack of physics bodies.
At swap, a hidden one is passed x,y and xVel,yVel and un-hidden and activated.

BTW, your posts in the past have been most helpful, so,
a belated multi-thanks

Tim Waddy.
[import]uid: 125741 topic_id: 36052 reply_id: 143245[/import]

Yes, it’s a bit tricky, tbh. But pre-create the bodies and move them in to replace the one currently on screen. There’s no elegant way, as far as I’ve found.

The typical problem example is the case of bubbles which join together effectively get destroyed and a larger bubble replaces them. If you can solve that problem, you’ve got your solution, I think.

Let us all know what you find out! [import]uid: 8271 topic_id: 36052 reply_id: 143287[/import]