# Collision code, HELP !!

I want to know how to collide things( for example: when a character collides with a ball then the character goes the other way ).

You can use the physics engine which will calculate everything very close to how it would react in the real world. Check out the physics lab examples to get an idea of how to do this.

For making a character react appropriately to collisions, you often don’t want to use the physics engine, though. Check out the Brickout example for a lesson on how to manually check for collisions and change an objects direction.

Here is a small example to get you started. A lot of this you can ignore, but look at the physics documentation and this example to get an idea of what you need. The best way to learn is to take an example, modify it and see what happens. As always, if you have more questions, we’re all here to help.

``````
function setup()
b=65    -- starting value for letter A

c1 = physics.body(CIRCLE,5)     -- create boundary for the letter
c1.x=295
c1.y=900
c1.restitution=.8
c1.gravityScale=1

c2 = physics.body(CIRCLE,50)    -- create boundary for 1st circle
c2.type=STATIC
c2.x=300
c2.y=600

c3 = physics.body(CIRCLE,50)    -- create boundary for 2nd circle
c3.type=STATIC
c3.x=120
c3.y=400
end

function draw()
a=string.char(b)    -- convert value to a letter

background(30, 30, 30, 25)

stroke(255)
strokeWidth(1)
noFill()
ellipse(c2.x,c2.y,100,100)    -- draw the 1st circle
ellipse(c3.x,c3.y,100,100)    -- draw the 2nd circle

fill(255)
fontSize(30)
text(a,c1.x,c1.y)   -- draw the letter

-- get next letter when previous gets below y position of 20
if c1.y<20 then
c1.y=900
c1.x=295
c1.linearVelocity=vec2(0,0)
b = b + 1
if b>90 then
b=65
end
end
end

``````

@dave1707 Hey thanks a lot Dave! This very short piece of code is really useful for a newbe as myself. Several very short codes like this are better than a big, comprehensive , accurate but … scary piece of code: it shows Codea is really an easy platform and one can quickly have fun with it. Thanks!

@Rakarinn i have made this exemple of colliding particles with two bumpers, right from the exemple of Dave1707, in a couple hours. This is my first Codea program and i am rather proud of the result (remember, i am a newbe, so it doesn’t take much to make me happy!)
@dave1707 As you can see you quick exemple really helped me to go a step further, and really quick! Thanks a lot!

– Collision

function setup()

``````-- create balls
NUMBALLS = 10
SPEED0 = 1000
ball = {}
for i=0,NUMBALLS do
ball[i] = physics.body(CIRCLE,20)
ball[i].x = math.random(WIDTH/2) + WIDTH/4
ball[i].y = math.random(HEIGHT/2) + HEIGHT/4
ball[i].restitution = .9
ball[i].gravityScale = 0
ball[i].linearVelocity=vec2(math.random(SPEED0)-SPEED0/2,math.random(SPEED0)-SPEED0/2)
end

c2 = physics.body(CIRCLE,50)    -- create boundary for 1st circle
c2.type=STATIC
c2.x=WIDTH/3
c2.y=HEIGHT/3
c2.restitution=2

c3 = physics.body(CIRCLE,50)    -- create boundary for 2nd circle
c3.type=STATIC
c3.x=WIDTH/3*2
c3.y=HEIGHT/3
c3.restitution=2

-- create borders
local w = 5
b0 = physics.body(POLYGON, vec2(0,w), vec2(0,0), vec2(WIDTH,0), vec2(WIDTH,w))
b0.type = STATIC
b1 = physics.body(POLYGON, vec2(0,0), vec2(w,0), vec2(w,HEIGHT), vec2(0,HEIGHT))
b1.type = STATIC
b2 = physics.body(POLYGON, vec2(WIDTH - w,0), vec2(WIDTH,0), vec2(WIDTH,HEIGHT), vec2(WIDTH - w,HEIGHT))
b2.type = STATIC
b3 = physics.body(POLYGON, vec2(0,HEIGHT), vec2(0,HEIGHT - w), vec2(WIDTH,HEIGHT - w), vec2(WIDTH,HEIGHT))
b3.type = STATIC
``````

end

