Using Lua, could an object be obstructed by a line that was drawn by the user’s finger
Unfortunately collision sucks in Corona. There is no per pixel collision detection, you are left on the mercy of box2d collision detection which has it’s own limitations, like…
1: you can’t create custom shapes for an entire sprite sheet.
2: There is no way to scale/position the rectangle collision shape to fit your character.
3: There is no way to position/change shape of the circle collision shape to fit your character.
After several days of begging for help here LINK without any help offered, I ended up crating a custom solution for collision detection.
Line is too thin for box2d, at least few pixels needed to detect collisiona and object speeds cannot be too big in such cases
@coolromin is both wrong and writing about irrelevant subjects for this. Further, @seananigan1 has not mentioned sprites, so that’s a moot subject.
The Lua language does not provide any solution to the problem as it is a programming language. Corona does provide a solution to this problem.
#1 - The most obvious Lua-only-based solution requires that you record a list of the touch points that the user has made with their finger and then check against each of those, as well as the connecting lines between them, to see if your given object intersects with any of them. This solution is not the simplest because it relies on your ability to write the mathematical code to calculate line and any other object intersections, which can be tricky. However, this is purely a mathematics problem and nothing related to Lua or Corona.
#2 - Collision detection in Corona is provided by the very popular and widely used Box2D physics engine, originally written by Erin Catto of Blizzard fame. Essentially, it provides began and ended phases for collision events (there is more, but we don’t need it for this) and this allows display objects to be wrapped in physics objects which can then bounce off each other. Box2D has one key aspect to be aware of: It simulates a 2D world as realistically as it can, meaning that it is subject to the “immovable object vs irresistible force problem.”
On the subject of…
#1 - Corona’s per-pixel access: No, this is not available, is not likely to be available and, given that it is an intermediate platform, I would not expect it any time soon. It’s also a completely irrelevant subject for the question.
#2 - Custom shapes for sprite sheets: You can programmatically create any physics body and add and remove them to your display objects (sprite sheets included) as much as you like. This is also irrelevant as drawing with the finger on the screen does not require sprint sheets.
#3 - Changing object shapes: Correctly creating object shapes is the point here, not changing their shapes. Box2D does not allow a physics body to change shape, but it does allow multiple bodies to be connected together with joints, which is a more powerful system than just changing physics bodies. If you really wanted to change the shape of a sprite’s body you could remove it and replace it with another one, this is not performant for many reasons (all internal to Box2D itself and not Corona.)
#4 - The LINK: At the end of that thread you’ve asked “what is bounding box collision detection?” It is the most basic checking of two objects as they overlap. Think about where a rectangle, unrotated, would be if it completely and tightly enclosed your objects. That’s your bounding box.
Two tutorials to read:
Non-physics collision detection: http://www.coronalabs.com/blog/2013/07/23/tutorial-non-physics-collision-detection/
Detecting screen and object taps: http://www.coronalabs.com/blog/2012/07/24/detecting-object-and-screen-taps/
You should also take a look at the demos which come with the CoronaSDK application download and the Code Exchange on the website.
To demonstrate what can be done using Corona and the Box2D physics engine in very few lines of code (sorry for not commenting, but I can answer any questions later) here is a demo which lets you a draw line and then randomly creates 5 circles which drop from the top and bounce of the line:
main.lua:
function lengthOf( a, b ) local width, height = b.x-a.x, b.y-a.y return (width\*width + height\*height)^0.5 -- math.sqrt(width\*width + height\*height) end local PI = (4\*math.atan(1)) local quickPI = 180 / PI function angleOf( a, b ) return math.atan2( b.y - a.y, b.x - a.x ) \* quickPI end require("physics") physics.start() physics.setGravity(0,10) physics.setDrawMode("normal") -- use "hybrid" to see the physics data on screen function touch(e) if (e.phase == "began") then local group = display.newGroup() group.e = e display.getCurrentStage():setFocus(group) group:addEventListener("touch",touch) elseif (e.phase == "moved") then local group = e.target local len, angle = lengthOf( group.e, e ), angleOf( group.e, e ) local mid = { x=(group.e.x+e.x)/2, y=(group.e.y+e.y)/2 } group.e = e local rect = display.newRect( group, 0, 0, len, 5 ) rect.x, rect.y, rect.rotation = mid.x, mid.y, angle rect:setFillColor(0,255,0) physics.addBody( rect, "static" ) else local group = e.target for i=1, 5 do local radius = math.random(10, 60 ) local circle = display.newCircle( math.random( 100, display.contentWidth-100 ), 0, radius ) circle:setFillColor(0,0,255) physics.addBody( circle, "dynamic", { radius=radius, bounce=.6} ) end group:removeEventListener("touch",touch) display.getCurrentStage():setFocus(nil) end return true end Runtime:addEventListener("touch",touch)
On the subject of thin lines… Yes, a physics object cannot be too thin if you want things to bounce off it. This is because an object moving fast enough will have a time step point which takes it from one side of the thin object to the other without actually colliding. You can modify the position iterations to adjust this, though turning that up requires more processing power to be used by Box2D and subsequently can have a negative effect on low power devices.
Unfortunately collision sucks in Corona. There is no per pixel collision detection, you are left on the mercy of box2d collision detection which has it’s own limitations, like…
1: you can’t create custom shapes for an entire sprite sheet.
2: There is no way to scale/position the rectangle collision shape to fit your character.
3: There is no way to position/change shape of the circle collision shape to fit your character.
After several days of begging for help here LINK without any help offered, I ended up crating a custom solution for collision detection.
Line is too thin for box2d, at least few pixels needed to detect collisiona and object speeds cannot be too big in such cases
@coolromin is both wrong and writing about irrelevant subjects for this. Further, @seananigan1 has not mentioned sprites, so that’s a moot subject.
The Lua language does not provide any solution to the problem as it is a programming language. Corona does provide a solution to this problem.
#1 - The most obvious Lua-only-based solution requires that you record a list of the touch points that the user has made with their finger and then check against each of those, as well as the connecting lines between them, to see if your given object intersects with any of them. This solution is not the simplest because it relies on your ability to write the mathematical code to calculate line and any other object intersections, which can be tricky. However, this is purely a mathematics problem and nothing related to Lua or Corona.
#2 - Collision detection in Corona is provided by the very popular and widely used Box2D physics engine, originally written by Erin Catto of Blizzard fame. Essentially, it provides began and ended phases for collision events (there is more, but we don’t need it for this) and this allows display objects to be wrapped in physics objects which can then bounce off each other. Box2D has one key aspect to be aware of: It simulates a 2D world as realistically as it can, meaning that it is subject to the “immovable object vs irresistible force problem.”
On the subject of…
#1 - Corona’s per-pixel access: No, this is not available, is not likely to be available and, given that it is an intermediate platform, I would not expect it any time soon. It’s also a completely irrelevant subject for the question.
#2 - Custom shapes for sprite sheets: You can programmatically create any physics body and add and remove them to your display objects (sprite sheets included) as much as you like. This is also irrelevant as drawing with the finger on the screen does not require sprint sheets.
#3 - Changing object shapes: Correctly creating object shapes is the point here, not changing their shapes. Box2D does not allow a physics body to change shape, but it does allow multiple bodies to be connected together with joints, which is a more powerful system than just changing physics bodies. If you really wanted to change the shape of a sprite’s body you could remove it and replace it with another one, this is not performant for many reasons (all internal to Box2D itself and not Corona.)
#4 - The LINK: At the end of that thread you’ve asked “what is bounding box collision detection?” It is the most basic checking of two objects as they overlap. Think about where a rectangle, unrotated, would be if it completely and tightly enclosed your objects. That’s your bounding box.
Two tutorials to read:
Non-physics collision detection: http://www.coronalabs.com/blog/2013/07/23/tutorial-non-physics-collision-detection/
Detecting screen and object taps: http://www.coronalabs.com/blog/2012/07/24/detecting-object-and-screen-taps/
You should also take a look at the demos which come with the CoronaSDK application download and the Code Exchange on the website.
To demonstrate what can be done using Corona and the Box2D physics engine in very few lines of code (sorry for not commenting, but I can answer any questions later) here is a demo which lets you a draw line and then randomly creates 5 circles which drop from the top and bounce of the line:
main.lua:
function lengthOf( a, b ) local width, height = b.x-a.x, b.y-a.y return (width\*width + height\*height)^0.5 -- math.sqrt(width\*width + height\*height) end local PI = (4\*math.atan(1)) local quickPI = 180 / PI function angleOf( a, b ) return math.atan2( b.y - a.y, b.x - a.x ) \* quickPI end require("physics") physics.start() physics.setGravity(0,10) physics.setDrawMode("normal") -- use "hybrid" to see the physics data on screen function touch(e) if (e.phase == "began") then local group = display.newGroup() group.e = e display.getCurrentStage():setFocus(group) group:addEventListener("touch",touch) elseif (e.phase == "moved") then local group = e.target local len, angle = lengthOf( group.e, e ), angleOf( group.e, e ) local mid = { x=(group.e.x+e.x)/2, y=(group.e.y+e.y)/2 } group.e = e local rect = display.newRect( group, 0, 0, len, 5 ) rect.x, rect.y, rect.rotation = mid.x, mid.y, angle rect:setFillColor(0,255,0) physics.addBody( rect, "static" ) else local group = e.target for i=1, 5 do local radius = math.random(10, 60 ) local circle = display.newCircle( math.random( 100, display.contentWidth-100 ), 0, radius ) circle:setFillColor(0,0,255) physics.addBody( circle, "dynamic", { radius=radius, bounce=.6} ) end group:removeEventListener("touch",touch) display.getCurrentStage():setFocus(nil) end return true end Runtime:addEventListener("touch",touch)
On the subject of thin lines… Yes, a physics object cannot be too thin if you want things to bounce off it. This is because an object moving fast enough will have a time step point which takes it from one side of the thin object to the other without actually colliding. You can modify the position iterations to adjust this, though turning that up requires more processing power to be used by Box2D and subsequently can have a negative effect on low power devices.