Physics pause() call displacing objects

here is the code that replicates problem

http://pastebin.com/LwaDd8uu

in this code, 3 crates are stacked.
initially you see each crate is stacked correctly. once crates are removed, physics is paused and added new crates after starting physics crates are not stacked properly. they get displaced.

sequence is
physics start -> stack crates -> remove crates -> pause physics-> start physics -> stack crates (just move x-position by 10 pixels compared to previous crates position) -> crates get displaced

if I do the same operation and use stop physics instead of pause physics crates stacked properly.

problem is physics.stop() function causing game to crash often, game got low ratings because of this crash.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
local physics = require("physics")
physics.setDrawMode("hybrid")
physics.start(true)
physics.setGravity(0,9.8)
 
display.setStatusBar( display.HiddenStatusBar )
 
local bkg = display.newImage( "bkg_cor.png" )
 
local grass = display.newImage("grass.png")
grass.x = 160; grass.y = 430
 
local grass2 = display.newImage("grass2.png") -- non-physical decorative overlay
grass2.x = 160; grass2.y = 440
 
physics.addBody( grass, "static", { friction=0.5, bounce=0.3 } )
 
 
local crates = {}
local stopit = false --make it true to stop instead of pause, you wont see problem
local displace = 0
 
--local dropCrates = timer.performWithDelay( 500, newCrate, 100 )
function startagain()
    physics.start(true)
    if stopit then
        local grass = display.newImage("grass.png")
        grass.x = 160; grass.y = 430
        physics.addBody( grass, "static", { friction=0.5, bounce=0.3 } )
    end
    if displace == 0 then
        displace = 10    --change this to > 30(since crate dimension is 30), won;t see the problem
    else
        displace = 0
    end
 
    SetCretes()
end
 
 
 
function CreatePhysicsProblem()
   for i=1,#crates do
       crates[i]:removeSelf()
       crates[i] = nil
   end
   crates = nil
   crates= {}
   if stopit then
    physics.stop()
   else
    physics.pause()
   end
   timer.performWithDelay( 1000, startagain )
 
end
 
function SetCretes()
    local j = display.newImageRect("crate.png",30,30);
    crates[#crates+1] = j
    j.x = 60+displace
    j.y = 405--335
    physics.addBody( j, { density=3, friction=.500, bounce=0} )
 
    local j = display.newImageRect("crate.png",30,30);
    crates[#crates+1] = j
    j.x = 60+displace
    j.y = 368
    physics.addBody( j, { density=3, friction=.500, bounce=0} )
 
    local j = display.newImageRect("crate.png",30,30);
    crates[#crates+1] = j
    j.x = 60+displace
    j.y = 330--402
    physics.addBody( j, { density=3, friction=.500, bounce=0} )
 
    timer.performWithDelay( 2000, CreatePhysicsProblem)
end
 
SetCretes()
 
 

I'm also having this problem, and can confirm that this is an urgent bug that needs to be fixed. Can this be moved up in the priority queue?

Here is a possible work around. It makes use of the physics.setTimeStep() function. When you pause the physics engine it seems like it doesn't remove objects unless another time-step is executed. here is the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
-----------------------------------------------------------------------------------------
--
-- main.lua
--
-----------------------------------------------------------------------------------------
 
-- Your code here
local physics = require("physics")
physics.setDrawMode("hybrid")
physics.start()
physics.setGravity(0,9.8)
 
display.setStatusBar( display.HiddenStatusBar )
 
local bkg = display.newImage( "bkg_cor.png" )
 
local grass = display.newImage("grass.png")
grass.x = 160; grass.y = 450
 
local grass2 = display.newImage("grass2.png") -- non-physical decorative overlay
grass2.x = 160; grass2.y = 440
 
physics.addBody( grass, "static", { friction=0.5, bounce=0.3 } )
 
 
local crates = {}
local stopit = false --make it true to stop instead of pause, you wont see problem
local displace = 0
 
--local dropCrates = timer.performWithDelay( 500, newCrate, 100 )
function startagain()
    physics.setTimeStep(0)
        --physics.start()
    if stopit then
        local grass = display.newImage("grass.png")
        grass.x = 160; grass.y = 450
        physics.addBody( grass, "static", { friction=0.5, bounce=0.3 } )
    end
    if displace == 0 then
        displace = 0    --change this to > 30(since crate dimension is 30), won;t see the problem
                physics.setTimeStep(0)
    else
        displace = 0
    end
 
    SetCretes()
end
 
 
 
function CreatePhysicsProblem()
   for i=1,#crates do
       crates[i]:removeSelf()
       crates[i] = nil
   end
   crates = nil
   crates= {}
   if stopit then
    physics.stop()
   else
        --physics.pause()
    physics.setTimeStep(0.0000000000000001) --this is like pause
   end
   timer.performWithDelay( 1000, startagain )
 
end
 
function SetCretes()
    local j = display.newImageRect("crate.png",30,30);
    crates[#crates+1] = j
    j.x = 60+displace
    j.y = 415--335
    physics.addBody( j, { density=3, friction=.500, bounce=0} )
 
    local j = display.newImageRect("crate.png",30,30);
    crates[#crates+1] = j
    j.x = 60+displace
    j.y = 384
    physics.addBody( j, { density=3, friction=.500, bounce=0} )
 
    local j = display.newImageRect("crate.png",30,30);
    crates[#crates+1] = j
    j.x = 60+displace
    j.y = 353--402
    physics.addBody( j, { density=3, friction=.500, bounce=0} )
 
    timer.performWithDelay( 2000, CreatePhysicsProblem)
end
 
SetCretes()

Thanks M.Y. for suggestion. I'll surely try this solution.

We have received this bug report and offered a workaround until this is resolved.

On line 37 in original post change;

setCretes()

to;

timer.performWithDelay(1, setCretes, 1)

Peach :)

@M.Y. and Peach,
thanks for your suggestions.
found a work around, I just delayed pause by 500ms after cleaning all the objects from physics. this worked fine.

I hope Ansca resolves this bug soon

views:3115 update:2012/2/13 9:11:28
corona forums © 2003-2011