[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]

## How can I detect object collision without physics? Started by amar.masic6 Oct 30 2018 04:54 AM

7 replies to this topic
collision

Best Answer davebollinger , 30 October 2018 - 07:09 AM

you'll need an overlap test.  here's one:

```--- pass me two rects and i'll return boolean true/false if they overlap
function overlap(a,b)
a, b = a.contentBounds, b.contentBounds
return (a.xMin <= b.xMax) and (a.xMax >= b.xMin) and (a.yMin <= b.yMax) and (a.yMax >= b.yMin)
end
```

but i'd also suggest you restructure some other things too.  you can consider it optional, but it'll make your life easier going forward.

first, let's give the player a "move" method.  insert this code after creating player:

```player.move = function(self,dx,dy)
self.x = self.x + dx
self.y = self.y + dy
-- self:collide() -- haven't written this yet, but this is where it'll go
end
```

then for your arrow taps, reword them to each use that move method:

```leftArrow:addEventListener("tap", function() player:move(-5,0) end)
```

then, create an array to hold all your blocks so it'll be easier to loop through them:

```local blocks = {}
blocks[#blocks+1] = display.newRect(x,y,w,h)
end
addBlock(centerX, centerY - 50, 100, 220)
-- etc, add all the other blocks similarly
```

... now, finally!, you're set up to write the collide function for the player, fe:

```player.collide = function(self)
for _,block in pairs(blocks) do
if (overlap(self,block)) then
block:setFillColor(1,0,0) -- do "something" in response to the collision, up to you
end
end
end

```

then uncomment that call to collide inside move() and you should be good!

NOTE:  the code above is just to give you all the ideas, it's still up to you to implement them properly.  fe, if you just copy/paste the code here as is, rather than thinking about it how it all should fit together, then you may have scope issues (for example the player methods might not know what the "blocks" array is if it's defined later), so make sure you put things in a logical order.

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

### amar.masic6

[GLOBAL: userInfoPane.html]
amar.masic6
• Observer

• 8 posts
• Corona SDK

All I have in my game is a player, which is this:

```local player = display.newRect(30, centerY - 20, 20, 20)
player:setFillColor(0.5)```

Movement buttons, which are these:

```local upArrow = display.newImage("arrows/up.png", 50, centerY + 30)
local downArrow = display.newImage("arrows/down.png", 50, centerY + 130)
local rightArrow = display.newImage("arrows/right.png", 100, centerY + 80)
local leftArrow = display.newImage("arrows/left.png", 0, centerY + 80)
```

They work like this:

```function moveUp( event )
player.y = player.y - 5
end

And I have objects that I named blocks(which are these white "walls"):

```local block1 = display.newRect(centerX, centerY - 50, 100, 220)
local block2 = display.newRect(centerX + 125, centerY + 135, 350, 80)
local block3 = display.newRect(centerX + 188, centerY + 45, 200, 100)
local block4 = display.newRect(centerX + 100, centerY - 100, 100, 125)
local block5 = display.newRect(centerX + 240, centerY - 50, 100, 100)
local block6 = display.newRect(centerX + 230, centerY - 160, 160, 50)```

How could I detect the player hitting one of these blocks?

#### Attached Files

[TOPIC: post.html]
#2

### XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
• Contributor

• 842 posts
• Corona SDK

You could write an enterframe function that compares the player's coordinates to those blocks. This kind of comparison would be easiest done if those blocks were in a table.

At its simplest, you know that the player is touching a block if the player's coordinates are located within a block. However, since your player is not 1 pixel by 1 pixel in size, you need to take its dimensions into account as well.

If you create an enterframe function that loops through each block, all you'd need to do is check if the player's x coordinates +/- half of its width are within a block's coordinates +/- half of the block's width, and same for the y values and the objects' heights.

You can (and should) add checks to the enterframe function to reduce the number of necessary calculations. For instance, first check to see only if a player is within the x bounds of a block. If it isn't, then the y bounds don't matter, etc. Depending on how you implement this system, there are numerous other means of improving its performance.

[TOPIC: post.html]
#3

### davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
• Corona Geek

• 1,348 posts
• Enterprise

you'll need an overlap test.  here's one:

```--- pass me two rects and i'll return boolean true/false if they overlap
function overlap(a,b)
a, b = a.contentBounds, b.contentBounds
return (a.xMin <= b.xMax) and (a.xMax >= b.xMin) and (a.yMin <= b.yMax) and (a.yMax >= b.yMin)
end
```

but i'd also suggest you restructure some other things too.  you can consider it optional, but it'll make your life easier going forward.

first, let's give the player a "move" method.  insert this code after creating player:

```player.move = function(self,dx,dy)
self.x = self.x + dx
self.y = self.y + dy
-- self:collide() -- haven't written this yet, but this is where it'll go
end
```

then for your arrow taps, reword them to each use that move method:

```leftArrow:addEventListener("tap", function() player:move(-5,0) end)
```

then, create an array to hold all your blocks so it'll be easier to loop through them:

```local blocks = {}
blocks[#blocks+1] = display.newRect(x,y,w,h)
end
addBlock(centerX, centerY - 50, 100, 220)
-- etc, add all the other blocks similarly
```

... now, finally!, you're set up to write the collide function for the player, fe:

```player.collide = function(self)
for _,block in pairs(blocks) do
if (overlap(self,block)) then
block:setFillColor(1,0,0) -- do "something" in response to the collision, up to you
end
end
end

```

then uncomment that call to collide inside move() and you should be good!

NOTE:  the code above is just to give you all the ideas, it's still up to you to implement them properly.  fe, if you just copy/paste the code here as is, rather than thinking about it how it all should fit together, then you may have scope issues (for example the player methods might not know what the "blocks" array is if it's defined later), so make sure you put things in a logical order.

[TOPIC: post.html]
#4

### Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
• Moderator

• 25,925 posts
• Enterprise

[TOPIC: post.html]
#5

### amar.masic6

[GLOBAL: userInfoPane.html]
amar.masic6
• Observer

• 8 posts
• Corona SDK

I'm just wondering how isn't there a function or something to check for collision in Corona, it seems like a such a simple thing, but I guess it's not.

[TOPIC: post.html]
#6

### Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
• Moderator

• 25,925 posts
• Enterprise

Corona has collision detection support, but it's part of the physics engine.

Rob

[TOPIC: post.html]
#7

### davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
• Corona Geek

• 1,348 posts
• Enterprise

I'm just wondering how isn't there a function or something to check for collision in Corona, it seems like a such a simple thing, but I guess it's not.

as Rob said, if you want full collision (contact detection and dynamics response) then physics lib, easy

but if you just want overlap testing, then DIY.  still easy, no big deal -- axis-aligned-rect-vs-rect overlap algorithm has been around since at least early 70's "Pong" and hasn't changed a bit since (SAT as proof that 4 tests suffice), so just grab the "one-liner" above and done. :)

[TOPIC: post.html]
#8

### XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
• Contributor

• 842 posts
• Corona SDK

Collision detection for all simple convex and concave polygons is also easily doable without physics.

[topic_controls]

[/topic_controls]