Collecting Items in Game + Problem

Hi Ansca Community

I am in the making of a platform game, where you need to collect a certain number of coins to complete the level. I have tried to make a table to accomplish this but it doesn’t seem to work along with my other game objects. My character is constantly bouncing (Each time the character collides with the platform/floor, force is applied, see the code below) and when the character collides with the coin/coins, the coin isn’t removed but instead force is applied to the character and it starts to jump crazy around the screen. Is there a way solve this problem? :smiley: (I hope you know what I mean)

Thank you in advance :slight_smile: I really appreciate your help :slight_smile:

[code]

–Coin Code:

local coin = {}
coin[1] = display.newImage(“coin.png”)
coin[1].x = 100
coin[1].y = 460
coin[1].myName = “coin”
coin[2] = display.newImage(“coin.png”)
coin[2].x = 180
coin[2].y = 460
coin[2].myName = “coin”
coin[3] = display.newImage(“coin.png”)
coin[3].x = 250
coin[3].y = 460
coin[3].myName = “coin”

coin[4] = display.newImage(“coin.png”)
coin[4].x = 280
coin[4].y = 460
coin[4].myName = “coin”

physics.addBody(coin[1],“static”,{isSensor = true})
physics.addBody(coin[2],“static”,{isSensor = true})
physics.addBody(coin[3],“static”,{isSensor = true})
physics.addBody(coin[4],“static”,{isSensor = true})

local function onCollision( event )
if ( event.phase == “began” ) then

if event.object1.myName == “player” and event.object2.myName == “coin” then
event.object2.alpha = 0.001

end

elseif ( event.phase == “ended” ) then

if event.object1.myName == “player” and event.object2.myName == “coin” then
event.object2:removeSelf()
event.object2 = nil

end

end
end

Runtime:addEventListener( “collision”, onCollision )

–Character bounce code:

local player = display.newImageRect(“player.png”, 50, 50 )
player.x = 50
player.y = 30
physics.addBody(player, “dynamic”, {density=0.2, friction=0.1, bounce=0.1, radius=30})

function player:collision (event)
if event.phase == “ended” then
player:applyForce(0,-90, player.x, player.y)

end

end
player:addEventListener(“collision”, player)

[import]uid: 122802 topic_id: 22117 reply_id: 322117[/import]

error post [import]uid: 10389 topic_id: 22117 reply_id: 87942[/import]

Out of interest why isn’t the coin being removed? [import]uid: 52491 topic_id: 22117 reply_id: 88025[/import]

Hi
I really don’t know why the coin isn’t being removed when it collide with the player/character, that was what I have hoped I could have get help with :).
I will try to describe the problem in another way: It is intended that the character / heroen / the player constantly bounces, I have accomplished this by applying force when the character hits the platform (see the last code above). The problem is when the character/player/hero collides with the coin, force is applied and the coin isn’t being removed(may be because the coins is “static”. I don’t want force to be applied to the character when it is colliding with the coin, it should only be removed (but somehow the coin is not being removed? :frowning: )

I hope you understand what I mean and I really appreciate the help :slight_smile:
[import]uid: 122802 topic_id: 22117 reply_id: 88045[/import]

First you need to add code to only apply force when a coin is not involved in the collision:

[lua]function player:collision (event)
if event.phase == “ended” and event.other.myName ~= “coin” then
player:applyForce(0,-90, player.x, player.y)

end[/lua]

Secondly, is it always going to be the case that player will be object1 and coin is object2 in all collisions between them? You might need to check for instances where it’s the other way round? [import]uid: 93133 topic_id: 22117 reply_id: 88086[/import]

Sorry, I misunderstood the problem; can you make the coins static sensors instead of static? [import]uid: 52491 topic_id: 22117 reply_id: 88106[/import]

Hi Nick & Peach, first I wanna thank you for taking your time to help me, I really appriciate it :slight_smile:

Thank you for the code Nick, it fixed a part of the problem and it helped me to track the code that is causing the problem. It is the physics.addBody - ( “dynamic”,{density=0.2, friction=0.1, bounce=0.1, radius=30}) code for the character that is causing the problem. When I remove the code where I declare the settings for the physic body, the coin is removed correctly, but my character starts to jump very high. When I use the code, my character jumps constantly, like it is supposed to be, but when my character collides with the coin, the coin is not being removed. What I want to accomplish is, I want my character to jump constantly up & down and when it collides with a coin, it must be removed. Is this possible? :smiley: - //Se460

This is my plug & play code"

[code] local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 9.5 )

