The problem with resizing physical bodies

Hello! I have a problem when I use physics.setScale(). All objects are shifted.
Working example -

local cx     = display.contentCenterX
local cy     = display.contentCenterY
local fullw  = display.actualContentWidth
local fullh  = display.actualContentHeight

local ZoomDefault = 30
local ScaleDefault = 1

local ZoomChange = 1

local physics = require "physics"
physics.start()
physics.setGravity( 0, 0 )
physics.setDrawMode("hybrid")


local ALL =  display.newGroup()

local AllMoveZome = display.newGroup()
ALL:insert(AllMoveZome)

local function MoveScreen( event )
	local phase = event.phase
	if ( "began" == phase ) then
		display.currentStage:setFocus( Gcontent )
    AllMoveZome.touchOffsetX = event.x - AllMoveZome.x
  	AllMoveZome.touchOffsetY = event.y - AllMoveZome.y
	elseif ( "moved" == phase ) then
    AllMoveZome.x = event.x - AllMoveZome.touchOffsetX
    AllMoveZome.y = event.y - AllMoveZome.touchOffsetY
	elseif ( "ended" == phase or "cancelled" == phase ) then
		display.currentStage:setFocus( nil )
  end
	return true
end

local function ZoomScreen()
  transition.to( AllMoveZome, { xScale = ZoomChange, yScale = ZoomChange, time = time } )
  physics.setScale( ZoomDefault*ZoomChange )
end


local back_MoveZoom = display.newRect( AllMoveZome, cx, cy, fullw, fullh )
back_MoveZoom:setFillColor(.3,.3,.3)
-- ----------------
local obj1_dark_MoveZoom = display.newRect( AllMoveZome, cx, cy, 100, 100 )
obj1_dark_MoveZoom:setFillColor(.6, .6, 0)

local obj2_dark_MoveZoom = display.newRect( AllMoveZome, cx+120, cy, 100, 200 )
obj2_dark_MoveZoom:setFillColor(.6, .6, 0)
-- ----------------
local obj1_MoveZoom = display.newRect( AllMoveZome, cx, cy, 100, 100 )
obj1_MoveZoom:setFillColor(1, 1, 0)
physics.addBody( obj1_MoveZoom, "static" )

local obj2_MoveZoom = display.newRect( AllMoveZome, cx+120, cy, 100, 200 )
obj2_MoveZoom:setFillColor(1, 1, 0)
physics.addBody( obj2_MoveZoom, "static" )


local toZoomX1 = display.newRect( ALL, 150, 150, 100, 100 )
local zoomTo1 = function()
  ZoomChange=1
  ZoomScreen()
end

local toZoomX1i2 = display.newRect( ALL, 300, 150, 100, 100 )
local zoomTo1i2 = function()
  ZoomChange=1.2
  ZoomScreen()
end

toZoomX1:addEventListener("tap", zoomTo1)

toZoomX1i2:addEventListener("tap", zoomTo1i2)

back_MoveZoom:addEventListener("touch", MoveScreen)

Dark yellow rectangles do not use the physical body. Bright yellow directly on top of dark yellow, but have a physical body.

The first square zoom x1, the second x1.2.

Not physical objects increase normally, but those with a physical body - shift.

You may need to take a closer look at docs when using physics. Wrong uses may break your game. Here - https://docs.coronalabs.com/api/library/physics/setScale.html

Sets the internal pixels-per-meter ratio that is used in converting between on-screen Corona coordinates and simulated physics coordinates. This should be done only once, before any physical objects are instantiated.
Changing this value has no visual consequences — it simply affects the accuracy of the physical model.

1 Like

Hmm, have any ideas how to implement this? I can store a list of objects with a physical body in an array and, when zoom, delete the old body and create a new enlarged one.

Yes, that would be the way. Delete the physics body and create a new one. If you encounter an error in this process you may need to add a delay before removing the body:

timer.performWithDelay(1, removeAddBody, 1)

While you are waiting for the delay to remove the physics body, you might also want to set it to
isSensor = true
so it stops interacting with the environment