Physics: How to create slippery ice?

Hi,

For my very first game I want to create a character that slips over the floor. I’m experimenting but I cannot get the right effect. what would be the right approach? What combination of physics functions should I use in my left/right touch events?

I have a main character and a floor both with friction values and a
Desired effects:

User presses the left or right button:
Character accelerates (slips as on Ice) until it’s moving on max speed.

User releases the left or right button:
Character de-accelerates (slips as on Ice) until it fully stops.

User shifts from left to right or right to left directly:
Character de-accelerates (slips as on Ice) until it fully stops and then accelerates (slips as
on Ice) in the opposite direction until it’s moving on max speed again.

An example would be appreciated.

Thanks.

[import]uid: 106768 topic_id: 36034 reply_id: 336034[/import]

It would be helpful if you gave an example of your implementation as well as an explanation of why it isn’t achieving the right effect.

[import]uid: 147305 topic_id: 36034 reply_id: 143192[/import]

Like Budershank said, it would be helpful if you posted some code.

From the top of my head, I’d say start with a character with a bit of linearDamping (to slow it down gradually) and a floor with low friction.

Caleb [import]uid: 147322 topic_id: 36034 reply_id: 143309[/import]

Hi Guys,

Thanks for your response!
In my initial code I didn’t use linear damping.

I have now more or less the desired effect but not completely. I would like to know if this is the correct way or is there a better way to create ’ ice’.

I still have the problem that the player accelerates immediately instead slowly (as you would on ice) from standstill.

[code]
– Function to move the player
local function movePlayer()
if player.moveDir == “left” then
if player.velocity < 30 then
player:setLinearVelocity( - playerSpeed, 0 )
end
elseif player.moveDir == “right” then
if player.velocity > - 30 then
player:setLinearVelocity( playerSpeed, 0 )
end
end
end

–left button
local left = display.newRoundedRect(5, 0, 150, 40, 12)
left.id = “left”
left:setFillColor(255, 255, 255)
left:setStrokeColor(140, 140, 140)
left.strokeWidth = 5
left:setReferencePoint(display.TopLeftReferencePoint)
left.y = display.contentHeight - left.height - 5
left.alpha = 0.5

–right button
local right = display.newRoundedRect(0, 0, 150, 40, 12)
right.id = “right”
right:setFillColor(255, 255, 255)
right:setStrokeColor(140, 140, 140)
right.strokeWidth = 5
right:setReferencePoint(display.TopLeftReferencePoint)
right.y = display.contentHeight - left.height - 5
right.x = display.contentCenterX
right.alpha = 0.5

– touch function left button
function left:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end
– add eventlisteners to left button
left:addEventListener( “touch”, left )

– touch function right button
function right:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
print(“addEventListener”)
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end

– add eventlisteners to right button
right:addEventListener( “touch”, right )

– add displaylayers (groups) to main displaygroup
group:insert(backgroundLayer)

– listener for linear velocity
local function checkVelocity()
player.velocity = player:getLinearVelocity()
end
Runtime:addEventListener( “enterFrame”, checkVelocity )

end
[/code] [import]uid: 106768 topic_id: 36034 reply_id: 143726[/import]

It would be helpful if you gave an example of your implementation as well as an explanation of why it isn’t achieving the right effect.

[import]uid: 147305 topic_id: 36034 reply_id: 143192[/import]

Like Budershank said, it would be helpful if you posted some code.

From the top of my head, I’d say start with a character with a bit of linearDamping (to slow it down gradually) and a floor with low friction.

Caleb [import]uid: 147322 topic_id: 36034 reply_id: 143309[/import]

Hi Guys,

Thanks for your response!
In my initial code I didn’t use linear damping.

I have now more or less the desired effect but not completely. I would like to know if this is the correct way or is there a better way to create ’ ice’.

I still have the problem that the player accelerates immediately instead slowly (as you would on ice) from standstill.

[code]
– Function to move the player
local function movePlayer()
if player.moveDir == “left” then
if player.velocity < 30 then
player:setLinearVelocity( - playerSpeed, 0 )
end
elseif player.moveDir == “right” then
if player.velocity > - 30 then
player:setLinearVelocity( playerSpeed, 0 )
end
end
end

–left button
local left = display.newRoundedRect(5, 0, 150, 40, 12)
left.id = “left”
left:setFillColor(255, 255, 255)
left:setStrokeColor(140, 140, 140)
left.strokeWidth = 5
left:setReferencePoint(display.TopLeftReferencePoint)
left.y = display.contentHeight - left.height - 5
left.alpha = 0.5

–right button
local right = display.newRoundedRect(0, 0, 150, 40, 12)
right.id = “right”
right:setFillColor(255, 255, 255)
right:setStrokeColor(140, 140, 140)
right.strokeWidth = 5
right:setReferencePoint(display.TopLeftReferencePoint)
right.y = display.contentHeight - left.height - 5
right.x = display.contentCenterX
right.alpha = 0.5

– touch function left button
function left:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end
– add eventlisteners to left button
left:addEventListener( “touch”, left )

– touch function right button
function right:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
print(“addEventListener”)
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end

– add eventlisteners to right button
right:addEventListener( “touch”, right )

– add displaylayers (groups) to main displaygroup
group:insert(backgroundLayer)