local Platform = display.newRect( 0, 0, 187, 33)
Platform.x = 116
Platform.y = 231
Platform:setFillColor(255, 255, 255)
physics.addBody( Platform, “static”, { density=1, friction=0, bounce=0 } )

–Character
local player = display.newRect(0,0, 20, 20 )
player.x = 50
player.y = 100
player.myName = “player”

–==This is causing the problem==–

physics.addBody(player, “dynamic”,{density=0.2, friction=0.1, bounce=0.1, radius=30})

– Bounce Function
function player:collision (event)
if event.phase == “ended” and event.other.myName ~= “coin” then
player:applyForce(0,-90, player.x, player.y)

end

end
player:addEventListener(“collision”, player)

local coin = {}
coin[1] = display.newCircle(5, 5, 5)
coin[1]:setFillColor(255,255,255)
coin[1].x = 60
coin[1].y = 201
coin[1].myName = “coin”

physics.addBody(coin[1],“static”,{isSensor = true})

function onCollision( event )
if ( event.phase == “began” ) then

if event.object1.myName == “player” and event.object2.myName == “coin” then
event.object2.alpha = 0.001

end

elseif ( event.phase == “ended” ) then

if event.object1.myName == “player” and event.object2.myName == “coin” then
event.object2:removeSelf()
event.object2 = nil

end

end
end

Runtime:addEventListener( “collision”, onCollision )

[import]uid: 122802 topic_id: 22117 reply_id: 88154[/import]

Try this and let me know results please;

[lua]display.setStatusBar (display.HiddenStatusBar)

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 9.5 )

local Platform = display.newRect( 0, 0, 187, 33)
Platform.x = 116
Platform.y = 231
Platform:setFillColor(255, 255, 255)
physics.addBody( Platform, “static”, { density=1, friction=0, bounce=0 } )

–Character
local player = display.newRect(0,0, 20, 20 )
player.x = 50
player.y = 100
player.myName = “player”

–==This is causing the problem==–

physics.addBody(player, “dynamic”,{density=0.2, friction=0.1, bounce=0.1, radius=30})

– Bounce Function
function player:collision (event)
if event.phase == “ended” and event.other.myName ~= “coin” then
player:applyForce(0,-90, player.x, player.y)

end

end
player:addEventListener(“collision”, player)

local coin = {}
coin[1] = display.newCircle(5, 5, 5)
coin[1]:setFillColor(255,255,255)
coin[1].x = 60
coin[1].y = 201
coin[1].myName = “coin”

physics.addBody(coin[1],“static”,{isSensor = true})

function onCollision( event )
if ( event.phase == “began” ) then
if event.object1.myName == “coin” and event.object2.myName == “player” then

event.object1.alpha = 0.001

end

elseif ( event.phase == “ended” ) then

if event.object1.myName == “coin” and event.object2.myName == “player” then
event.object1:removeSelf()
event.object1 = nil

end

end
end

Runtime:addEventListener( “collision”, onCollision )[/lua]

Peach :slight_smile: [import]uid: 52491 topic_id: 22117 reply_id: 88271[/import]

Hi Peach,

It works, thank you very much for your help, I really appreciate it. :slight_smile:

[import]uid: 122802 topic_id: 22117 reply_id: 88832[/import]

Not a problem, good luck with your project :slight_smile: [import]uid: 52491 topic_id: 22117 reply_id: 88981[/import]

Instead of opening a new topic, I will ask the question here, when it is related to the code above. I hope someone can help me. :slight_smile:

As I explained above my character is constantly jumping (force is applied, when colliding with the platforms) and controlled with the accelerometers. The character needs to collect coins, but when the character collides with the coin, the character stops jumping and starts to slide along the platform. As well as, the character starts to stick to the walls when it hits. I have read “Solutions to Common Physics Challenges” by Jonathan Beebe, but the solutions dosen’t seem to work for me. Any suggestions how I can fix this?

This is my code:

