Touch with proximity/collision detection

Hi guys, complete newbie here.
I’m having problems with a simple concept in Corona. I have an idea for a simple game where the player touches a character and drags/moves him to a box shape (like a building) to finish the level.
I have the characters spawning and touch enabled but can’t figure out how to get the box object to respond to the player when I drag him onto it.

Any help will be appreciated. Thanks [import]uid: 92074 topic_id: 15811 reply_id: 315811[/import]

if you are using physics you can detect collision between the character and box.
[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,0)
local circle = display.newCircle(150,150,40)
circle.alpha = .5
physics.addBody(circle ,“static”,{isSensor=true})
local square = display.newRect(50,50,20,20)
physics.addBody(square ,“dynamic”)
local function squareCollision(event)
if event.phase ==“began” then
print(“inside circle”)
end
end

local function moveSquare( event )
local t = event.target
local phase = event.phase
if “began” == phase then
– Make target the top-most object
local parent = t.parent
parent:insert( t )
display.getCurrentStage():setFocus( t )
t.isFocus = true
elseif t.isFocus then
if “moved” == phase then
t.x = event.x
t.y = event.y
elseif “ended” ==phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
end
end
return true
end

square:addEventListener(“touch”,moveSquare)
square:addEventListener(“collision”,squareCollision)[/lua]

if you don’t want to use physics you can check the content bounds of the square to see whether the player is inside the square.

it will be something like below
note: please see the terminal window also
[lua]local circle = display.newCircle(150,150,40)
circle.alpha = .5

local square = display.newRect(50,50,20,20)

local function moveSquare( event )
local t = event.target
local phase = event.phase
if “began” == phase then
– Make target the top-most object
local parent = t.parent
parent:insert( t )
display.getCurrentStage():setFocus( t )
t.isFocus = true
elseif t.isFocus then
if “moved” == phase then
t.x = event.x
t.y = event.y
elseif “ended” == phase then
local bounds = circle.contentBounds
if square.x > bounds.xMin and square.x < bounds.xMax and square.y > bounds.yMin and square.y < bounds.yMax then
print(“inside circle”)
end
end
end
return true
end

square:addEventListener(“touch”,moveSquare)[/lua] [import]uid: 71210 topic_id: 15811 reply_id: 58510[/import]

Thanks renvis@technowand,

I’ve run into difficulty using the physics system with collision detection. I can get the single player character to end the level by landing on the building. But, my later levels will have a few characters and I need them all to be placed into the building to complete the level. I’ve tried using the isSensor=true for the building object. This works for 1 single character with dynamic physics but I can’t get it to work with more than 1. The characters sort of “cancel each other out” when they interact. I want them to only disappear when they touch the building.
Basically, the game is to simply put “Character A, B, and C” into/onto “Object A” to complete the level.
I’ve been using this code to try it out before I implement it in my actual game.
Any thoughts?

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

local circle = display.newCircle(150,150,40)
circle.alpha = .5
physics.addBody(circle ,“static”,{isSensor=true})

local group1 = display.newGroup()
for i=1, group1.numChildren do
local child = group[i]
end

local square = display.newRect(50,50,20,20)
physics.addBody(square ,“dynamic”)

local square2 = display.newRect(20,20,20,20)
physics.addBody(square2 ,“dynamic”)

local square3 = display.newRect(0,0,20,20)
square3.x = 100; square3.y = 300
physics.addBody(square3 ,“dynamic”)

group1:insert(square)
group1:insert(square2)
group1:insert(square3)

–MOVE SQUARE
local function moveSquare( event )
local t = event.target
local phase = event.phase
if “began” == phase then
– Make target the top-most object
local parent = t.parent
parent:insert( t )
display.getCurrentStage():setFocus( t )
t.isFocus = true
elseif t.isFocus then
if “moved” == phase then
t.x = event.x
t.y = event.y
elseif “ended” ==phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
end
end
return true
end

square:addEventListener(“touch”,moveSquare)
square:addEventListener(“collision”,squareCollision)