– listener for linear velocity
local function checkVelocity()
player.velocity = player:getLinearVelocity()
end
Runtime:addEventListener( “enterFrame”, checkVelocity )

end
[/code] [import]uid: 106768 topic_id: 36034 reply_id: 143726[/import]

It would be helpful if you gave an example of your implementation as well as an explanation of why it isn’t achieving the right effect.

[import]uid: 147305 topic_id: 36034 reply_id: 143192[/import]

Like Budershank said, it would be helpful if you posted some code.

From the top of my head, I’d say start with a character with a bit of linearDamping (to slow it down gradually) and a floor with low friction.

Caleb [import]uid: 147322 topic_id: 36034 reply_id: 143309[/import]

Hi Guys,

Thanks for your response!
In my initial code I didn’t use linear damping.

I have now more or less the desired effect but not completely. I would like to know if this is the correct way or is there a better way to create ’ ice’.

I still have the problem that the player accelerates immediately instead slowly (as you would on ice) from standstill.

[code]
– Function to move the player
local function movePlayer()
if player.moveDir == “left” then
if player.velocity < 30 then
player:setLinearVelocity( - playerSpeed, 0 )
end
elseif player.moveDir == “right” then
if player.velocity > - 30 then
player:setLinearVelocity( playerSpeed, 0 )
end
end
end

–left button
local left = display.newRoundedRect(5, 0, 150, 40, 12)
left.id = “left”
left:setFillColor(255, 255, 255)
left:setStrokeColor(140, 140, 140)
left.strokeWidth = 5
left:setReferencePoint(display.TopLeftReferencePoint)
left.y = display.contentHeight - left.height - 5
left.alpha = 0.5

–right button
local right = display.newRoundedRect(0, 0, 150, 40, 12)
right.id = “right”
right:setFillColor(255, 255, 255)
right:setStrokeColor(140, 140, 140)
right.strokeWidth = 5
right:setReferencePoint(display.TopLeftReferencePoint)
right.y = display.contentHeight - left.height - 5
right.x = display.contentCenterX
right.alpha = 0.5

– touch function left button
function left:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end
– add eventlisteners to left button
left:addEventListener( “touch”, left )

– touch function right button
function right:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
print(“addEventListener”)
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end

– add eventlisteners to right button
right:addEventListener( “touch”, right )

– add displaylayers (groups) to main displaygroup
group:insert(backgroundLayer)

– listener for linear velocity
local function checkVelocity()
player.velocity = player:getLinearVelocity()
end
Runtime:addEventListener( “enterFrame”, checkVelocity )

end
[/code] [import]uid: 106768 topic_id: 36034 reply_id: 143726[/import]

It would be helpful if you gave an example of your implementation as well as an explanation of why it isn’t achieving the right effect.

[import]uid: 147305 topic_id: 36034 reply_id: 143192[/import]

Like Budershank said, it would be helpful if you posted some code.

From the top of my head, I’d say start with a character with a bit of linearDamping (to slow it down gradually) and a floor with low friction.

Caleb [import]uid: 147322 topic_id: 36034 reply_id: 143309[/import]

Hi Guys,

Thanks for your response!
In my initial code I didn’t use linear damping.

I have now more or less the desired effect but not completely. I would like to know if this is the correct way or is there a better way to create ’ ice’.

I still have the problem that the player accelerates immediately instead slowly (as you would on ice) from standstill.

[code]
– Function to move the player
local function movePlayer()
if player.moveDir == “left” then
if player.velocity < 30 then
player:setLinearVelocity( - playerSpeed, 0 )
end
elseif player.moveDir == “right” then
if player.velocity > - 30 then
player:setLinearVelocity( playerSpeed, 0 )
end
end
end

–left button
local left = display.newRoundedRect(5, 0, 150, 40, 12)
left.id = “left”
left:setFillColor(255, 255, 255)
left:setStrokeColor(140, 140, 140)
left.strokeWidth = 5
left:setReferencePoint(display.TopLeftReferencePoint)
left.y = display.contentHeight - left.height - 5
left.alpha = 0.5

–right button
local right = display.newRoundedRect(0, 0, 150, 40, 12)
right.id = “right”
right:setFillColor(255, 255, 255)
right:setStrokeColor(140, 140, 140)
right.strokeWidth = 5
right:setReferencePoint(display.TopLeftReferencePoint)
right.y = display.contentHeight - left.height - 5
right.x = display.contentCenterX
right.alpha = 0.5

– touch function left button
function left:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end
– add eventlisteners to left button
left:addEventListener( “touch”, left )

– touch function right button
function right:touch( event )
if event.phase == “began” then
player.linearDamping = 1
player.moveDir = self.id
print(“addEventListener”)
Runtime:addEventListener( “enterFrame”, movePlayer )
elseif event.phase == “ended” or event.phase == “cancelled” then
player.linearDamping = 3
Runtime:removeEventListener( “enterFrame”, movePlayer )
end
return true
end

– add eventlisteners to right button
right:addEventListener( “touch”, right )

– add displaylayers (groups) to main displaygroup
group:insert(backgroundLayer)

– listener for linear velocity
local function checkVelocity()
player.velocity = player:getLinearVelocity()
end
Runtime:addEventListener( “enterFrame”, checkVelocity )

end
[/code] [import]uid: 106768 topic_id: 36034 reply_id: 143726[/import]