[lua]
local Platform = display.newRect( 0, 0, 187, 33)
Platform.x = 116
Platform.y = 231
Platform:setFillColor(255, 255, 255)
physics.addBody( Platform, “static”, { density=1, friction=0, bounce=0 } )

– create wall objects
topWall = display.newRect( 0, 0, display.contentWidth, 1)
topWall.alpha = 0
topWall.myName = “topWall”
leftWall = display.newRect( 0, 0, 1, display.contentHeight )
leftWall.alpha = 0
leftWall.myName = “leftWall”
rightWall = display.newRect( display.contentWidth - 1, 0, 1, display.contentHeight )
rightWall.myName = “rightWall”
rightWall.alpha = 0

– make them physics bodies
physics.addBody(topWall, “static”, {density = 1.0, friction = 1, bounce = 1, isSensor = false})
physics.addBody(leftWall, “static”, {density = 1.0, friction = 1, bounce = 1, isSensor = false})
physics.addBody(rightWall, “static”, {density = 1.0, friction = 1, bounce = 1, isSensor = false})

–Character
local player = display.newRect(0,0, 20, 20 )
player.x = 50
player.y = 100
player.myName = “player”
player.isFixedRotation = true
player.iAwake = true
player.isBullet = true
Level1Group:insert(player)

physics.addBody(player, “dynamic”,{density=0.2, friction=0.1, bounce=0.1, radius=30})

– Bounce Function
function player:collision (event)
if event.phase == “ended” and event.other.myName ~= “coin” and event.other.myName ~= “leftWall” and event.other.myName ~= “rightWall” and event.other.myName ~= “topWall” then

player:applyForce(0,-40, player.x, player.y)

end

end
player:addEventListener(“collision”, player)

local coin = {}
coin[1] = display.newCircle(5, 5, 5)
coin[1]:setFillColor(255,255,255)
coin[1].x = 60
coin[1].y = 201
coin[1].myName = “coin”

physics.addBody(coin[1],“static”,{isSensor = true})

function onCollision( event )
if ( event.phase == “began” ) then
if event.object1.myName == “coin” and event.object2.myName == “player” then

event.object1.alpha = 0.001

end

elseif ( event.phase == “ended” ) then

if event.object1.myName == “coin” and event.object2.myName == “player” then
event.object1:removeSelf()
event.object1 = nil

end

end
end

Runtime:addEventListener( “collision”, onCollision )[/lua]

[import]uid: 122802 topic_id: 22117 reply_id: 91127[/import]

A quick run through of this and it appears that the body is still there for the coin. Try adding this line;
physics.setDrawMode ( “hybrid” )

Also, the body for your player is a circle much larger than itself, is this intentional? [import]uid: 52491 topic_id: 22117 reply_id: 91206[/import]

Hi Peach,

Thank you for your quick answer. Infact is my characters shape not a circle, instead I have defined my characters shape with a Physics Editor. This can not be seen because of my plug and play code above :slight_smile: I will try to post the “real” code.

[lua]function new()

local Level1 = display.newGroup()

display.setStatusBar( display.HiddenStatusBar ) – Hide Status Bar

– REQUIRED EXTERNAL LIBRARIES
local radlib = require “radlib”
local ui = require(“ui”)
local scaleFactor = 1
local physicsData = (require “Physics”).physicsData(scaleFactor)

– REQUIRED PHYSICS
local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 9.5 )
physics.setDrawMode( “hybrid” )
–physics.setDrawMode( “debug” )

–GAME SEETTINGS
local gameIsActive = false
local levelCompleted = false

–OBJECTS
local Platform1
local ground
local leftWall
local rightWall
local Player
local topWall

– HUD OBJECTS
local Background
local HudBar
local tryAgainBtn
local menuBtn
local menuBtn1
local PauseOverlay
local ResetLevelBtn

–Background
Background = display.newImageRect(“Level1BGK.png”, 480, 320 )
Background.x = 240
Background.y = 160
Level1:insert(Background)

–Platform 1

Platform1 = display.newImageRect(“PFinal.png”, 205, 36)
physics.addBody(Platform1, “static”, physicsData:get(“PFinal”))
Platform1.x = 363
Platform1.y = 220
Platform1.myName = “Platform1”

–HUD BAR
HudBar = display.newImageRect(“HBar.png”, 480, 25 )
HudBar.x = 240
HudBar.y = 12
Level1:insert(HudBar)

–Ground
ground = display.newImageRect(“Ground.png”, 479, 1 )
ground.x = 240
ground.y = 321
physics.addBody(ground, “static”, {bounce=0})
ground.myName = “ground”
Level1:insert(ground)
– create wall objects
topWall = display.newRect( 0, 0, display.contentWidth, 1)
topWall.alpha = 0
topWall.myName = “topWall”
leftWall = display.newRect( 0, 0, 1, display.contentHeight )
leftWall.alpha = 0
leftWall.myName = “leftWall”
rightWall = display.newRect( display.contentWidth - 1, 0, 1, display.contentHeight )
rightWall.myName = “rightWall”
rightWall.alpha = 0

– make them physics bodies
physics.addBody(topWall, “static”, {density = 1.0, friction = 1, bounce = 1, isSensor = false})
physics.addBody(leftWall, “static”, {density = 1.0, friction = 1, bounce = 1, isSensor = false})
physics.addBody(rightWall, “static”, {density = 1.0, friction = 1, bounce = 1, isSensor = false})
–Pause Screen

local touchPause = function( event )

if event.phase == “began” then
if gameIsActive then
– Pause the game
gameIsActive = false
system.setIdleTimer( true ) – turn on device sleeping

– START PAUSE SCREEN

– Pause Overlay
pauseOverlay = display.newImageRect(“pauseoverlay.png”, 440, 277 )
pauseOverlay.x = 240; pauseOverlay.y = 170
pauseOverlay.isVisible = true

Level1:insert(pauseOverlay)

ResetLevelBtn = ui.newButton{
defaultSrc = “ResetLevel.png”,
defaultX = 170,
defaultY = 70,
overSrc = “ResetLevelPressed.png”,
overX = 170,
overY = 70,
onEvent = touchResetLevel,
id = “ResetLevelButton”,
text = “”,
font = “Helvetica”,
textColor = { 255, 255, 255, 255 },
size = 16,
emboss = false
}

ResetLevelBtn .xOrigin =350; ResetLevelBtn .yOrigin =248
ResetLevelBtn .isVisible = true
ResetLevelBtn.isActive = true

Level1:insert(ResetLevelBtn )

local touchResetLevel = function( event )
if event.phase == “release” and ResetLevelBtn.isActive == true then

print(“Button Was pressed”)
–main menu call
director:changeScene( “Level1”, “fade” )
end
end

menuBtn1 = ui.newButton{
defaultSrc = “MainMenu.png”,
defaultX = 170,
defaultY = 70,
overSrc = “MainMenuPressed.png”,
overX = 170,
overY = 70,
onEvent = touchMenuBtn1,
id = “menuButton1”,
text = “”,
font = “Helvetica”,
textColor = { 255, 255, 255, 255 },
size = 16,
emboss = false
}

menuBtn1.xOrigin =130; menuBtn1.yOrigin =248
menuBtn1.isVisible = true
menuBtn1.isActive = true

Level1:insert( menuBtn1 )

local touchMenuBtn1 = function( event )
if event.phase == “release” and menuBtn1.isActive == true then

print(“Button Was pressed”)

–main menu call
director:changeScene( “GotoMainMenu”, “fade” )
end
end

physics.pause()

else
– Unpause the game
system.setIdleTimer( false ) – turn off device sleeping
gameIsActive = true

if pauseOverlay then
pauseOverlay.isVisible = false;
display.remove( pauseOverlay )
pauseOverlay = nil
end

if menuBtn1 then
menuBtn1.isVisible = false
menuBtn1.isActive = false
menuBtn = nil
display.remove( menuBtn1 )

end

if ResetLevelBtn then
ResetLevelBtn.isVisible = false
ResetLevelBtn.isActive = false
ResetLevelBtn = nil
display.remove(ResetLevelBtn)

end

physics.start()

end

end

end

Runtime:addEventListener( “touch”, touchPause )

