Passing Through Platforms One Way - Confusion

I have been trying to get that basic effect of passing through a platform underneath and then bouncing on top of it. I have been trying for about a day now, and still not there. I have found various different solutions online, but none of them have worked, including the one in the documentation (several people are complaining of it not working).

I have tried the following:

  • Use a preCollision and check for the y coordinates of the moving object, if it’s higher (making it below) then make the platform a sensor so he can pass through. If the moving object is above the object then isSensor is set to false, causing a collision. I have a listener for onCollision that makes my character jump.

This doesn’t work. My character never passes through the platform, whether he’s coming from above or below. The code for this is here: http://pastebin.com/VcidWAvW

I’ve also tried (found a thread on the forums of someone having the same issue):

  • Use a preCollision as before and detect placement of character. This time, the platform is always a sensor. I then have a ‘hard’ (isSensor=false) platform off screen that is the same size as the sensor platform. When the moving object/character is coming downwards I detect on a preCollision and move the hard platform in place so it hits that instead. If it comes from below then I move it off screen.

This worked the same as above, and wouldn’t pass through at all.

I then tried setting the event to a collision, instead of preCollision. This worked far better, but occassionally the character doesn’t pass through. The character would also get stuck against the side of the platform - this is rare but does happen (potentially a bug I can live with). The code for this is here: http://pastebin.com/fXJDvbNf (please note: I added a second listener ‘movePlatform’, I read on another forum post that you can’t directly manipulate objects on a collision event, so instead O set a flag and check for this flag on enterFrame).

Any help is appreciated. I know I’m not the only one struggling on what should be a simple concept, I have read quite a lot of forum posts on this, but no positive answers.

Thanks [import]uid: 61422 topic_id: 15399 reply_id: 315399[/import]

Hey there,

I attempted to have a look at this however the code you’ve posted isn’t plug and play - is that intentional? [import]uid: 52491 topic_id: 15399 reply_id: 56894[/import]

Kind of. I’m not asking for my code to be fixed or written for me, I just need a bullet-proof concept. I also don’t want to publish all my code online for obvious reasons.

Could you provide some pseudo-code for me? Do I need to use isSensor? Should I be doing the second method of moving ‘hard’ platforms about? Do I use preCollision, collision, postCollision, or a combination?

Thanks :slight_smile: [import]uid: 61422 topic_id: 15399 reply_id: 56899[/import]

try this
[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,9.8)

local jumpPlatform = display.newRect( 120, 250, 60, 10 )
physics.addBody( jumpPlatform, “static”, { friction=0.3 } )
jumpPlatform.isSensor = true

local ball = display.newCircle(150,350,10)
physics.addBody( ball, “dynamic”, { friction=0.3,density = .2,bounce = 0.5 } )

local function onFloorCollision( event )
if ( event.phase == “ended” ) then
jumpPlatform.isSensor = false
end
end

jumpPlatform:addEventListener( “collision”, onFloorCollision )

ball:applyLinearImpulse(0, -1, ball.x, ball.y) [/lua] [import]uid: 71210 topic_id: 15399 reply_id: 56905[/import]

here goes a better code

[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,9.8)

local jumpPlatform = display.newRect( 120, 250, 60, 5 )
physics.addBody( jumpPlatform, “static”, { friction=0.3 } )
jumpPlatform.isSensor = false

local jumpPlatformbottom = display.newRect( 120, 256, 60, 5 )
physics.addBody( jumpPlatformbottom, “static”, { friction=0.3 } )
jumpPlatformbottom.isSensor = true

local function onFloorCollision( event )
if event.phase == “ended” then
jumpPlatform.isSensor = false
end
end

local function onFloorBottomCollision( event )
jumpPlatform.isSensor = true
end
jumpPlatformbottom:addEventListener( “collision”, onFloorBottomCollision )
jumpPlatform:addEventListener( “collision”, onFloorCollision )

–ball coming from bottom
—[[
local ball = display.newCircle(150,350,10)
physics.addBody( ball, “dynamic”, { friction=0.3,density = .2,bounce = 0.5 } )
ball:applyLinearImpulse(0, -1, ball.x, ball.y)
–]]
–ball coming from top
–[[
local ball = display.newCircle(150,150,10)
physics.addBody( ball, “dynamic”, { friction=0.3,density = .2,bounce = 0.5 } )
ball:applyLinearImpulse(0, 1, ball.x, ball.y)
–]][/lua]
hope this helps… [import]uid: 71210 topic_id: 15399 reply_id: 56907[/import]

I was going to comment on your first code but just as I was about to post you put up the 2nd post which seemed to clear up what I was thinking. So basically you have a sensor right below the platform which will turn the platform momentarily into a sensor until the ball finishes its collision with it. Has anyone done something similar to this using this method?

I can see issues arise if the ball touches the sensor but not the platform. This will cause the platform to allow passing through from the top. Maybe making the sensor 1 pixel will help with this? [import]uid: 31262 topic_id: 15399 reply_id: 56913[/import]

Hi,

This is very helpful, nice to see a different way of doing things. From what I can gather you’re listening for a collision, if the object is below it then apply a force in the opposite direction if it was above.

I’ve tried this, but it doesn’t work as I’d have hoped. If the platform is a little bit above the object then it should be able to jump through it, fall back to it, land on it, and then jump. In this case it would hit the platform, and then jump at a set height as it passes through, which comes across quite oddly when playing.

http://www.youtube.com/watch?v=2UaHpndcVhw - see how the character goes through platforms and then drops back down onto it?

I feel it’s very close with the preCollisions, I’m just missing it somewhere. [import]uid: 61422 topic_id: 15399 reply_id: 56914[/import]

Thanks for the suggestion. I’ve tried that, I get the same issues still. Although, I’m sure it would have fixed the potential problem that you mentioned.