function draw()

``````background(30, 30, 30, 25)

stroke(255)
strokeWidth(1)
noFill()
ellipse(c2.x,c2.y,100,100)    -- draw the 1st circle
ellipse(c3.x,c3.y,100,100)    -- draw the 2nd circle

fill(255, 13, 0, 255)
for i=0,NUMBALLS do
ellipse(ball[i].x,ball[i].y,40,40)    -- draw the circle
end
``````

end

Sorry

``````
-- Collision

function setup()

-- create balls
NUMBALLS = 10
SPEED0 = 1000
ball = {}
for i=0,NUMBALLS do
ball[i] = physics.body(CIRCLE,20)
ball[i].x = math.random(WIDTH/2) + WIDTH/4
ball[i].y = math.random(HEIGHT/2) + HEIGHT/4
ball[i].restitution = .9
ball[i].gravityScale = 0
ball[i].linearVelocity=vec2(math.random(SPEED0)-SPEED0/2,math.random(SPEED0)-SPEED0/2)
end

c2 = physics.body(CIRCLE,50)    -- create boundary for 1st circle
c2.type=STATIC
c2.x=WIDTH/3
c2.y=HEIGHT/3
c2.restitution=2

c3 = physics.body(CIRCLE,50)    -- create boundary for 2nd circle
c3.type=STATIC
c3.x=WIDTH/3*2
c3.y=HEIGHT/3
c3.restitution=2

-- create borders
local w = 5
b0 = physics.body(POLYGON, vec2(0,w), vec2(0,0), vec2(WIDTH,0), vec2(WIDTH,w))
b0.type = STATIC
b1 = physics.body(POLYGON, vec2(0,0), vec2(w,0), vec2(w,HEIGHT), vec2(0,HEIGHT))
b1.type = STATIC
b2 = physics.body(POLYGON, vec2(WIDTH - w,0), vec2(WIDTH,0), vec2(WIDTH,HEIGHT), vec2(WIDTH - w,HEIGHT))
b2.type = STATIC
b3 = physics.body(POLYGON, vec2(0,HEIGHT), vec2(0,HEIGHT - w), vec2(WIDTH,HEIGHT - w), vec2(WIDTH,HEIGHT))
b3.type = STATIC
end

function draw()

background(30, 30, 30, 25)

stroke(255)
strokeWidth(1)
noFill()
ellipse(c2.x,c2.y,100,100)    -- draw the 1st circle
ellipse(c3.x,c3.y,100,100)    -- draw the 2nd circle

fill(255, 13, 0, 255)
for i=0,NUMBALLS do
ellipse(ball[i].x,ball[i].y,40,40)    -- draw the circle
end

end

``````

@Jmv38

I’m glad I could help. I find small examples that get to the point are easier to follow and learn from than large ones that do a lot of other things. As you figured out, it doesn’t take a lot of code to do interesting things. If you’re interested in another example along the same line, here is a program I wrote back in June.

``````
-- Random PinBall by Dave1707

function setup()
displayMode(FULLSCREEN)

-- define variables and tables
cx=0
cy=0
limit=150
tab1={}
tab2={}

create()    -- set table values

-- set pinball values
circ1 = physics.body(CIRCLE,5)
circ1.x=300
circ1.y=HEIGHT-50
circ1.gravityScale=.6
circ1.restitution=1

-- set line values
line1 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
line2 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
line3 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
line4 = physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
end

function create()
-- set initial values for pins in tables
for x=1,limit do
tab1[x] = physics.body(CIRCLE,10)
tab1[x].x = math.random(WIDTH)
tab1[x].y = math.random(HEIGHT)
tab1[x].type = STATIC
tab2[x]=0    -- 0=pin not hit, 1=pin was hit
end
end

function collide(contact)
-- check for collision
if contact.state == BEGAN then
cx=contact.bodyA.x    -- x position of hit pin
cy=contact.bodyA.y    -- y position of hit pin
-- restart pinball when at bottom of screen
if circ1.y < 20 then
circ1.y = HEIGHT-50
circ1.x = math.random(WIDTH)
end
end
end

function draw()
background(0, 0, 0)

