Collision Platform looking for issue(s)

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

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

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

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 

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 @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 &nbsp;\> PlatY-83.5 then event.contact.isEnabled = false&nbsp;

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 &nbsp; &nbsp; = {"Platform","Pass","Statue",} for x = 1, #PlatformLevel do &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;local ObjectNum = PlatformLevel[x] Platform = display.newImageRect("Images/Element-" .. PlatformImages[ObjectNum] .. ".png",sizesWObject[ObjectNum],sizesHObject[ObjectNum]) &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Platform.ObjectNum = ObjectNum Platform.x = -5000 Platform.y = PlatY[ObjectNum] physics.addBody( Platform, &nbsp;"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, &nbsp;"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 :

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

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, &nbsp;density=1, bounce = 0, shape=physicsShape})

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

&nbsp; local function PhysicsPreCo(self,event)&nbsp; &nbsp; &nbsp; &nbsp; local Type = event.other.Type &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;local PhysicsY = self.y &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;local PlatY = event.other.y &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Type == "Plat" then if PhysicsY - 30 &nbsp;\> PlatY - (event.other.height)\*0.5 then event.contact.isEnabled = false ; print("H") &nbsp;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?