Why won't this block fall down?

I'm having a problem where blocks won't fall down holes, even though the size should be just right.

I've made a simple example to show you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local smallblock1 = display.newImageRect( "block_stone.png", 32, 32 )
smallblock1:setReferencePoint( display.TopLeftReferencePoint )
smallblock1.x = 0
smallblock1.y = 448
physics.addBody( smallblock1, "static", { density=1, friction=0.3, bounce=0.2 } )
 
--BIG BLOCK
local bigBlock = display.newImageRect( "block_4square.png", 64, 64 )
bigBlock:setReferencePoint( display.TopLeftReferencePoint )
bigBlock.x = 32
bigBlock.y = 384
physics.addBody( bigBlock, { density=1, friction=0.3, bounce=0.2 } )
bigBlock.isFixedRotation = true
 
local smallblock2 = display.newImageRect( "block_stone.png", 32, 32 )
smallblock2:setReferencePoint( display.TopLeftReferencePoint )
smallblock2.x = 96
smallblock2.y = 448
physics.addBody( smallblock2, "static", { density=1, friction=0.3, bounce=0.2 } )

Move the small blocks further apart, if it falls then you know its because they're placed incorrectly. If not try this when you make the new big block.

physics.addBody( bigBlock,  "dynamic", { density=1, friction=0.3, bounce=0.2 } )

... i'm wondering if you removed the friction if they'd be able to slide down. friction is "sticking power" i believe. namely, consider with friction you have blocks of sandpaper, rather than blocks of ice.

@kennw: No, changing the friction doesn't make any difference.

Moving the smaller blocks further apart would of course let the big block fall through. The problem is that I'm placing a lot more blocks, and they're all based on a 32px grid. Moving blocks around by 1 pixel here and there would be a lot of work, and shouldn't really be needed.

If I measure the sizes on the blocks using the normal draw mode they should fit perfectly. However, when using the debug draw mode I can see that the blocks have gotten 1px higher and 1px wider.

have you tried placing the big block higher so it will start moving before it gets to the small blocks

Or perhaps you could offset the positioning in a easy way since you know the offset.

1
2
3
4
local offset = 1
 
local myBlock = whatever
myBlock.x = 200 - offset -- Or plus offset depending on position

everybody seem to try to find a workaround, but this is apparently is a bug. There is an invisible border around display objects, which makes it bigger then its real size.

Yes, I agree with culutas.

None of the workarounds are really that great. The problem is that the calculated physical size is larger than it really should be. This might not affect most games, but if your game needs pixel perfection then it's a problem.

Until this is resolved I suggest the following using a shape parameter to reduce the size of the physics body by one pixel all the way around.

For a top-left referenced box try:

1
2
3
4
5
6
7
8
9
10
11
12
13
myBox = display.newRect(x,y,w,h)
 
topLeftX = myBox.x
topLeftY = myBox.y
topRightX = myBox.width + myBox.x
topRightY = topLeftY
bottomRightX = topRightX
bottomRightY = myBox.height + myBox.y
bottomLeftX = topLeftX
bottomLeftY = bottomRightY
 
myShape = {topLeftX + 1,topLeftY + 1, topRightX - 1,topRightY + 1,
 bottomRightX -1,bottomRightY - 1, bottomLeftX + 1,bottomLeftY - 1}

That makes a lot of sense. I'll try it out. Thank you!

It occurs to me now that the shape property uses points based on a center reference point. So the above solution will require modification to accommodate that. Still, the idea is sound. Please let us know if this solves the problem (for now) and exactly what you did.

And, IF it works, you're welcome :)

views:1618 update:2011/10/4 17:12:07
corona forums © 2003-2011