-- draw pinball
fill(255,0,0,255)
ellipse(circ1.x,circ1.y,10,10)

-- draw boundary lines
line(0,0,0,HEIGHT)
line(WIDTH,0,WIDTH,HEIGHT)
line(0,0,0,WIDTH)
line(0,HEIGHT,WIDTH,HEIGHT)

-- draw flashing pins or white pins each draw cycle
for x=1,limit do
-- check which pin was hit
if cx == tab1[x].x and cy == tab1[x].y then
tab2[x] = 1    -- set table for hit pin
cx=0           -- clear values
cy=0
end

fill(255)                -- set color to white
if tab2[x] > 0 then      -- pin was hit, set random color
fill(math.random(255),math.random(255),math.random(255),255)
end

ellipse(tab1[x].x,tab1[x].y,20)    -- draw pins
end

-- draw credits
fill(0, 252, 0, 255)
text("Random PinBall by Dave1707",WIDTH/2,HEIGHT/2)
end

``````

@dave1707 Thanks! Some more functions i needed are in this exemple, yep!

Lots of helpful stuff here however how would you do a game over screen when object gets hit. Any advice would be appreciated.

@Frazamataza

Not exactly sure what you’re after. Maybe something here will give you an idea.

``````
function setup()
displayMode(FULLSCREEN)
showShip=true
explodeShip=false
endGame=false
x=0
e=30
end

function draw()
background(40, 40, 50)

x = x + 1        -- simulate game

if showShip then
ship()
if x==100 then        -- simulate ship being hit
explodeShip=true
end
end
if explodeShip then
explode()
end
if endGame then
endOfGame()
end

end

function ship()
sprite("SpaceCute:Rocketship",350,500)
end

function explode()
e = e + 2
sprite("Tyrian Remastered:Explosion Huge",350,500,e,e)
if e>500 then
showShip=false
explodeShip=false
endGame=true
end
end

function endOfGame()
fill(255)
fontSize(40)
text("End of Game",WIDTH/2,HEIGHT/1.3)
text("Press New Game for another game",WIDTH/2,HEIGHT/1.5)
fill(255,0,0)
text("NEW GAME",WIDTH/2,HEIGHT/1.8)
end

``````

My program keeps crashing (codea closes) when i try to use the body.info property to store a value like a number or a string. Can someone tell me how to use this property? Thanks
@dave1707 @Simeon

@Jmv38

Body.info uses a table. I don’t think there’s anything that says that, but this example works.

``````
function setup()
tab={"qwerty","asdfg","zxcvb"}

circle = physics.body(CIRCLE,10)
circle.info=tab

print(circle.info)
print()

for x,y in pairs(circle.info) do
print(x,y)
end

end

``````

thanks dave however i was looking for if an object hits something it then explodes and then game over screen. I believe you helped me before on the math.randomseed topic, and this is for that same game I have managed to get it to explode but can not figure out how to then get game over screen. I already have a game over screen just wondering how you get to it. Sorry if I wasn’t clear before.

@dave1707 thanks for this info. @Simeon maybe the fact that body.info is a table should be added in the refrence? Without this information i couldnt make it work. By the way, i have the feeling that in a contact involving contact.bodyA and contact.bodyB, bodyA is always the physics object that was defined first in the code. This is useful to know (if true) because only half the number of tests have to be made during a collision.

As an example for others who need a hand to start with collisions, here is my last version of the code: access to body info, collision management, sounds… Woks nicely.

``````-- Collision

function setup()

-- create balls
NUMBALLS = 10
SPEED0 = 1000
ball = {}
ballInfo = {}
for i=0,NUMBALLS do
ball[i] = physics.body(CIRCLE,20)
ball[i].x = math.random(WIDTH/2) + WIDTH/4
ball[i].y = math.random(HEIGHT/2) + HEIGHT/4
ball[i].restitution = 0.9
ball[i].gravityScale = 0
ball[i].linearVelocity=vec2(math.random(SPEED0)-SPEED0/2,math.random(SPEED0)-SPEED0/2)
ball[i].info = {} -- body.info is a table and has to be initialized otherwise ..bug!
ball[i].info.state = 0
ball[i].info.type = "ball"
end

