#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Collision not being detected properly (physics.body and POLYGON)

edited November 2015 Posts: 8

I'm starting a game where balls bounce across the screen, and you have to dodge them. Right now, I am unable to detect a collision against the user-controlled square and the circle. I believe it has to do with my physics.body syntax, specifically with the square (POLYGON). Any pointers?

``````--dodgeball

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
w1=physics.body(EDGE,vec2(0,HEIGHT/4),vec2(WIDTH,HEIGHT/4))
w2=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
b=physics.body(CIRCLE,40)
b.x=WIDTH
b.y=HEIGHT/2
b.restitution=1
b.friction=0
b.linearVelocity=vec2(-(math.random(100,400)),30)
p=40
circnum=0
tx=20
ty=HEIGHT/4
player=physics.body(POLYGON,
vec2(tx, ty),
vec2(tx, ty+30),
vec2(tx+30, ty),
vec2(tx+30, ty+30)
)
player.info="c1"
b.info="c2"
end

function draw()
circnum = circnum +.1
if math.floor(circnum) == 10 then
--[[
b.x=WIDTH
b.y=HEIGHT/2
circnum = 0
ellipse(b.x,b.y,math.random(10,150))
p=math.random(30,60)
--]]
end
stroke(255, 255, 255, 255)
strokeWidth(3)
background(40, 40, 50)
line( 0, HEIGHT/4, WIDTH, HEIGHT/4)
fill(255)
ellipse(b.x,b.y,p)
rect(tx,ty,30)
if o==true then
text("collision",WIDTH/2,HEIGHT/1.5)
end
fontSize(25)
fill(255, 255, 255, 255)
end

function touched(t)
if t.state == BEGAN or t.state == MOVING then
tx=CurrentTouch.x
end
end

function collide(c)
if c.state==BEGAN then
if c.bodyA.info=="c1" and c.bodyB.info=="c2" or c.bodyA.info=="c2" and c.bodyB.info=="c1" then
o=true
print("collision")
end
end
if c.state==ENDED then
if c.bodyA.info=="c1" and c.bodyB.info=="c2" or c.bodyA.info=="c2" and c.bodyB.info=="c1" then
o=false
print("collision ended")
end
end
end
``````
Tagged:

• Posts: 2,020

I'm away from my iPad so I can't run your code, but I think I can see the issues.

Firstly, you haven't assigned a position to the player, like you have with the object `b`, with `b.x =`, `b.y =` etc. It looks as if you want `tx, ty` to be the player's position. Instead of defining the points of the shape in absolute space, define them around `0,0`, eg `vec2(-15,-15), vec2(-15,15), vec2(15,15), vec2(15,-15)`, and then set `player.x, player.y = tx, ty`

Secondly, you're not drawing the player. You would need to have some kind of drawing operation that is reading player.x, .y or .position. I see that you're drawing a rect at `tx, ty`, which are the variables you used to define the player's points, but they won't automatically update to reflect the new position set by the physics engine unless you tell them to. So you could draw the rect at `player.x, player.y`, or update tx,ty to equal player coords.

• Posts: 5,396

From the Box2D docs (Codea uses Box2D)

Game simulation usually generates a sequence of images that are played at some frame rate. This is called discrete simulation. In discrete simulation, rigid bodies can move by a large amount in one time step. If a physics engine doesn't account for the large motion, you may see some objects incorrectly pass through each other. This effect is called tunneling.

By default, Box2D uses continuous collision detection (CCD) to prevent dynamic bodies from tunneling through static bodies. This is done by sweeping shapes from their old position to their new positions. The engine looks for new collisions during the sweep and computes the time of impact (TOI) for these collisions. Bodies are moved to their first TOI and then halted for the remainder of the time step.

Normally CCD is not used between dynamic bodies. This is done to keep performance reasonable. In some game scenarios you need dynamic bodies to use CCD. For example, you may want to shoot a high speed bullet at a stack of dynamic bricks. Without CCD, the bullet might tunnel through the bricks.

Fast moving objects in Box2D can be labeled as bullets. Bullets will perform CCD with both static and dynamic bodies. You should decide what bodies should be bullets based on your game design. If you decide a body should be treated as a bullet, use the following setting.

``````YourBodyName.bullet = true
``````

You can also try

``````physics.continuous=true
``````

Which applies to all physics objects

• Posts: 2,020

Also, assuming you want touch to move the player, you shouldn't move a dynamic physics body by setting its position directly (can especially interfere with collisions). You can either make it kinematic, or, if you want it to remain dynamic, move it by applying forces.

Also, don't use `currentTouch` inside a `touched` function, just use the `t` variable.

eg, if using a force `player:applyForce(vec2(t.deltaX * speed, 0))`

where `speed` is a variable that you can experiment with depending on the mass/ friction of the player, how much you want it to fly around etc.

• Posts: 8,622

@McCann Here's a version. Slide your finger right or left to move the square. I don't know everything you want to do, so this doesn't do much except demo the movement and collision.

``````supportedOrientations(LANDSCAPE_ANY)

function setup()
rectMode(CENTER)
dx=0
w1=physics.body(EDGE,vec2(0,200),vec2(WIDTH,200))
w2=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))

b1=physics.body(CIRCLE,20)
b1.x=WIDTH
b1.y=400
b1.linearVelocity=vec2(-100,50)
b1.restitution=1
b1.info="b1"

p1=physics.body(POLYGON,vec2(-10,10),vec2(-10,-10),vec2(10,-10),vec2(10,10))
p1.x=50
p1.y=250
p1.info="p1"
end

function draw()
background(40, 40, 50)
stroke(255)
strokeWidth(2)
line(0,200,WIDTH,200)
ellipse(b1.x,b1.y,40)
rect(p1.x,p1.y,20,20)
if math.abs(p1.linearVelocity.x)<1 then
dx=0
end
end

function touched(t)
if t.state==MOVING then
dx=dx+t.deltaX
p1.linearVelocity=vec2(dx,0)
end
end

function collide(c)
if c.state==BEGAN then
if c.bodyA.info=="b1" and c.bodyB.info=="p1" or
c.bodyA.info=="p1" and c.bodyB.info=="b1" then
print("collide")
end
end
end
``````