Collision Platform looking for issue(s)

Hi, everybody

I’m using the pre-Collision to get my Player go through the platform like this

local function PhysicsPreCo(self,event) local Type = event.other.Type local PlayerY = self.y local PlatY = event.other.y if Type == "Platform" then if PlayerY -8 \> PlatY then event.contact.isEnabled = false ; print("H") end end end 

So until here everything is working my player go through the platform properly, but sometimes when I jump before the platform too early my player hits the Platform’s left side rather to go through.

 

I thought to use the content widht and content height to identify the left side Platform and tell to the physics to go through when it hits it but I did not success to figure it out.

 

Any help will be appreciate thanks a lot :slight_smile:

There is a good tutorial on the event.contact property and an example project with one-sided platform logic.

Thanks Panc, I’ve followed this tutoriel to make my player go through platform, but I think I know where is my problem :

I put the Platform’s anchorY to 0 until here that’s working but when I try to put the Player’s anchorY to 1 nothing happening, the anchorY stay to 0.5.  I can’t understand.

My player is a rectangle make with corona:  70:weight / 5:height

Someone know why I can’t change this anchorpoint ?

thanks 

Hi @Julio DeVega,

Generally speaking, you should use and position physics objects around their center point, especially when dealing with collisions. If you set the anchor point afterward, the display object (image part) will shift, but the physics body will remain center-based. We may provide for some kind of pre-set of anchors with proper alignment in a future release, but for now, you should handle bodies around their center point.

Best regards,

Brent

thanks Brent, at least that help me to understand anchor point , but I still can’t resolve my problem, I get mad lol, this is the major bug in my game , I can’t find a nice issue …

Because I can’t exactly define the height and the weight of my physics object, so to tell to my player to become "event.contact.isEnabled = false " and go throught the platform, I need to do like :

if PlayerY  \> PlatY-83.5 then event.contact.isEnabled = false 

But the number(-83.5) is not a perfect number( because I can’t calculate the perfect number of my physics objects), so sometime the “event.contact.isEnabled = false” is not calling and my player hits the platform’s side, My question is How can I handle that properly with the perfect number and maybe some different code than it or maybe I missed somethings

For information I’m making an endless runner game so all the platforms and objects are moving alone from the right to the left going faster and faster

I don’t know if I’ve been clear but I hope, because I really need to find that issue to go ahead

Thanks a lot for all the reply

Hi Julio,

How are you generating the physics bodies? Are they rectangles that are auto-calculated based on the size of the display object? If so, you should be able to use the .height of the object, and then calculate where the top edge of the platform is. Can you post some code that shows one of your platforms being configured with a physics body?

Thanks,

Brent

Thanks Brent to help me,

I’m generating my physics body with “physics editor” so nothing is auto-calculate, I’m making the stuff by myself with rectangle, because I need to make multi-element body for my platforms to tell my player to go down at the end and change the animation :

local Platform local shapesPlatform     = {"Platform","Pass","Statue",} for x = 1, #PlatformLevel do             local ObjectNum = PlatformLevel[x] Platform = display.newImageRect("Images/Element-" .. PlatformImages[ObjectNum] .. ".png",sizesWObject[ObjectNum],sizesHObject[ObjectNum])            Platform.ObjectNum = ObjectNum Platform.x = -5000 Platform.y = PlatY[ObjectNum] physics.addBody( Platform,  "kinematic", physicsData:get(shapesPlatform[ObjectNum]) )

that’s a shortcut of my loop to display multiple Platform with physics editor

 Are they rectangles that are auto-calculated based on the size of the display object?

You mean to auto-calculate the physics of my platforms like that ? 

local rad = (platform.width\*0.5); local height = (platform.height\*0.5)-8 local physicsShape = { -rad, -height, rad, -height, rad, platform.height\*0.5, -rad, platform.height\*0.5 } physics.addBody( platform,  "kinematic", { friction=0, bounce=0, shape=physicsShape} ); end

Hi Julio,

Can you post a basic screenshot (clip) of one of these platforms, with “hybrid” physics mode enabled, so I can see what the overall shape looks like from the engine’s perspective?

Thanks,

Brent

Hi Brent,

Here is my platform with hybrid :

Platform begin :

Platform middle :

Platform end :

Here is my shape :

   {             shape = {   -738.5, -84.5  ,  757.5, -84.5  ,  733.5, -43.5  ,  -738.5, 100.5  }                     }                     ,                     {             shape = {   733.5, -43.5  ,  757.5, -84.5  ,  769.5, 20.5  }                     }

Hi Julio,

Overall, it looks like this platform could be a simple rectangle. Is there a specific reason why you need that angle and little pointed piece at the right side?

Brent

Hi brent,

 Yes , because I need at the end of my platform to change the animation to get my player go down properly. so when the player touch this pointed piece at the right the animation is changing.

But for now I’m doing like that to get the physics of my platform :

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

and to get my player go through I go like that : 

  local function PhysicsPreCo(self,event)        local Type = event.other.Type                local PhysicsY = self.y                local PlatY = event.other.y           if Type == "Plat" then if PhysicsY - 30  \> PlatY - (event.other.height)\*0.5 then event.contact.isEnabled = false ; print("H")  end end end

But I still get the same bug even having a simple rectangle as physicsShape, my player hit the left side …

Hi Julio,

Can you include a basic “platformHeight” along with each platform (which you set in advance), then read that property (and use it for the pre-collision) when necessary?

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