Thanks [import]uid: 61422 topic_id: 15399 reply_id: 56915[/import]

this will help to attain the same result with a single body.

[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,9.8)

local prevy , y = 0 ,0
local jumpPlatform = display.newRect( 120, 250, 60, 5 )
physics.addBody( jumpPlatform, “static”, { friction=0.3,isSensor = true} )

local ball = display.newCircle(150,350,10)
physics.addBody( ball, “dynamic”, { friction=0.3,density = .2} )

local function onFloorCollision( event )
if y > prevy then
ball:setLinearVelocity( 0, 0 )
ball:applyLinearImpulse(0, -1, ball.x, ball.y)

end
end

jumpPlatform:addEventListener( “collision”, onFloorCollision )
ball:applyLinearImpulse(0, -1, ball.x, ball.y)

local function ballDirection()
prevy = y
y = ball.y
end

timer.performWithDelay(500,ballDirection)[/lua] [import]uid: 71210 topic_id: 15399 reply_id: 56921[/import]

I am always amazed at renvis@technowand quick solutions.

I was struggling with this FOREVER, in fact it was one of the first problems I tackled when I first started programming EVER back in June 2011 (with Lua/Corona SDK of course).
Techno’s (yea I just shortened your name haha) works really well. It’s doodle jump type code, which is really cool - it has so many uses.
Ok now on to my analysis. I’m way new to programming (I just started to understand functions lol).

  
--Cut out just the parts I wanted to know about  
  
local prevy , y = 0 ,0  
local function onFloorCollision( event )  
 if y \> prevy then  
 ball:setLinearVelocity( 0, 0 )  
 ball:applyLinearImpulse(0, -1, ball.x, ball.y)   
   
 end   
end  
  

For this :

local prevy , y = 0 ,0  

–A variable called prevy , which Y = 0, 0
– Y is 0,0 are these X and Y coordinates (a little confused here)

Then if Y is greater than 0 the function onFloorCollision runs?
For the function itself:

I noticed that changing the -1 to a 1 results in…nothing. Is -1 a loop or something? (sorry, if its a total noob question then forgive me, I am noob lol).

I really examined this closely, and I want to make sure I understand this concept. Seems like I think I know what it’s doing, but sometimes what I think and what is are 2 different things :slight_smile:

ng
-ng
[import]uid: 61600 topic_id: 15399 reply_id: 56959[/import]

local prevy , y = 0 ,0
means I have assigned 2 variables y and prevy and assigned value 0 to both

its same as
local prevy = 0
local y = 0

see the example
[lua]local a , b = 1,2

print(“a=”…a)
print(“b=”…b)[/lua]
so in that code we will constantly monitor the direction of the ball using the y position. so y is copied to prevy and y is assigned with y value of ball on each trigger of the timer. and in collision we compare y and prevy to find the direction. ie if y is > prevy its going down and else its going up. so we will apply a force to the ball if its coming down.

and for applyLinearImpulse
the parameters are xForce and yForce and the position where to apply the force.

see the example below
[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,0)

local ball3 = display.newCircle(100,300,10)
physics.addBody( ball3, “dynamic”, { friction=0.3,density = .2} )

local ball1 = display.newCircle(150,300,10)
physics.addBody( ball1, “dynamic”, { friction=0.3,density = .2} )

local ball2 = display.newCircle(200,300,10)
physics.addBody( ball2, “dynamic”, { friction=0.3,density = .2} )

local ball4 = display.newCircle(300,300,10)
physics.addBody( ball4, “dynamic”, { friction=0.3,density = .2} )
local function applyImpulse()
–impulse in x direction to the left
ball3:applyLinearImpulse(-1, 0, ball3.x, ball3.y)
–impulse in x direction to the right
ball4:applyLinearImpulse(1, 0, ball4.x, ball4.y)
–impulse in y direction to bottom
ball1:applyLinearImpulse(0, 1, ball1.x, ball1.y)
–impulse in y direction to top
ball2:applyLinearImpulse(0, -1, ball2.x, ball2.y)

end

timer.performWithDelay(1500, applyImpulse ,-1)[/lua] [import]uid: 71210 topic_id: 15399 reply_id: 57006[/import]

actually there is a better way of doing this by identifying the direction of the ball by looking at its velocity
see the sample below
[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,9.8)

local prevy , y = 0 ,0
local jumpPlatform = display.newRect( 120, 250, 60, 5 )
physics.addBody( jumpPlatform, “static”, { friction=0.3,isSensor = true} )

local ball = display.newCircle(150,350,10)
physics.addBody( ball, “dynamic”, { friction=0.2,density = .2} )

local function onFloorCollision( event )
vx, vy = ball:getLinearVelocity()
if vy > 0 then
ball:setLinearVelocity( 0, 0 )
ball:applyLinearImpulse(0, -1, ball.x, ball.y)
end
end

jumpPlatform:addEventListener( “collision”, onFloorCollision )
ball:applyLinearImpulse(0, -1, ball.x, ball.y) [/lua] [import]uid: 71210 topic_id: 15399 reply_id: 57007[/import]

Ok. Your explanation was very well documented.
I feel silly now about

Local prevy , y = 0, 0

For some reason I was thinking y = (x position), (y position)
For the 0, 0 …now I know it was just short cut to cut down on total lines of code :wink:

I find that cool that you can do that. I’ll remember that.

One day I’ll be cool enough to write clean functional code, right now my stuff works just seem like I’m making up stuff as I go along haha.

By the way very cool on velocity of the ball and identifying the direction. Another very cool way.

Ng

[import]uid: 61600 topic_id: 15399 reply_id: 57038[/import]

Works fantastic, and with much less code. Thanks [import]uid: 61422 topic_id: 15399 reply_id: 57068[/import]