Please HELP: need to make an object respond to only one force

Please HELP! I do high speed action platformer, something like Contra, but even more rapid. I have a problem with impulses: some objects must did not get impetus from the other objects. Here is a sample code. Then the player gets a boost from the platform, but it should not.

-- start physics  
local physics = require( "physics" )  
physics.start()  
physics.setGravity( 0, 10 )  
physics.setDrawMode( "hybrid" ) -- hybrid, debug  
   
-- creates a moving platform  
local platform = display.newRect( 0, 0, 200,150 )  
platform:setFillColor( 155, 155, 255 )  
physics.addBody( platform, "kinematic", { friction=0.1, bounce=0.1, density=12 } )  
platform.x, platform.y = 200, 700  
   
 -- create "player"  
local player = display.newRect( 0, 0, 60, 60 )  
player:setFillColor( 245, 215, 245 )  
physics.addBody( player, "dynamic", { friction=0.1, bounce=0.1, density=12 } )  
player.x, player.y = 200, 650  
  
-- move the platform  
local j=0   
local function movePlatform()  
j=j+1  
 if j==30 then   
 -- stop the platform, but player is still moving....  
 platform:setLinearVelocity(0,0)   
 platform.x, platform.y = 200, 700  
elseif j==60 then  
platform:setLinearVelocity(0,-200)  
j=0  
 end  
 end  
 Runtime:addEventListener( "enterFrame", movePlatform )  

P.S.:
I could not simplify the game. Platforms are many and they complex. In addition here is a lot of monsters. Not all the forces that act upon the world must act on the player.
[import]uid: 26141 topic_id: 29898 reply_id: 329898[/import]

UP! Forgot to say: I can not use joints, because the player can move as he wants and when he wants at any time, and types of platforms is too much. Those who have any ideas? [import]uid: 26141 topic_id: 29898 reply_id: 120011[/import]

So the problem is that the player’s physics body is colliding and bouncing off the platform physics bodies? Did I understand you correctly?

For a quick fix, have you tried making the player and/or the platform’s physics bodies have a bounce attribute = 0? [import]uid: 144339 topic_id: 29898 reply_id: 120012[/import]

If u check the Sample, u see: bounce does not affect this movement. After post-collision player has received Impulse (impulse from platform). Thats why he continue moving. I have to to make the player ignore the impulses from platforms. [import]uid: 26141 topic_id: 29898 reply_id: 120023[/import]

Ok; there might be a simple way to do this. You could manually set the player’s velocity back to what it was before the collision with a platform - this should hopefully stop it from altering its velocity when it hits the platform.

You need to have a listener on the player for pre and post-collision events - and you’ll need to give your objects “names”, so you can test which object the player is colliding with.

In the pre-collision event, you should save the player’s current velocity as it is before the collision.

Then, in the post collision function, if the player is found to be colliding with a platform; you can revert its velocity back to its previous velocity that you saved earlier.

For example, you’ll want, say,
[lua]player.name = “player”
platform.name = “platform”

–Now, set up the functions for pre and post collision events
local playerPrevVelX, playerPrevVelY = 0, 0

local function onPlayerPreCollision(event)
playerPrevVelX, playerPrevVelY = player:getLinearVelocity()
end

local function onPlayerPostCollision(event)
if (event.other.name == “platform”) then
player:setLinearVelocity(playerPrevVelX, playerPrevVelY)
end
end

–Now, set up the player to listen for the events

player.preCollision = onPlayerPreCollision
player.postCollision = onPlayerPostCollision
player:addEventListener( “preCollision”, player )
player:addEventListener( “postCollision”, player )[/lua]

Something like that could be what you want. Hope that helps you justfunk! [import]uid: 144339 topic_id: 29898 reply_id: 120030[/import]

lionelbuffman, Thank you for your answers :slight_smile: You are the one who tries to help me on this forum :slight_smile:
I checked your code. If you start this:

-- start physics  
local physics = require( "physics" )  
physics.start()  
physics.setGravity( 0, 10 )  
physics.setDrawMode( "hybrid" ) -- normal, hybrid, debug  
   