square2:addEventListener(“touch”,moveSquare)
square2:addEventListener(“collision”,squareCollision)

square3:addEventListener(“touch”,moveSquare)
square3:addEventListener(“collision”,squareCollision)

local function squareCollision(event)
if event.phase ==“began” then
removeBody(event)
end
end

–STUFF WHEN COMPLETE
local function winTxt()
if(group1.numChildren == 0) then
wintext = display.newText(“Yes”, 160, 240, “Marker Felt”, 40)
wintext:setTextColor(255,0,0)
end
end

–REMOVAL
function removeBody(event)
event.target:removeSelf()
event.target = nil
winTxt()

end
[/code] [import]uid: 92074 topic_id: 15811 reply_id: 59496[/import]

sorry for the delay in replying. was busy with some other stuffs…

I think you better register the collision listener to the circle object (building object) rather than square objects. so you just need to put one listener.

you can do it other way also. but the error i see in the above code is with the declaration of squareCollision. you are declaring the function after the place you are calling it. so you should either move the function above the addEventListener or give a forward declaration. see the code below

[lua]local function squareCollision(event)
if event.phase ==“began” then
removeBody(event)
end
end

square:addEventListener(“touch”,moveSquare)
square:addEventListener(“collision”,squareCollision)

square2:addEventListener(“touch”,moveSquare)
square2:addEventListener(“collision”,squareCollision)

square3:addEventListener(“touch”,moveSquare)
square3:addEventListener(“collision”,squareCollision)[/lua]

or
[lua]local squareCollision
square:addEventListener(“touch”,moveSquare)
square:addEventListener(“collision”,squareCollision)

square2:addEventListener(“touch”,moveSquare)
square2:addEventListener(“collision”,squareCollision)

square3:addEventListener(“touch”,moveSquare)
square3:addEventListener(“collision”,squareCollision)

function squareCollision(event)
if event.phase ==“began” then
removeBody(event)
end
end[/lua]

hope this helps
[import]uid: 71210 topic_id: 15811 reply_id: 59644[/import]

fixed your code.
hope this is what you where trying to achieve
[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0,0)

local circle = display.newCircle(150,150,40)
circle.alpha = .5
physics.addBody(circle ,“static”,{isSensor=true})

local group1 = display.newGroup()
for i=1, group1.numChildren do
local child = group[i]
end

local square = display.newRect(50,50,20,20)
physics.addBody(square ,“dynamic”)

local square2 = display.newRect(20,20,20,20)
physics.addBody(square2 ,“dynamic”)

local square3 = display.newRect(0,0,20,20)
square3.x = 100; square3.y = 300
physics.addBody(square3 ,“dynamic”)

group1:insert(square)
group1:insert(square2)
group1:insert(square3)

–MOVE SQUARE
local function moveSquare( event )
local t = event.target
local phase = event.phase
if “began” == phase then
– Make target the top-most object
local parent = t.parent
parent:insert( t )
display.getCurrentStage():setFocus( t )
t.isFocus = true
elseif t.isFocus then
if “moved” == phase then
t.x = event.x
t.y = event.y
elseif “ended” ==phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
end
end
return true
end

square:addEventListener(“touch”,moveSquare)
square2:addEventListener(“touch”,moveSquare)
square3:addEventListener(“touch”,moveSquare)

local removeBody
local function squareCollision(event)
if event.phase ==“began” then
removeBody(event.other)
end
end

circle:addEventListener(“collision”,squareCollision)

–STUFF WHEN COMPLETE
local function winTxt()
if(group1.numChildren == 0) then
wintext = display.newText(“Yes”, 160, 240, “Marker Felt”, 40)
wintext:setTextColor(255,0,0)
end
end

–REMOVAL
function removeBody(object)
object:removeSelf()
object = nil
winTxt()

end[/lua] [import]uid: 71210 topic_id: 15811 reply_id: 59646[/import]

Thanks Renvis, that worked perfectly. I got it working with my game. Really appreciate your help. [import]uid: 92074 topic_id: 15811 reply_id: 59721[/import]