Collision Platform looking for issue(s)

Hi, I tried a lot of stuff but nothing working, what is crazy that’s I bought a template where is include the “go through platform” and i’ve done exactly same stuff than him but my player still hit the left side and in the template not ! the template change all the anchor point…

What you mean by “platformHeight” ?

Have you already seen something like that ?

That’s mad I can’t find an issue it seems easy  <_<

Hi Julio,

I’ve done a little testing on my side. You may be encountering some issue with the fact that you’re using multi-element bodies with this approach (something happening with which body element it detects, and how it behaves). Could you just place distinct objects as your “end of platform sensors” and use a separate function to handle collisions with them, so you could change the sprite animation?

By “platformHeight” I just mean, for each platform, you set its height in advance. Then, you know that exact value when you handle the collision, and use it to detect when the player is above a certain Y point on it.

Brent

Hi brent,

Still not resolve, sorry to be long to resolve it  :huh:

I did all what you advice me, but still same problem, I try all the stuff it could be use for this issue, I can’t understand , I’ve not anymore multi-element, i’ve just one rectangle …

The thing is when my player hit the top left side the function is called , because I can see on the output the print (“X”) for the function, but the “event.contact.isEnabled = false” is not calling but the “print” yes …

I’m missing something, or something-else in my code make trouble !

I think I’m going to don’t use anymore “event.contact.isEnabled = false”, just use sensor for the platform.

An other idea ?

Hi Julio,

Can you post your current (updated) code with the collision listener function? And also, perhaps another screenshot with your new physics bodies setup?

Thanks,

Brent

Hi Brent,

I post the whole precollision and collision code : 

Platform Height =  70px

 local function PlayerPreCo(self,event) local Type = event.other.Type local KangaPhysicsY = self.y+1 local PlatY = event.other.y-35 -- LET PLAYER GO THROUGH if Type == "Bar" then if KangaPhysicsY \> PlatY+30 then event.contact.isEnabled = false ; self.isSensor = true ; self.setAsSensor = true; print("PRECO") end end end local function PlayerCollision(self,event) local class = event.other.class local Type = event.other.Type -- COLLISION PLATFORM -------------------------------------- -- PLATFORM HAVE ONE TYPE ("Bar") AND ONE CLASS ("Sol") ------------------------------- if Type == "Bar" then if ( event.phase == "began" ) then local KangaPhysicsY = self.y+1 local PlatY = event.other.y-35 if KangaPhysicsY \> PlatY+30 then event.contact.isEnabled = false ; self.isSensor = true ; self.setAsSensor = true; print("Boogie") end elseif (event.phase == "ended") then self.isSensor = false ; self.setAsSensor = false; end end if class == "Sol" then if ( event.phase == "began" ) then local KangaPhysicsY = KangaPhysics.y local BarY = event.other.y if Idle == false and ( KangaPhysicsY \< BarY - 7 ) and KangaPhysics.States \> 0 then audio.play(LandSnd) stateK:setAnimationByName(0, "WalkGround", true,0) timer.performWithDelay(30, StateManager) timer.performWithDelay(27, StateManagerII) elseif Idle == true then physics.pause()end elseif (event.phase == "ended") then end -- OTHER STUFF COLLISION ----------------------------------------------------- elseif class == "Trampo" then if ( event.phase == "began" ) then KangaPhysics:setLinearVelocity (0,-3000) audio.play(JumpSnd) stateK:setAnimationByName(0, "JumpDown", false,0) timer.performWithDelay(0, StateManagerII) elseif (event.phase == "ended") then end KangaPhysics.States = KangaPhysics.States + 1 elseif class == "Bois" then if ( event.phase == "began" ) then local KangaPhysicsY = KangaPhysics.y local BarY = event.other.y if ( KangaPhysicsY \< BarY+25 )and KangaPhysics.States \> 0 then KangaPhysics:setLinearVelocity (0,-1000) audio.play(LandSnd) stateK:setAnimationByName(0, "WalkGround", true,0) end elseif (event.phase == "ended") then end elseif class == "Next" and Next == false then if ( event.phase == "began" ) then Choice = Choice + 1 if Choice \> 4 then Choice = 1 end elseif (event.phase == "ended") then end timer.performWithDelay(100,Step) Next = true print("Next") end end

So that’s all what I use to make my player go through the platform but with this code my player hits sometimes the top left side while the function is called, at least the print(“PRECO”) which one I can see in the output, but the rest of the function is not called. Weird …

All my platform are display with a loop, I can publish it if you need

I post here just my physicsShape : 

local rad = (Sol.width\*0.5)+10; local height = (Sol.height\*0.5)- 30 local physicsShape = { -rad, -height, rad, -height, rad, Sol.height\*0.5, -rad, Sol.height\*0.5 } physics.addBody(Sol,"kinematic", {friction = 0, density=1, bounce = 0, shape=physicsShape})