c2 = physics.body(CIRCLE,50)    -- create boundary for 1st circle
c2.x=WIDTH/3
c2.y=HEIGHT/2
c2.restitution=0.9
c2.gravityScale = 0
c2.info = {}
c2.info.state = 0
c2.info.type = "target"

c3 = physics.body(CIRCLE,50)    -- create boundary for 2nd circle
c3.type=STATIC
c3.x=WIDTH/3*2
c3.y=HEIGHT/2
c3.restitution=4
c3.info = {}
c3.info.state = 0
c3.info.type = "bumper"

-- create borders
local w = 5
b0 = physics.body(POLYGON, vec2(0,w), vec2(0,0), vec2(WIDTH,0), vec2(WIDTH,w))
b0.type = STATIC

b1 = physics.body(POLYGON, vec2(0,0), vec2(w,0), vec2(w,HEIGHT), vec2(0,HEIGHT))
b1.type = STATIC

b2 = physics.body(POLYGON, vec2(WIDTH - w,0), vec2(WIDTH,0), vec2(WIDTH,HEIGHT), vec2(WIDTH - w,HEIGHT))
b2.type = STATIC

b3 = physics.body(POLYGON, vec2(0,HEIGHT), vec2(0,HEIGHT - w), vec2(WIDTH,HEIGHT - w), vec2(WIDTH,HEIGHT))
b3.type = STATIC

end

function collide(contact)
-- check for collision
if contact.state == ENDED then
if contact.bodyA.info.type == "ball" then
if contact.bodyB.info.type == "bumper" then
contact.bodyA.info.state = 1
contact.bodyB.info.state = 1
sound(SOUND_HIT, 2652)
-- print(contact.bodyB.info.type.."  "..contact.bodyA.info.type)
end
if contact.bodyB.info.type == "target" then
contact.bodyA.info.state = 2
sound(SOUND_PICKUP, 2652)
-- print(contact.bodyB.info.type.."  "..contact.bodyA.info.type)
end
end
end
end

function action(obj,val)
-- print("contact: "..obj.info)
end

function draw()

background(30, 30, 30, 25)

stroke(255)
strokeWidth(1)
fill(0, 1, 255, 255)
ellipse(c2.x,c2.y,100,100)    -- draw the 1st circle
-- draw the 2nd circle
fill(255, 222, 0, 255)
if c3.info.state==0 then
ellipse(c3.x,c3.y,100,100)
else
ellipse(c3.x,c3.y,120,120)
c3.info.state = 0
end

for i=0,NUMBALLS do
if ball[i].info.state == 0 then
fill(255, 13, 0, 255)
elseif ball[i].info.state == 1 then
fill(255, 147, 0, 255)
elseif ball[i].info.state == 2 then
fill(255, 0, 236, 255)
end
ellipse(ball[i].x,ball[i].y,40,40)    -- draw the circle
end

end

``````

@Frazamataza

Is this something that you’re after. I added the circles to show you the collision areas. Play around with this to get an idea of what’s happening. There are collisions as soon as the program starts because I set the x,y values for s1, r1, and r2 to the same values in setup.

``````function setup()
x = WIDTH/2
y = HEIGHT/2
c = color(0, 0, 0, 255)
x1=0
y1=0

s1=physics.body(CIRCLE,30)    -- collision area around star
s1.x=x
s1.y=y

r1=physics.body(CIRCLE,90)    -- collision area at back of ship
r1.x=x
r1.y=y

r2=physics.body(CIRCLE,40)    -- collision area at front of ship
r2.x=x
r2.y=y
end

function draw()
background(0, 0, 0, 225)

x1=x1-5
if x1<1 then
rand()
end

sprite("SpaceCute:Star",x1,y1) -- x,y position of star
s1.x=x1    -- x,y position of star collision area
s1.y=y1

sprite("SpaceCute:Rocketship",150,y) -- x,y position of ship
r1.x=100    -- x,y position of both ship collision areas
r1.y=y
r2.x=230
r2.y=y-10    -- -10 to adjust collision area down

-- this just shows collision area circles, to be removed in game
noFill()
stroke(255)
strokeWidth(4)
ellipse(s1.x,s1.y,60,60)
ellipse(r1.x,r1.y,180,180)
ellipse(r2.x,r2.y-10,80,80)    -- -10 to adjust circle down
--
end

function touched(touch)
x = x
y = touch.y
end

function rand()
y1=math.random(100,HEIGHT-100)
x1=WIDTH
end

function collide(contact)
if contact.state == BEGAN then
end
end

``````

On the example that you have where you have the letters bouncing off the balls, how would you code it so you can touch the ball and move it?

Starting here, I have some tutorials on bouncing things with and without physics
http://coolcodea.wordpress.com/2013/03/11/3-moving-an-object-around-the-screen/

. @Andrewsimpson4 I added the touched function so it allows you to move the balls. There are other ways of doing this, but I was in a hurry.

``````
function setup()
b=65    -- starting value for letter A

c1 = physics.body(CIRCLE,5)     -- create boundary for the letter
c1.x=295
c1.y=900
c1.restitution=.8
c1.gravityScale=1

c2 = physics.body(CIRCLE,50)    -- create boundary for 1st circle
c2.type=STATIC
c2.x=300
c2.y=600

c3 = physics.body(CIRCLE,50)    -- create boundary for 2nd circle
c3.type=STATIC
c3.x=120
c3.y=400
end

function draw()
a=string.char(b)    -- convert value to a letter

background(30, 30, 30, 25)

stroke(255)
strokeWidth(1)
noFill()
ellipse(c2.x,c2.y,100,100)    -- draw the 1st circle
ellipse(c3.x,c3.y,100,100)    -- draw the 2nd circle

fill(255)
fontSize(30)
text(a,c1.x,c1.y)   -- draw the letter

-- get next letter when previous gets below y position of 20
if c1.y<20 then
c1.y=900
c1.x=295
c1.linearVelocity=vec2(0,0)
b = b + 1
if b>90 then
b=65
end
end
end

function touched(t)
if math.abs(t.x-c2.x)<50 and math.abs(t.y-c2.y)<50 then
c2.x=t.x
c2.y=t.y
end
if math.abs(t.x-c3.x)<50 and math.abs(t.y-c3.y)<50 then
c3.x=t.x
c3.y=t.y
end
end

``````

Thant you so much one more thing how can I make the circles to a rectangle because the physics.body is still set to CIRCLE and I could not figure out how to change that.

. @Andrewsimpson4 I changed one of the circles to a square so you can compare the code for a circle and a square.

``````
function setup()
b=65    -- starting value for letter A
rectMode(CENTER)

c1 = physics.body(CIRCLE,10)     -- create boundary for the letter
c1.x=295
c1.y=900
c1.restitution=.8
c1.gravityScale=1
c1.sleepingAllowed=false    -- don't let letter sleep

-- create a square physics body
c2 = physics.body(POLYGON,vec2(-50,-50),vec2(-50,50),vec2(50,50),vec2(50,-50))
c2.type=STATIC
c2.x=300
c2.y=600

-- create circle physics body
c3 = physics.body(CIRCLE,50)
c3.type=STATIC
c3.x=120
c3.y=400
end

function draw()
a=string.char(b)    -- convert value to a letter
background(30, 30, 30, 25)

stroke(255)
strokeWidth(2)
noFill()
rect(c2.x,c2.y,100,100)        -- draw square
ellipse(c3.x,c3.y,100,100)     -- draw circle

fill(255)
fontSize(30)
text(a,c1.x,c1.y)   -- draw the letter

-- get next letter when previous gets below y position of 20
if c1.y<20 then
c1.y=900
c1.x=295
c1.linearVelocity=vec2(0,0)
b = b + 1
if b>90 then
b=65
end
end
end

function touched(t)
if math.abs(t.x-c2.x)<50 and math.abs(t.y-c2.y)<50 then
c2.x=t.x
c2.y=t.y
end
if math.abs(t.x-c3.x)<50 and math.abs(t.y-c3.y)<50 then
c3.x=t.x
c3.y=t.y
end
end

``````