drag object and collision event

Hello everyone,
My name is Giuseppe and I am a teacher for disabled students.
I’m sorry for my english.

I found yesterday Corona SDK and I’m amazed by so much power.
I want to congratulate with the staff of Corona.

Lua is a language that I never used,
but I want to learn.
I learned this morning to enter the background

local centerX = display.contentCenterX
local centerY = display.contentCenterY
local _W = display.contentWidth
local _H = display.contentHeight
local bkg = display.newImage (“background.png” centerX, centerY)

and then to insert new image with absolute X and Y
local test = display.newImage (“test.png”, 100, 50).

to other things.

I want to develop a small game for children with cognitive problems.
I’m changing the project DragMe.
The goal of the game is to drag the red rectangle in the red basket,
here I’m finding a lot of problems.

I think the best solution is to have images to be loaded with

local red = {}
local blue = {}

for i = 1,2 do
red [i] = display.newImage (“red_balloon.png” math.random + 100 (50), 50)
blue [i] = display.newImage (“blue_balloon.png”, 100+ math.random (50), 100)
end

I added the red basket
local test = display.newImage (“basket_red.png”, 300, 0).

I think I have to use the event Collision Filtering

ballRedCollisionFilter = categoryBits = {1, 6} = maskBits
it’s right?

then I have to add the event
local redCollisionFilter categoryBits = = {2, 3} = maskBits
it’s right?

Now if the red ball collide with the red basket,
red ball disappears, it is right to do this:

display.remove (red)
 red: removeSelf ()

where this is inserted inside in curly braces?
local redCollisionFilter = {…}

sorry for the long post, and thanks again for the help.

Hello and welcome :slight_smile:

I think you are going down the wrong path with collision filters and collision events. Those belong to physics, which you don’t need to solve this problem. As I understand it, what you want to do is drag objects towards a “basket”, and when the right color of object is dragged to the right color of basket, the object disappears. All you need to do that is a touch listener and a bit of math.

Here, I have edited the DragMe example to spawn a blue and a red rectangle, and if the red rectangle is dragged over the red “basket” (which is just a circle), it disappears. Try it out.

local rectangles = { { x=200, y=60, w=50, h=50, r=10, red=1, green=0, blue=0 }, { x=80, y=100, w=50, h=50, r=10, red=0, green=0, blue=1 }, } local baskets = {} -- table to hold a list of "baskets" -- Check if a basket is colliding with a rectangle of the same color, and if it does, remove the rectangle local function checkCollision(event) if event.target then local rect = event.target for i = 1, #baskets do local basket = baskets[i] local basketColor = basket.fillColor local rectColor = rect.fillColor local sameColor = basketColor[1] == rectColor[1] and basketColor[2] == rectColor[2] and basketColor[3] == rectColor[3] local distance = math.sqrt((basket.x - rect.x)^2 + (basket.y - rect.y)^2) if distance \< 50 and sameColor then display.remove(rect) end end end end local function onTouch( event ) local t = event.target -- Do our collision checking checkCollision(event) 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 -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end -- Iterate through rectangles array and create rounded rects (vector objects) for each item for \_,item in ipairs( rectangles ) do local button = display.newRoundedRect( item.x, item.y, item.w, item.h, item.r ) button.fillColor = {item.red, item.green, item.blue} button:setFillColor(unpack(button.fillColor)) button.strokeWidth = 6 button:setStrokeColor(1) -- Make the button instance respond to touch events button:addEventListener( "touch", onTouch ) end -- Add "baskets" (just a single red circle "basket" for now) local basket = display.newCircle(display.contentCenterX, display.contentCenterY, 50) basket.fillColor = {1, 0, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket)

You’re going to run into problems with this.  Physics bodies need to be moved by physics, not by transitions or dragging to work right. This will cause collisions to not work the way you want since two systems are competing to move the object.  We  have a tutorial on testing when two objects collide without using Physics.  Please read:

https://coronalabs.com/blog/2013/07/23/tutorial-non-physics-collision-detection/

Rob

Thanks Rob,
thanks for the advice,
I followed the tutorial but combining parts of the code,

error appears in this line

elseif (phase == “ended” or phase == “canceled”) then