and here the screenshot :

all my platform have differents width but the same height (70)

What Do you think ?

Thanks in advance

Hi Julio,

I think the issue is in your math calculations and conditional logic. It looks like you’re comparing:

  1. The center point of “Kanga”, +1 pixel

against

  1. The top of the platform (event.other.y-35) + 30 (PlatY+30)

That means, the center of Kanga… not the base (or “foot”) is being compared with some middle point in the platform. And then, you compare with the > operator, which means, below this platform center, and you disable the collision.

Let’s say Kanga is an object of 100 pixels high (with matching physics body). What you should do is compare the bottom part of this object (its “foot”) with the TOP of the platform, and if its foot is > than that, then you disable the collision:

[lua]

local function PlayerPreCo( self, event )

    local Type = event.other.Type

    local KangaPhysicsFoot = self.y + (self.height/2)

    local PlatTop = event.other.y - (event.other.height/2)

    – LET PLAYER GO THROUGH             

    if Type == “Bar” then

        if KangaPhysicsFoot > PlatTop  then

            event.contact.isEnabled = false ; self.isSensor = true ; self.setAsSensor = true; print(“PRECO”)

        end

    end

end

[/lua]

Hi brent,

The things is my kangaphysics.height = 2 so do “self.y+1”  it’s the same than that “self.y + (self.height/2)”, I did not tell you  sorry, and I need to add+30 to :

the PlatTop because I take off 30 in the Platform Shape

local rad = (Sol.width*0.5)+10; local height = (Sol.height*0.5)- 30

local physicsShape = { -rad, -height, rad, -height, rad, Sol.height*0.5, -rad, Sol.height*0.5 }

I try to make higher the kangaphysics.height like 100px but same bug

I know what you mean but I think it’s a bug because the condition "if KangaPhysicsFoot > PlatTop +30 " is checked and called when I get the bug where my player hit the left side, because I can see in the output the print(“PRECO”) displayed …

You know what I mean ?

I really don’t How to fix it because I’m doing I think exactly how it should be done …

Hi Julio,

At this point, can you simplify this down to the most basic case? Meaning:

  1. Take out the conditional “Type” check for the moment.

  2. Remove the other collision listener (“PlayerCollision”) from the player, so you can focus solely on “PlayerPreCo” for testing.

Basically, I’d like to get this project simplified, because I’m convinced there’s something going on in the logic, not the physics engine. I’m testing my project of pass-through platforms and it works fine, so I don’t think the engine is the issue here.

Thanks,

Brent

Hi Brent ,

I make a Test Project but same bug …

even if everything is simplified I got this bug, the output write the print in the precollision but don’t call the rest …

I give you the whole project stuff : 

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid") local \_x = display.contentCenterX local \_y = display.contentCenterY local Plat = {} local Platform local stage = display.currentStage local PlayerGround = display.newRect(0,0, 1100, 10) PlayerGround.x = \_x PlayerGround.y = 500 physics.addBody(PlayerGround, "static",{Friction=0.3, Bounce=0.1}) local Player = display.newRect (0,0,50,50) Player.x = \_x - 300 Player.y = 470 physics.addBody(Player, "dynamic", {Friction=0.3, Bounce=0.2}) Player.gravityScale = 15 Player.isFixedRotation = true function Player:preCollision( event ) -- EVEN IF I TAKE OUT THE CONDITIONAL CLASS THE BUG HAPPENED local class =event.other.class if class == "Transparent" then local PlayerBase = self.y + self.height/2 local MurTop = event.other.y - event.other.height/2 -- WHEN THE BUG HAPPENED THE PRINT IS CALLED BUT NOT THE REST if ( PlayerBase \> MurTop ) then event.contact.isEnabled = false --self.isSensor = true --self.setAsSensor = true print("through") end end end function Player:collision( event ) if ( event.phase == "began" ) then elseif ( event.phase == "ended" ) then --self.isSensor = false --self.setAsSensor = false end end local function doJump( event ) if event.phase == "began" then Player:setLinearVelocity(0 , -1200) elseif event.phase == "ended" then end end local function randomly () if Plat ~= {} then for x = #Plat, 1, -1 do display.remove( Plat[x] ) Plat[x] = nil end Plat = {} end for x = 1,3 do Platform = display.newRect(0,0,1150,25) Platform.class = "Transparent" physics.addBody(Platform, "kinematic",{Friction=0.3, Bounce=0.2}) Platform:setLinearVelocity(-500, 0) Plat[#Plat+1] = Platform end Plat[1].x = 1300 + 1500 Plat[1].y = 200 Plat[2].x = 1300 + 750 Plat[2].y = 300 Plat[3].x = 1300 Plat[3].y = 400 end timer.performWithDelay( 6500, randomly, 20 ) Player:addEventListener( "preCollision" ) Player:addEventListener( "collision" ) stage:addEventListener( "touch", doJump )