-- creates a moving platform  
 platform = display.newRect( 0, 0, 200,150 )  
platform:setFillColor( 155, 155, 255 )  
physics.addBody( platform, "kinematic", { friction=0.1, bounce=0.1, density=12 } )  
platform.x, platform.y = 200, 700  
   
 -- create "player"  
 player = display.newRect( 0, 0, 60, 60 )  
player:setFillColor( 245, 215, 245 )  
physics.addBody( player, "dynamic", { friction=0.1, bounce=0.1, density=12 } )  
player.x, player.y = 200, 650  
  
-- move the platform  
local j=0   
local function movePlatform()  
j=j+1  
 if j==30 then   
 -- stop the platform, but player is moving....  
 platform:setLinearVelocity(0,0)   
 platform.x, platform.y = 200, 700  
elseif j==60 then  
platform:setLinearVelocity(0,-200)  
j=0  
 end  
 end  
 Runtime:addEventListener( "enterFrame", movePlatform )  
   
player.name = "player"  
platform.name = "platform"  
   
--Now, set up the functions for pre and post collision events  
local playerPrevVelX, playerPrevVelY = 0, 0  
   
local function onPlayerPreCollision(self,event)  
 playerPrevVelX, playerPrevVelY = player:getLinearVelocity()  
end  
   
local function onPlayerPostCollision(self,event)  
 if (event.other.name == "platform") then  
 player:setLinearVelocity(playerPrevVelX, playerPrevVelY)  
 end  
end  
   
--Now, set up the player to listen for the events  
   
player.preCollision = onPlayerPreCollision  
player.postCollision = onPlayerPostCollision  
player:addEventListener( "preCollision", player )  
player:addEventListener( "postCollision", player )  
   

You can see that: it is impossible to equate the rate of property before the collision, because the speed is not constant, it varies over time. The only thing that I see thee for a solution to this problem: after the collision, subtract the clear momentum gained from the collision of the player
player:setLinearVelocity(playerXcollisionVelosity - platformXcollisionVelosity, playerXcollisionVelosity - platformXcollisionVelosity)

but… Points of forces attachment are different… it’s BLOW my mind [import]uid: 26141 topic_id: 29898 reply_id: 120034[/import]

Ok, I think I understand your problem now. You don’t want the speed the player gains from moving on the platform to continue to “push it upwards” once the platform stops pushing it, right?

What if on the postCollision function, you simply set player:setLinearVelocity(0,0)?
Of course, that wouldn’t help you if say, the player is jumping off the platform as he’d immediately stop moving…

You might have to set a bunch of bools - say
[lua]local function onPlayerPostCollision(self,event)
if (event.other.name == “platform” and not playerJumping) then
player:setLinearVelocity(0, 0)
end
end[/lua]
That way, you could control manually when the player should stop moving after being on moving platforms and when the player should keep moving.

Is that what you’re trying to do here?
[import]uid: 144339 topic_id: 29898 reply_id: 120037[/import]

Thank you! Exactly as you wrote, I realized now in the game. But the problem initially is to move players on the platform. When I set player Linear Velocity to 0 - 0, physics becomes not realistic. Because of the limitations of the Corona, it is impossible to make a game with great potential. Unfortunately, Corona is only suitable for simple games … [import]uid: 26141 topic_id: 29898 reply_id: 120099[/import]

Yeah man, that’s the problem I outlined in my previous post.

Because you want to move the player on the platforms; but you don’t want the platform to be affecting the player’s velocity after the platform drops - you’d need to have several cases to detect:
-What direction the platform was moving in
-What the player’s velocity was before they left the platform

If you had a scenario like the code you posted above - let’s say you were walking straight off the platform - you’d want the player’s Y velocity to set back to zero (so it didn’t fly upwards from the platform’s push) - but you’d want the player’s X velocity to stay the same from walking. In that case you’d want something like this:

[lua]local function onPlayerPostCollision(self,event)
if (event.other.name == “platform”) then
if (event.other.moveDirection == “up”) then
–The platform was moving up - when the player leaves the platform; we need to adjust the Y velocity
local curX, curY = player:getLinearVelocity()
if (player.jumping == false) then
player:setLinearVelocity(curX, 0) --only reset the Y speed
else
player:setLinearVelocity(curX, player.jumpSpeed)
end

elseif (event.other.moveDirection == “horizontal”) then
–Platform was moving horizontally; maybe we want to reset the player’s X velocity
local curX, curY = player:getLinearVelocity()
player:setLinearVelocity(0, curY) --only reset the X speed
end
end
end[/lua]

You get my idea here? You’re gonna have to manually detect what kind of platform the player was on - what the player was doing and then adjust the velocities as required.
It’s not that Corona can’t make complicated games; it’s just when your game is complicated - you’re gonna have to do some more complicated programming! [import]uid: 144339 topic_id: 29898 reply_id: 120223[/import]

UP! Forgot to say: I can not use joints, because the player can move as he wants and when he wants at any time, and types of platforms is too much. Those who have any ideas? [import]uid: 26141 topic_id: 29898 reply_id: 120011[/import]

So the problem is that the player’s physics body is colliding and bouncing off the platform physics bodies? Did I understand you correctly?

For a quick fix, have you tried making the player and/or the platform’s physics bodies have a bounce attribute = 0? [import]uid: 144339 topic_id: 29898 reply_id: 120012[/import]

If u check the Sample, u see: bounce does not affect this movement. After post-collision player has received Impulse (impulse from platform). Thats why he continue moving. I have to to make the player ignore the impulses from platforms. [import]uid: 26141 topic_id: 29898 reply_id: 120023[/import]

Ok; there might be a simple way to do this. You could manually set the player’s velocity back to what it was before the collision with a platform - this should hopefully stop it from altering its velocity when it hits the platform.

You need to have a listener on the player for pre and post-collision events - and you’ll need to give your objects “names”, so you can test which object the player is colliding with.

In the pre-collision event, you should save the player’s current velocity as it is before the collision.

Then, in the post collision function, if the player is found to be colliding with a platform; you can revert its velocity back to its previous velocity that you saved earlier.

For example, you’ll want, say,
[lua]player.name = “player”
platform.name = “platform”

–Now, set up the functions for pre and post collision events
local playerPrevVelX, playerPrevVelY = 0, 0

local function onPlayerPreCollision(event)
playerPrevVelX, playerPrevVelY = player:getLinearVelocity()
end

local function onPlayerPostCollision(event)
if (event.other.name == “platform”) then
player:setLinearVelocity(playerPrevVelX, playerPrevVelY)
end
end

–Now, set up the player to listen for the events

player.preCollision = onPlayerPreCollision
player.postCollision = onPlayerPostCollision
player:addEventListener( “preCollision”, player )
player:addEventListener( “postCollision”, player )[/lua]

Something like that could be what you want. Hope that helps you justfunk! [import]uid: 144339 topic_id: 29898 reply_id: 120030[/import]

lionelbuffman, Thank you for your answers :slight_smile: You are the one who tries to help me on this forum :slight_smile:
I checked your code. If you start this:

-- start physics  
local physics = require( "physics" )  
physics.start()  
physics.setGravity( 0, 10 )  
physics.setDrawMode( "hybrid" ) -- normal, hybrid, debug  
   
-- creates a moving platform  
 platform = display.newRect( 0, 0, 200,150 )  
platform:setFillColor( 155, 155, 255 )  
physics.addBody( platform, "kinematic", { friction=0.1, bounce=0.1, density=12 } )  
platform.x, platform.y = 200, 700  
   
 -- create "player"  
 player = display.newRect( 0, 0, 60, 60 )  
player:setFillColor( 245, 215, 245 )  
physics.addBody( player, "dynamic", { friction=0.1, bounce=0.1, density=12 } )  
player.x, player.y = 200, 650  
  
-- move the platform  
local j=0   
local function movePlatform()  
j=j+1  
 if j==30 then   
 -- stop the platform, but player is moving....  
 platform:setLinearVelocity(0,0)   
 platform.x, platform.y = 200, 700  
elseif j==60 then  
platform:setLinearVelocity(0,-200)  
j=0  
 end  
 end  
 Runtime:addEventListener( "enterFrame", movePlatform )  
   
player.name = "player"  
platform.name = "platform"  
   
--Now, set up the functions for pre and post collision events  
local playerPrevVelX, playerPrevVelY = 0, 0  
   
local function onPlayerPreCollision(self,event)  
 playerPrevVelX, playerPrevVelY = player:getLinearVelocity()  
end  
   
local function onPlayerPostCollision(self,event)  
 if (event.other.name == "platform") then  
 player:setLinearVelocity(playerPrevVelX, playerPrevVelY)  
 end  
end  
   
--Now, set up the player to listen for the events  
   
player.preCollision = onPlayerPreCollision  
player.postCollision = onPlayerPostCollision  
player:addEventListener( "preCollision", player )  
player:addEventListener( "postCollision", player )  
   

You can see that: it is impossible to equate the rate of property before the collision, because the speed is not constant, it varies over time. The only thing that I see thee for a solution to this problem: after the collision, subtract the clear momentum gained from the collision of the player
player:setLinearVelocity(playerXcollisionVelosity - platformXcollisionVelosity, playerXcollisionVelosity - platformXcollisionVelosity)

but… Points of forces attachment are different… it’s BLOW my mind [import]uid: 26141 topic_id: 29898 reply_id: 120034[/import]

Ok, I think I understand your problem now. You don’t want the speed the player gains from moving on the platform to continue to “push it upwards” once the platform stops pushing it, right?

What if on the postCollision function, you simply set player:setLinearVelocity(0,0)?
Of course, that wouldn’t help you if say, the player is jumping off the platform as he’d immediately stop moving…

You might have to set a bunch of bools - say
[lua]local function onPlayerPostCollision(self,event)
if (event.other.name == “platform” and not playerJumping) then
player:setLinearVelocity(0, 0)
end
end[/lua]
That way, you could control manually when the player should stop moving after being on moving platforms and when the player should keep moving.

Is that what you’re trying to do here?
[import]uid: 144339 topic_id: 29898 reply_id: 120037[/import]

Thank you! Exactly as you wrote, I realized now in the game. But the problem initially is to move players on the platform. When I set player Linear Velocity to 0 - 0, physics becomes not realistic. Because of the limitations of the Corona, it is impossible to make a game with great potential. Unfortunately, Corona is only suitable for simple games … [import]uid: 26141 topic_id: 29898 reply_id: 120099[/import]

Yeah man, that’s the problem I outlined in my previous post.

Because you want to move the player on the platforms; but you don’t want the platform to be affecting the player’s velocity after the platform drops - you’d need to have several cases to detect:
-What direction the platform was moving in
-What the player’s velocity was before they left the platform

If you had a scenario like the code you posted above - let’s say you were walking straight off the platform - you’d want the player’s Y velocity to set back to zero (so it didn’t fly upwards from the platform’s push) - but you’d want the player’s X velocity to stay the same from walking. In that case you’d want something like this:

[lua]local function onPlayerPostCollision(self,event)
if (event.other.name == “platform”) then
if (event.other.moveDirection == “up”) then
–The platform was moving up - when the player leaves the platform; we need to adjust the Y velocity
local curX, curY = player:getLinearVelocity()
if (player.jumping == false) then
player:setLinearVelocity(curX, 0) --only reset the Y speed
else
player:setLinearVelocity(curX, player.jumpSpeed)
end

elseif (event.other.moveDirection == “horizontal”) then
–Platform was moving horizontally; maybe we want to reset the player’s X velocity
local curX, curY = player:getLinearVelocity()
player:setLinearVelocity(0, curY) --only reset the X speed
end
end
end[/lua]

You get my idea here? You’re gonna have to manually detect what kind of platform the player was on - what the player was doing and then adjust the velocities as required.
It’s not that Corona can’t make complicated games; it’s just when your game is complicated - you’re gonna have to do some more complicated programming! [import]uid: 144339 topic_id: 29898 reply_id: 120223[/import]