Thanks memo,
your example is very clear,
I have understood and I have changed
the distance of collision and the quantity of objects
and other little things.

Now I have seven rectangles moving
 

local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, }

each rectangle has his basket with his own color.

I wish that when all rectangles have “disappeared”
return all seven on the screen,
how can I develop this?

Perhaps with a variable?
 

thanks

Hi @android.masc,

I’d like to clarify a few points just for your understanding as you move forward:

When working with physics objects, especially those under the influence of simulated physical forces like gravity or other forces, you generally should not explicitly set the x/y position of these objects or control them via transitions (positional x/y shift from one point to another). This is because the physics engine naturally wants to control those objects in the scope of the physical simulation, and by setting the positions directly, you are “fighting against” the physics engine’s expected calculations. This will usually result in erratic behavior and possibly even skipping as the two systems battle with each other for positional control of the object.

Note that direct x/y manipulation of physics-enabled objects is legal and completely logical under certain circumstances, including:

  1. Physical bodies that are not under the influence of forces like gravity, for example “kinematic” bodies or those with .gravityScale=0.

  2. Physical bodies which are temporarily “asleep” or inactive.

Another note on controlling physical objects directly relates to collisions. Moving a physical object via direct x/y positioning will still register collisions with other physical bodies, assuming you have set up the collision detection properly. However, collisions are detected on a per-frame (application Runtime FPS rate), and if the initial position and the next position of the manipulated physical object does not result in an overlap of the other physical object, no collision will register… in other words, if the positional shift causes the first object to skip through the other object without registering a contact point, the physics engine will not register that a collision occurred, because technically it did not.

Hope this makes sense,

Brent

Thank you, Brent Sorrentino

for your explanation,
you are very clear and complete in your intervention.
Your message is very important for people like me who does not have knowledge
computer correct.

In these days, through the forum,
I learned many things, for me, of Corona SDK:
I have learned to put the score in my game,
to enter the levels in the game,
to make small animations,
to scale objects,
using math.random etc …
My small program for students with cognitive disabilities
It is almost finished.

But what I can not understand is,
I have seven objects declared thus:

local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, }

if a rectangle object collides with a “basket”

display.remove (rect)

the production of arrays of rectangles is controlled by

_ for, items in ipairs (rectangles) do
local button = display.newRoundedRect (item.x, item.y, item.w, item.h, item.r)

end

whenever a rectangle object collides with the “basket”
the rectangle is removed from the display with display.remove (rect)
as I can when all the rectangles and 7 have been removed,
make them reappear on the display?

Thank you for your help

Hi @android.masc,

You should probably keep a counter variable for the number of rectangles. Then, when it reaches 7, you can loop through the “rectangles” table and place all rectangles back on the screen.

Also, you don’t need to use “ipairs” for this structure. Just loop through the table. If you don’t fully understand the difference between Lua tables with non-named members and Lua tables with named “dictionary” members, you should research that topic separately.

Brent

Thanks Brent,
I have executed with the variable score = 7
(each rectangle that goes in the “basket” right has a point)
but it does not work,
I put all the code…

display.setStatusBar( display.HiddenStatusBar ) local centerX = display.contentCenterX local centerY = display.contentCenterY local \_W = display.contentWidth local \_H = display.contentHeight local bkg = display.newImage ("prato3.png", centerX, centerY,true) score = 0 local function rettanglesNew() rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, } end local scoreNumber = display.newText(score, display.contentCenterX + 60, 20, native.systemFontBold, 20) scoreNumber:setFillColor( 1, 0, 0 ) local function updateScore() score = score + 1 scoreNumber.text = score end local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, } local baskets = {} -- table to hold a list of "baskets" -- Check if a basket is colliding with a rectangle of the same color, and if it does, remove the rectangle local function checkCollision(event) if event.target then local rect = event.target for i = 1, #baskets do local basket = baskets[i] local basketColor = basket.fillColor local rectColor = rect.fillColor local sameColor = basketColor[1] == rectColor[1] and basketColor[2] == rectColor[2] and basketColor[3] == rectColor[3] local distance = math.sqrt((basket.x - rect.x)^2 + (basket.y - rect.y)^2) if distance \< 20 and sameColor then display.remove(rect) updateScore() if score == 7 then rettanglesNew() end end end end end local function onTouch( event ) local t = event.target -- Do our collision checking checkCollision(event) 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 -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end -- Iterate through rectangles array and create rounded rects (vector objects) for each item for \_,item in ipairs( rectangles ) do local button = display.newCircle(item.x, item.y, item.r ) button.fillColor = {item.red, item.green, item.blue} button:setFillColor(unpack(button.fillColor)) button.strokeWidth = 3 button:setStrokeColor(0) -- Make the button instance respond to touch events button:addEventListener( "touch", onTouch ) end -- Add "baskets" (just a single red circle "basket" for now) local basket = display.newCircle(100, 112, 14) basket.fillColor = {1, 0, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(300, 112, 14) basket.fillColor = {1, 1, 1} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(200, 112, 14) basket.fillColor = {1, 1, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(400, 112, 14) basket.fillColor = {1, 0, 1} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket)

where I am wrong?

thanks for the help

Hi @android.masc,

Can you please be more specific about what “doesn’t work”?

Thanks,

Brent

Hi Brent,

my problem is this:
after the rectangles have collided with the relative “baskets” and are removed,
I wish they all reappear,
the simplest solution to understand when all rectangles are all removed
It is a score = 7,
since each rectangle collides with the right basket,
the rectangle is removed and there is a point in the score,

I tried using the function rectanglesNew
but it does not work,
my code is this

display.setStatusBar( display.HiddenStatusBar ) local centerX = display.contentCenterX local centerY = display.contentCenterY local \_W = display.contentWidth local \_H = display.contentHeight local bkg = display.newImage ("prato3.png", centerX, centerY,true) score = 0 local function rettanglesNew() rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, } end local scoreNumber = display.newText(score, display.contentCenterX + 60, 20, native.systemFontBold, 20) scoreNumber:setFillColor( 1, 0, 0 ) local function updateScore() score = score + 1 scoreNumber.text = score end local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, } local baskets = {} -- table to hold a list of "baskets" -- Check if a basket is colliding with a rectangle of the same color, and if it does, remove the rectangle local function checkCollision(event) if event.target then local rect = event.target for i = 1, #baskets do local basket = baskets[i] local basketColor = basket.fillColor local rectColor = rect.fillColor local sameColor = basketColor[1] == rectColor[1] and basketColor[2] == rectColor[2] and basketColor[3] == rectColor[3] local distance = math.sqrt((basket.x - rect.x)^2 + (basket.y - rect.y)^2) if distance \< 20 and sameColor then display.remove(rect) updateScore() if score == 7 then rettanglesNew() end end end end end local function onTouch( event ) local t = event.target -- Do our collision checking checkCollision(event) 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 -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end -- Iterate through rectangles array and create rounded rects (vector objects) for each item for \_,item in ipairs( rectangles ) do local button = display.newCircle(item.x, item.y, item.r ) button.fillColor = {item.red, item.green, item.blue} button:setFillColor(unpack(button.fillColor)) button.strokeWidth = 3 button:setStrokeColor(0) -- Make the button instance respond to touch events button:addEventListener( "touch", onTouch ) end -- Add "baskets" (just a single red circle "basket" for now) local basket = display.newCircle(100, 112, 14) basket.fillColor = {1, 0, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(300, 112, 14) basket.fillColor = {1, 1, 1} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(200, 112, 14) basket.fillColor = {1, 1, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(400, 112, 14) basket.fillColor = {1, 0, 1} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket)

how I can fix this?

thanks

Hi @android.masc,

I suggest that you re-think this somewhat. If you want to “replace” all 7 rectangles at some point, you don’t need to remove them entirely (destroy them). Instead, you should move them far off screen or make them invisible/inactive. Then, later, reposition the exact same 7 rectangles where needed.

Brent

If you are going to use only 7 physical items, like Brent said, don’t remove them. Use something like item.isVisible = false, and turn it to true whenever you need them to appear again. If you are going to make them invisible for a considerable ammount of time, you might want to remove the physical body (not the item) and add it again after you make it visible again.

https://docs.coronalabs.com/api/type/DisplayObject/isVisible.html

https://docs.coronalabs.com/api/library/physics/removeBody.html