Hi Julio,

Now you’ve changed it from a “local” collision listener to the “global” style, so “self” is not known. Also, I’m a bit concerned that you’re using the same reference for all 20 platforms (“Platform”)… there is no need for this if you’re adding each platform to the table “Plat”. Just create a new local variable inside the creation function, create the new platform on that handle, add the object to the “Plat” table, and continue.

Take care,

Brent

I’ve changed to global function because in your event.contact example (PhysicsContact) you used global function with “self” to make your player go through …

So I changed to local function listener my precollision and create a new local variable for create the platforms but still same stuff, hit the left side … 

I have simplified the code : 

the whole code

local physics = require( "physics" ) physics.start() physics.setDrawMode( "hybrid") local \_x = display.contentCenterX local \_y = display.contentCenterY local stage = display.currentStage local PlayerGround = display.newRect(0,0, display.contentWidth, 50) PlayerGround.x = \_x PlayerGround.y = 1000 physics.addBody(PlayerGround, "static",{Friction=0.3, Bounce=0.1}) local Player = display.newRect (0,0,100,100) Player.x = \_x - 700 Player.y = 470 physics.addBody(Player, "dynamic", {Friction=0, Bounce=0}) Player.gravityScale = 15 Player.isFixedRotation = true local Platform = display.newRect(0,0,1150,50) Platform.x = -2400 Platform.y = 850 physics.addBody(Platform, "kinematic" , {friction = 0, density=1, bounce = 0}) Platform.class = "Transparent" Platform:setLinearVelocity (-500,0) local function PlayerpreCo ( self, event ) if event.other.class == "Transparent" then local PlayerBase = self.y + self.height/2 local MurTop = event.other.y - event.other.height/2 if ( PlayerBase \> MurTop ) then event.contact.isEnabled = false print("through") end end end local function doJump( event ) if event.phase == "began" then Player:setLinearVelocity(0 , -1500) elseif event.phase == "ended" then end end local function randomly () if Platform.x \< -2500 then Platform.x = 2500 end end Runtime:addEventListener("enterFrame", randomly) Player.preCollision = PlayerpreCo Player:addEventListener("preCollision",Player) stage:addEventListener( "touch", doJump )

Hi Julio,

I tested your code, and it appears to be working fine. The player, if “hit” by the platform, passes through it. But, if the player jumps, he lands on top of the platform perfectly. And, he can pass through from the bottom, landing on top when his “feet” touch back down. So I’m not sure what the issue is… this all looks fine to me. :slight_smile:

Brent

Hi brent , I couldn’t reply before,

I know it looks fine so I got a video to show you the bug with this code : 

https://drive.google.com/file/d/0B07DH0VwmfBYbjBwUWh6Q24waDg/edit?usp=sharing

It not happening everytime but when it happening it kills my logic game

Hi Julio,

From a potential “player” perspective, I think the second jump in the video should fail, and the character pushed back, because you haven’t jumped high enough to land on top of the platform. However, if you don’t want the player to be physically pushed back, next you must add another method to handle these cases. In that method, it should make the player into a sensor-type object so that he drops back down through the platform without being knocked backward… however (and this is very important), you must detect when he exits the platform (“ended” phase of a normal collision listener) and then make him into non-sensor-type object again.

I suggest you carefully inspect the demo project (from the tutorial) again, as it has this functionality built-in.

Brent

I have already done it before, and I got the same collision …

I downloaded the sample project Brent provided, and it works as I would expect it.

You should base your code off of that model, since it’s already a working base.

Yes I know it working fine, but I got a collision unexpected as you can see in the video I posted in the previous page, and I’m doing exactly the same code as the brent’s sample project ( with preco and collision ). I don’t know why I got a collision, i’m going to find an other way to fix it.

Anyway thanks brent and gremlin for your help

Hi,

Finally I have managed to fix this issue, but forgot to update the post, sorry for that…

Firstly, my mistake was about the physics body of my platform, it was “kinematic” and it seems to act strangly with this type of collision (collision happen, when it should not), so now I use “static” body

Secondly I add in my collision condition the velocity Y to check if this one is a positive value to let the layer land on top or not 

And finally I get back all my anchor point to 0.5 and I got it !

Thanks again to your help, the big mistake was about the physics body, I still don’t understand why with kinematic isn’t working, anyway I fix it !

See you  :wink:

Hi,

Finally I have managed to fix this issue, but forgot to update the post, sorry for that…

Firstly, my mistake was about the physics body of my platform, it was “kinematic” and it seems to act strangly with this type of collision (collision happen, when it should not), so now I use “static” body

Secondly I add in my collision condition the velocity Y to check if this one is a positive value to let the layer land on top or not 

And finally I get back all my anchor point to 0.5 and I got it !

Thanks again to your help, the big mistake was about the physics body, I still don’t understand why with kinematic isn’t working, anyway I fix it !

See you  :wink: