Some LUA collision detection code for you all.

The code at the following link (http://pastebin.com/3BwbxLjn) has routines for:

  • Point in rectangle = pointInRect( pX, pY, rLeft, rTop, rWidth, rHeight )

  • Point in circle = pointInCircle( pX, pY, cX, cY, cRadius )

  • Point in diamond = pointInDiamond( pX, pY, dX, dY, dSize )

  • Rectangle in rectangle = rectInRect( r1Left, r1Top, r1Width, r1Height, r2Left, r2Top, r2Width, r2Height )

  • Circle in circle = circleInCircle( c1X, c1Y, c1Radius, c2X, c2Y, c2Radius )

  • Diamond in diamond = diamondInDiamond( d1X, d1Y, d1Size, d2X, d2Y, d2Size )

  • Two rectangles intersecting = intersectRects( r1Left, r1Top, r1Width, r1Height, r2Left, r2Top, r2Width, r2Height )

  • Two circles intersecting = intersectCircles( c1X, c1Y, c1Radius, c2X, c2Y, c2Radius )

  • Two diamonds intersecting = intersectDiamonds( d1X, d1Y, d1Size, d2X, d2Y, d2Size )

  • A rectangle intersecting a circle = intersectRectWithCircle( rLeft, rTop, rWidth, rHeight, cX, cY, cRadius )

  • A rectangle intersecting a diamond = intersectRectWithDiamond( rLeft, rTop, rWidth, rHeight, dX, dY, dSize )

I hope the parameters you have to pass are obvious!
In the case of circles and diamonds, the X and Y values you pass are of the center of the shape.

In all cases the routines return TRUE to touching results, eg if you pass a point that is on the edge of a rectangle to pointInRect(), then it will return true.
And what is a diamond in my routines? It is a rectangle rotated 45 degrees. Why do I have it? Because it is the simplest and therefore the fastest shape to do a collision test on.

The way to use the code is to stick the pastebin contents into a new lua file, called something appropriate, then require() that file in your own code. Then you call the routines with the . operator, so you might have something like:

local collisions = require( “collisions” )
local isInside = collisions.pointInCircle( 0, 0, 0, 5, 10 )

etc.

http://pastebin.com/3BwbxLjn

Have fun and let me know of any bugs, I haven’t actually tested some of the routines (copy and paste and tweaks) but it *should* be fine. Famous last words, right? [import]uid: 46639 topic_id: 26882 reply_id: 326882[/import]

Thanks for sharing!

Could you also post it up here: http://developer.anscamobile.com/code/ [import]uid: 84637 topic_id: 26882 reply_id: 109101[/import]

Of course I immediately messed up and posted an old, non-working version, but the one online now *DOES* work, hurrah! [import]uid: 46639 topic_id: 26882 reply_id: 109105[/import]

@Danny - I could, now I know it exists :slight_smile: [import]uid: 46639 topic_id: 26882 reply_id: 109108[/import]

Please do, will be easier to reference and im sure many many people will find this extremely useful.

:slight_smile: [import]uid: 84637 topic_id: 26882 reply_id: 109110[/import]

Done. Just hope the code actually works. I’ll probably try to knock up a full demo to check and show people how it works. [import]uid: 46639 topic_id: 26882 reply_id: 109124[/import]

If you find the time to do that I’m sure a lot of people would appreciate it :slight_smile: [import]uid: 84637 topic_id: 26882 reply_id: 109125[/import]

Great stuff, thanks for posting this.

I feel loading physics, just to do collision detection is over kill, and may cause more problems than it solves.

The shapes presented here can cover a wide range of objects in a classic arcade style shooter. [import]uid: 98652 topic_id: 26882 reply_id: 109131[/import]

@Danny, I’ve also just done a small demo project so people can visualise things, but there’s no mechanism I’m aware of for making it available to people via this site. Any ideas what I can do about that? [import]uid: 46639 topic_id: 26882 reply_id: 109138[/import]

@Rakoonic: Post it here: http://developer.anscamobile.com/code/

With either a link to the github project (then the users can directly download it) or simply post a link in the description.
[import]uid: 84637 topic_id: 26882 reply_id: 109187[/import]

OK I *hope* this is what you meant - new to GitHub so bear with me:

https://github.com/Rakoonic/Corona-collision-shapes [import]uid: 46639 topic_id: 26882 reply_id: 109255[/import]

Exactly.

Now post it here: https://developer.anscamobile.com/admin/node/add/code-library

(Your github link goes in the second field.

Then just fill out the title and description :slight_smile: [import]uid: 84637 topic_id: 26882 reply_id: 109259[/import]

But won’t that add in a duplicate entry for the one I did yesterday? I was looking for a way to edit it but I couldn’t see one, so just stuck the link in the comments. [import]uid: 46639 topic_id: 26882 reply_id: 109261[/import]

If you post the link to the old one I can edit it for you :slight_smile: [import]uid: 84637 topic_id: 26882 reply_id: 109270[/import]

I already have two pretty reliable are two rect’s overlapping and are two circles overlapping code, but it doesn’t work well if it’s not center reference point.

Clearly having these other options (point in, diamonds etc.) is going to make life much much easier.

I have always believed that using Physics just for collision detection was wasteful and overly complex. The problem is everyone here seems to understand the Corona event model better than they do using a Runtime:addEventListener(“enterFrame”, function) handler for a game loop that has to do the collision detection, though the latter is at least as efficient and at least as fast (if not more efficient and faster)

In addition if you’re doing something like a card game, or Word with Friends where you need to drag something to another location, trying to get Physics working with non-dynamic objects for collision detection is a nightmare.

I for one stand in applause for this!!!

Though perhaps you could provide wrapper functions that let you pass in display objects and have it calculate the various points needed and/or be center reference point friendly for the rectangles.

Then your code would turn from:

if intersectRects( target.x - target.width/2, target.y - target.height /2, target.width, target.height, dest.x - dest.width / 2, dest.y - dest.height / 2, dest.width, dest.height ) then …

to

if inersectRectObjects(target,dest) then

just a thought.
[import]uid: 19626 topic_id: 26882 reply_id: 109281[/import]

@Danny: http://developer.anscamobile.com/code/simple-shape-collision-routines

@robmiracle: Not a bad idea actually. The only reason I didn’t do that in the first place is I always keep my graphics and my collision routines apart. I’ll be travelling until early next week but if I get time I might look into it. What I’d do is accept any table as a ‘shape’, and treat it as a rectangle (IE use the x, y, width and height properties) unless it also contains a ‘shape’ key, which would naturally be “rectangle”, “circle” or “diamond”, with the latter 2 needing a “radius” key instead of width and height.

Would that seem to make sense?

OK I am being an idiot really, since you would not need to specify the shape, as the shape is explicit from the collision routine you call. Doh! [import]uid: 46639 topic_id: 26882 reply_id: 109309[/import]

You might also want to use a reduced rectangle or other shape in some cases. Imagine you have a sprite with some shape bounds that cover some blank area. You might want to define your own rectangle or bounds for that shape is a little smaller than the actual shape.

Of course using objects vs coordinates is not a hard change to make.

Actually seems like, if this were to act as library, you’d want BOTH options. Something like:

[lua]pointInRect( pX, pY, rLeft, rTop, rWidth, rHeight )[/lua]

and

[lua]pointInRectObj( pX, pY, obj )[/lua]

Then of course internally the second could call the first after it figured the width and height from the object. [import]uid: 98652 topic_id: 26882 reply_id: 109313[/import]

Well I don’t really see the point in having more than 1 routine - it is easy enough to have it work out if individual values or table objects were passed, I just check the type() if the first couple of parameters, making it easier for everyone :slight_smile: [import]uid: 46639 topic_id: 26882 reply_id: 109314[/import]