If you are going to use removeBody right after the colision, you will need to do it some miliseconds after it just to make sure it works (like the documents say): timer.performWithDelay(10,function()physics.removeBody(item);end,1)

Hello and welcome :slight_smile:

I think you are going down the wrong path with collision filters and collision events. Those belong to physics, which you don’t need to solve this problem. As I understand it, what you want to do is drag objects towards a “basket”, and when the right color of object is dragged to the right color of basket, the object disappears. All you need to do that is a touch listener and a bit of math.

Here, I have edited the DragMe example to spawn a blue and a red rectangle, and if the red rectangle is dragged over the red “basket” (which is just a circle), it disappears. Try it out.

local rectangles = { { x=200, y=60, w=50, h=50, r=10, red=1, green=0, blue=0 }, { x=80, y=100, w=50, h=50, r=10, red=0, green=0, blue=1 }, } local baskets = {} -- table to hold a list of "baskets" -- Check if a basket is colliding with a rectangle of the same color, and if it does, remove the rectangle local function checkCollision(event) if event.target then local rect = event.target for i = 1, #baskets do local basket = baskets[i] local basketColor = basket.fillColor local rectColor = rect.fillColor local sameColor = basketColor[1] == rectColor[1] and basketColor[2] == rectColor[2] and basketColor[3] == rectColor[3] local distance = math.sqrt((basket.x - rect.x)^2 + (basket.y - rect.y)^2) if distance \< 50 and sameColor then display.remove(rect) end end end end local function onTouch( event ) local t = event.target -- Do our collision checking checkCollision(event) 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 -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end -- Iterate through rectangles array and create rounded rects (vector objects) for each item for \_,item in ipairs( rectangles ) do local button = display.newRoundedRect( item.x, item.y, item.w, item.h, item.r ) button.fillColor = {item.red, item.green, item.blue} button:setFillColor(unpack(button.fillColor)) button.strokeWidth = 6 button:setStrokeColor(1) -- Make the button instance respond to touch events button:addEventListener( "touch", onTouch ) end -- Add "baskets" (just a single red circle "basket" for now) local basket = display.newCircle(display.contentCenterX, display.contentCenterY, 50) basket.fillColor = {1, 0, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket)

You’re going to run into problems with this.  Physics bodies need to be moved by physics, not by transitions or dragging to work right. This will cause collisions to not work the way you want since two systems are competing to move the object.  We  have a tutorial on testing when two objects collide without using Physics.  Please read:

https://coronalabs.com/blog/2013/07/23/tutorial-non-physics-collision-detection/

Rob

Thanks Rob,
thanks for the advice,
I followed the tutorial but combining parts of the code,

error appears in this line

elseif (phase == “ended” or phase == “canceled”) then

Thanks memo,
your example is very clear,
I have understood and I have changed
the distance of collision and the quantity of objects
and other little things.

Now I have seven rectangles moving
 

local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, }

each rectangle has his basket with his own color.

I wish that when all rectangles have “disappeared”
return all seven on the screen,
how can I develop this?

Perhaps with a variable?
 

thanks

Hi @android.masc,

I’d like to clarify a few points just for your understanding as you move forward:

When working with physics objects, especially those under the influence of simulated physical forces like gravity or other forces, you generally should not explicitly set the x/y position of these objects or control them via transitions (positional x/y shift from one point to another). This is because the physics engine naturally wants to control those objects in the scope of the physical simulation, and by setting the positions directly, you are “fighting against” the physics engine’s expected calculations. This will usually result in erratic behavior and possibly even skipping as the two systems battle with each other for positional control of the object.

Note that direct x/y manipulation of physics-enabled objects is legal and completely logical under certain circumstances, including:

  1. Physical bodies that are not under the influence of forces like gravity, for example “kinematic” bodies or those with .gravityScale=0.

  2. Physical bodies which are temporarily “asleep” or inactive.

Another note on controlling physical objects directly relates to collisions. Moving a physical object via direct x/y positioning will still register collisions with other physical bodies, assuming you have set up the collision detection properly. However, collisions are detected on a per-frame (application Runtime FPS rate), and if the initial position and the next position of the manipulated physical object does not result in an overlap of the other physical object, no collision will register… in other words, if the positional shift causes the first object to skip through the other object without registering a contact point, the physics engine will not register that a collision occurred, because technically it did not.