Player = display.newImageRect(“Player.png”, 40, 40 )
physics.addBody( Player, “dynamic”, physicsData:get(“Player1”))
Player.x = 40
Player.y = 100
Player.myName = “Player”
Player.isFixedRotation = true
Player.iAwake = true
Player.isBullet = true
Level1:insert(Player)

function Player:collision (event)
if event.phase == “ended” and event.other.myName ~= “coin” and event.other.myName ~= “leftWall” and event.other.myName ~= “rightWall” and event.other.myName ~= “topWall” then
Player:applyForce(0,-40, Player.x, Player.y)

if event.other.myName == “ground” then

gameIsActive = false

physics.pause()
Runtime:removeEventListener( “touch”, touchPause )
Player:removeSelf()

print(“GameOver!”)

end

end
end
Player:addEventListener(“collision”, Player)

function onTilt( event )
physics.setGravity( ( 9.8 * remote.xGravity ), 0 )
end

Runtime:addEventListener( “accelerometer”, onTilt )

–Corns to collect - total - 5
local coin = {}
coin[1] = display.newImageRect(“coin.png”, 20, 20)

coin[1].x = 160
coin[1].y = 238
coin[1].myName = “coin”

coin[2] = display.newImageRect(“coin.png”, 20, 20)
coin[2].x = 180
coin[2].y = 238
coin[2].myName = “coin”
coin[3] = display.newImageRect(“coin.png”, 20, 20)
coin[3].x = 200
coin[3].y = 238
coin[3].myName = “coin”

physics.addBody(coin[1],“static”, {isSensor = true})
physics.addBody(coin[2],“static”, {isSensor = true})
physics.addBody(coin[3],“static”,{isSensor = true})

local function onCollision( event )
if ( event.phase == “began” ) then

if event.object2.myName == “coin” and event.object1.myName == “Player” then
event.object2.alpha = 0.001

end

elseif ( event.phase == “ended” ) then

if event.object2.myName == “coin” and event.object1.myName == “Player” then
event.object2:removeSelf()
event.object2 = nil

end

end

Runtime:addEventListener( “collision”, onCollision )

– MUST return a display.newGroup()
return Level1

end [import]uid: 122802 topic_id: 22117 reply_id: 91224[/import]

Too much friction on the walls. Try changing it to a lower number like 0.3. [import]uid: 38820 topic_id: 22117 reply_id: 91231[/import]

Hi glennbjr,

Thank you for your answer, but it doesn’t seem to solve that problem. Other suggestions to solve the problems I have explained above is really appreciated. Thank you in advance [import]uid: 122802 topic_id: 22117 reply_id: 91461[/import]

This doesn’t answer your question but i want to point it out.

You can make life easier for yourself in a few ways there

Rather than adding a body individually for each coin in your coin table, just use a loop :

[code]

for i = 1, #coin do
physics.addBody(coin[i], “static”, {isSensor = true})
end [import]uid: 84637 topic_id: 22117 reply_id: 91465[/import]

What happens when you set the wall friction to zero?

You can also prevent an object from sticking to a wall by using a collision listener. When your hero touches the wall you can detect the collision and apply force to your hero forcing it away from the wall so it doesn’t stick.

[import]uid: 38820 topic_id: 22117 reply_id: 91481[/import]

On tilt you are removing the y gravity. This can cause your hero to stick to the top wall. You are also bouncing your hero up forcing it against the top wall with no y gravity so it could get stuck against that wall too.

But, it’s hard finding the exact issue with just snippets of code. It might be easier with an example in a zipped file that we can test out.

Hope this helps. [import]uid: 38820 topic_id: 22117 reply_id: 91486[/import]

Hi Danny & glennbjr

Thank you very much for your feedback, I really appreciate it. In the meantime I have found out that the characters physics shape is causing one of the problems related to the issue that the character stops jumping when colliding with a coin. I still haven’t found the reasons for the sticky walls. Here is my code, uploaded in a zip file.
http://www.mediafire.com/?m6qxc8q41yysx5q

Thank you for your support. [import]uid: 122802 topic_id: 22117 reply_id: 91750[/import]

I looked at and tested your code. All physics objects must be in the same display group or you will experience weird problems with physics objects.

So your Level1 group you need to insert Platform1, Platform2 and each coin into the Level1 display group. [import]uid: 38820 topic_id: 22117 reply_id: 91776[/import]