Physics / Extra Space

Hello,

In my continuing struggle to learn both MTE and Corona SDK, I am trying to mimic the old style Super Mario Brothers.

I’ve got movement where I am happy with it and now I am ready to tackle breakable blocks.

The goal is simple:

When the player collides with a block that is tagged in Tiled as “breakable”, the block will bounce up a little (on Y axis only) and return back to it’s resting position.

Right now, the easiest way to do it that I can think of is to have each breakable block be a kinematic body. When the collision occurs between player and breakable block, setLinearVelocity will be called moving it up and then a timer with a small delay will fire reversing the linear velocity.

An invisible wall (newRect) will be created at Runtime under each block and set as static. This will return the breakable blocks to their original positions.

However, I am encountering a weird issue.

Box2D shows the physics bodies for the invisible wall, breakable blocks, and my character all correctly.

If I remove the invisible walls (comment them out), jumping and movement work just fine.

If I keep the walls in place, it only lets me jump about half the distance I’d expect.

So, to debug, I set the invisible walls as dynamic. Much to my surprise, the wall directly on top of the player came to rest well above my character (see screenshot) even though the bodies are correct.

Any ideas?

local myBreakableBlocks = {} local onBreakableProperty = function(event) myBreakableBlocks[#myBreakableBlocks + 1] = event.target:makeSprite() myBreakableBlocks[#myBreakableBlocks].bodyType = "kinematic" myBreakableBlocks[#myBreakableBlocks].name = "breakable" mte.updateTile({locX = event.target.locX, locY = event.target.locY, tile = 0, layer = event.target.layer}) local bottom = display.newRect(myBreakableBlocks[#myBreakableBlocks].levelPosX - (myBreakableBlocks[#myBreakableBlocks].width/2), myBreakableBlocks[#myBreakableBlocks].levelPosY + (myBreakableBlocks[#myBreakableBlocks].height / 2), myBreakableBlocks[#myBreakableBlocks].width, 5) bottom.isVisible = false mte.physics.addBody(bottom, "dynamic") end mte.addPropertyListener("breakable", onBreakableProperty)

Corona’s Physics hybrid debug view doesn’t always reflect reality. A few things to watch out for is how you create new sprites. For example, you’re creating a rect named bottom, but you aren’t adding it to the map or to a layer group object in the map. The x and y positions of the stage do not match the x and y positions of the map or its layers in most situations. 

If the goal is to make a box appear to bounce up a little and then return to its starting position, you could try using a pair of moveSpriteTo() calls, one to move it up, the other to move it back down. The first call would use the “outQuad” or “outExpo” easing function. It’s onComplete parameter would run a function which calls the second moveSpriteTo(). The second moveSpriteTo() would use “inQuad” or “inExpo”. When hit, the block would appear to bounce up and back down in a single smooth trajectory.

Just an update for the public’s sake…

I don’t quite understand exactly what Dyson is getting at RE the physics solution but I did resolve it with his second solution.

I set the blocks as “static” so I could detect collision then use moveSpriteTo to move them.

To handle collectable objects, I also set them to static. During the collision detection, I check if any collectable objects are right above the blocks and if there are, I move those too.

Corona’s Physics hybrid debug view doesn’t always reflect reality. A few things to watch out for is how you create new sprites. For example, you’re creating a rect named bottom, but you aren’t adding it to the map or to a layer group object in the map. The x and y positions of the stage do not match the x and y positions of the map or its layers in most situations. 

If the goal is to make a box appear to bounce up a little and then return to its starting position, you could try using a pair of moveSpriteTo() calls, one to move it up, the other to move it back down. The first call would use the “outQuad” or “outExpo” easing function. It’s onComplete parameter would run a function which calls the second moveSpriteTo(). The second moveSpriteTo() would use “inQuad” or “inExpo”. When hit, the block would appear to bounce up and back down in a single smooth trajectory.

Just an update for the public’s sake…

I don’t quite understand exactly what Dyson is getting at RE the physics solution but I did resolve it with his second solution.

I set the blocks as “static” so I could detect collision then use moveSpriteTo to move them.

To handle collectable objects, I also set them to static. During the collision detection, I check if any collectable objects are right above the blocks and if there are, I move those too.