Hope this makes sense,

Brent

Thank you, Brent Sorrentino

for your explanation,
you are very clear and complete in your intervention.
Your message is very important for people like me who does not have knowledge
computer correct.

In these days, through the forum,
I learned many things, for me, of Corona SDK:
I have learned to put the score in my game,
to enter the levels in the game,
to make small animations,
to scale objects,
using math.random etc …
My small program for students with cognitive disabilities
It is almost finished.

But what I can not understand is,
I have seven objects declared thus:

local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, }

if a rectangle object collides with a “basket”

display.remove (rect)

the production of arrays of rectangles is controlled by

_ for, items in ipairs (rectangles) do
local button = display.newRoundedRect (item.x, item.y, item.w, item.h, item.r)

end

whenever a rectangle object collides with the “basket”
the rectangle is removed from the display with display.remove (rect)
as I can when all the rectangles and 7 have been removed,
make them reappear on the display?

Thank you for your help

Hi @android.masc,

You should probably keep a counter variable for the number of rectangles. Then, when it reaches 7, you can loop through the “rectangles” table and place all rectangles back on the screen.

Also, you don’t need to use “ipairs” for this structure. Just loop through the table. If you don’t fully understand the difference between Lua tables with non-named members and Lua tables with named “dictionary” members, you should research that topic separately.

Brent

Thanks Brent,
I have executed with the variable score = 7
(each rectangle that goes in the “basket” right has a point)
but it does not work,
I put all the code…

display.setStatusBar( display.HiddenStatusBar ) local centerX = display.contentCenterX local centerY = display.contentCenterY local \_W = display.contentWidth local \_H = display.contentHeight local bkg = display.newImage ("prato3.png", centerX, centerY,true) score = 0 local function rettanglesNew() rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, } end local scoreNumber = display.newText(score, display.contentCenterX + 60, 20, native.systemFontBold, 20) scoreNumber:setFillColor( 1, 0, 0 ) local function updateScore() score = score + 1 scoreNumber.text = score end local rectangles = { { x=100, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=30, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=170, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=240, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=310, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=380, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, { x=450, y=300, w=50, h=50, r=20, red=1, green=math.random(0,1), blue=math.random(0,1) }, } local baskets = {} -- table to hold a list of "baskets" -- Check if a basket is colliding with a rectangle of the same color, and if it does, remove the rectangle local function checkCollision(event) if event.target then local rect = event.target for i = 1, #baskets do local basket = baskets[i] local basketColor = basket.fillColor local rectColor = rect.fillColor local sameColor = basketColor[1] == rectColor[1] and basketColor[2] == rectColor[2] and basketColor[3] == rectColor[3] local distance = math.sqrt((basket.x - rect.x)^2 + (basket.y - rect.y)^2) if distance \< 20 and sameColor then display.remove(rect) updateScore() if score == 7 then rettanglesNew() end end end end end local function onTouch( event ) local t = event.target -- Do our collision checking checkCollision(event) 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 -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then display.getCurrentStage():setFocus( nil ) t.isFocus = false end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end -- Iterate through rectangles array and create rounded rects (vector objects) for each item for \_,item in ipairs( rectangles ) do local button = display.newCircle(item.x, item.y, item.r ) button.fillColor = {item.red, item.green, item.blue} button:setFillColor(unpack(button.fillColor)) button.strokeWidth = 3 button:setStrokeColor(0) -- Make the button instance respond to touch events button:addEventListener( "touch", onTouch ) end -- Add "baskets" (just a single red circle "basket" for now) local basket = display.newCircle(100, 112, 14) basket.fillColor = {1, 0, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(300, 112, 14) basket.fillColor = {1, 1, 1} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(200, 112, 14) basket.fillColor = {1, 1, 0} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket) local basket = display.newCircle(400, 112, 14) basket.fillColor = {1, 0, 1} basket:setFillColor(unpack(basket.fillColor)) table.insert(baskets, basket)

where I am wrong?

thanks for the help

Hi @android.masc,

Can you please be more specific about what “doesn’t work”?

Thanks,

Brent