#### Howdy, Stranger!

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

# Ball split physics?

in General Posts: 50

I want one ball to split into two balls that bounce away from each other if I tap and those balls get split into smaller balls and so on. This is my code

``````function move(cuex,cuey,speedx,speedy)
local p = physics.body(CIRCLE,20)
p.restitution = .8
p.linearVelocity = vec2(speedx,speedy)
p.linearDamping = 0.8
p.x = cuex
p.y= cuey
return p
end
``````

• Posts: 50

Wait sorry this is my code

``````-- Stick Physics

-- Use this function to perform your initial setup
function setup()
physics.gravity(0,-100)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
ball = move(100,300,100,-200, 60)
end
function touched(t)
if t.state == BEGAN then
end
end
function move(posx,posy,speedx,speedy, size)
local p = physics.body(CIRCLE,size)
p.restitution = .8
p.linearVelocity = vec2(speedx,speedy)
p.x = posx
p.y = posy
p.size = size
p.bullet = true
return p
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)
fill(255, 0, 19, 255)
ellipse(ball.x,ball.y,(ball.size*2))
end
``````
• Mod
Posts: 7,749

Do you want each ball to split into 2 only when you tap the screen. When the balls split, do they keep the original size or are the 2 balls half the size of the original ball. If they reduce in size, is there a minimum size where they don’t get smaller.

• Posts: 50

They split into half the size and the minimum size is 5

• Posts: 50

Only when I touch

• Mod
Posts: 7,749

When you create the balls, they should go in a table. When you tap the screen, you loop thru the table and create a new ball for each ball in the table. You reduce the size of the balls.

• Posts: 50

How come this doesn't work?

``````-- Stick Physics

-- Use this function to perform your initial setup
function setup()
physics.gravity(0,-100)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
ball = move(100,300,100,-200, 60)
end
balltable = {ball}
function touched(t)
if t.state == BEGAN then
for i in balltable do
newball = move(i.x,i.y,-10,0)
end
end
end
function move(posx,posy,speedx,speedy, size)
local p = physics.body(CIRCLE,size)
p.restitution = .8
p.linearVelocity = vec2(speedx,speedy)
p.x = posx
p.y = posy
p.size = size
return p
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)
fill(255, 0, 19, 255)
ellipse(ball.x,ball.y,(ball.size*2))

end
``````
• Mod
Posts: 7,749

Your for loop in touched is incorrect. The format is `for a,b in pairs(balltable) do` where a and b are any variable name you want.

• Posts: 50

Why doesn't this work

``````function setup()
physics.gravity(0,-100)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
ball = move(100,300,100,-200, 60)
end
balltable = {ball}
function touched(t)
if t.state == BEGAN then
for a,b in pairs(balltable) do
newball = move(a.x,a.y,-10,0,30)
table.insert(balltable,newball)
end
end
end
function move(posx,posy,speedx,speedy, size)
local p = physics.body(CIRCLE,size)
p.restitution = .8
p.linearVelocity = vec2(speedx,speedy)
p.x = posx
p.y = posy
p.size = size
return p
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)
for a,b in pairs(balltable) do
fill(255, 0, 19, 255)
ellipse(b.x,b.y,(b.size*2))
end

end
``````
• Mod
Posts: 7,749

balltable={ball} should be inside a function, move it up a line after ball=move. The next problem you’re going to run into is in the touched function. As you’re going thru the for loop, you add another ball to the table. You’ll never reach the end of the table. Also, you need to use b as in b.x and b.y in the move() in the touched function. The variable a is just a count, b is the object.

• Posts: 50

How would I modify the first ball to change its size

• Posts: 50

This is what i got but, as you know I want the smaller balls to split into more balls

``````function setup()
physics.gravity(0,-100)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
ball = move(100,300,100,-200, 60)
balltable = {ball}
balls = {ball}
end
function touched(t)
if t.state == BEGAN then
for a,b in pairs(balltable) do
newball = move(b.x+b.size/2,b.y,-100,0,b.size/2)
table.insert(balls,newball)
end
end
end
function move(posx,posy,speedx,speedy, size)
local p = physics.body(CIRCLE,size)
p.restitution = .8
p.linearVelocity = vec2(speedx,speedy)
p.x = posx
p.y = posy
p.size = size
return p
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)
for a,b in pairs(balls) do
fill(255, 0, 19, 255)
ellipse(b.x,b.y,(b.size*2))
end

end
``````

Would you mind modifying this to do that?

• Mod
Posts: 7,749

I don’t think you can. I’ll have to verify that. I think you need to destroy the original ball and create 2 new half sized balls.

• Mod
Posts: 7,749

I checked and what I see is the physics circle has a radius variable. You can modify the value and set the radius.

• Mod
edited January 2018 Posts: 7,749

Here’s a version. Tap the screen to create the first ball then tap again to split them. If you go over 512 balls, the FPS get really low and the program will probably crash.

``````Code removed. See updated code below.
``````
• Posts: 50

is there away for the balls to pass through each other instead of colliding?

• Posts: 50

but not pass through the walls

• Mod
edited January 2018 Posts: 7,749

Yes. Check mask for physics body.

• Posts: 50

But, how do you make them pass through each other after they find another ball physics body

• Posts: 50

• Mod
edited January 2018 Posts: 7,749

Here’s an example that uses the mask and categories for physics objects. Tap the screen to create the first ball, then to split each ball. One split ball will continue in its original path, the other will have its speed and direction varied.

``````Code removed. See updated code below.
``````
• Posts: 50

Now, how do I make it so only when I touch a ball it explodes into two

• Mod
Posts: 7,749

@dmoeller That changes a lot of things. Since you’ll only be splitting 1 ball that’s touched, you won’t need 2 tables anymore. To split a touched ball, in the touched function, when you touch the screen, loop thru the ballTab and see if any ball is within a certain distance of where you touch. If it is, reduce that ball and create a second ball as a temp. Once the loop is finished, add the temp ball to the ballTab. There’s probably more to it, but that should give you an idea.

• Posts: 50

This is my code, why is the table nil? How do I fix my code?

``````displayMode(FULLSCREEN)

function setup()
physics.continuous = true
physics.gravity(0,-100)
ballTab={}
-- objects have a default value for collisions (0 or 1)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
w4 = physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
move(100,300,120,100,0)
end

function touched(t)
if t.state == BEGAN then
for a,b in pairs(ballTab) do
if t.x > b.x-b.size and t.x < b.x+b.size and t.y > b.y-b.size and t.y < b.y+b.size then
if a > 256 then
b:destroy()
else
s=b.size/2
vx=b.linearVelocity.x
vy=b.linearVelocity.y
move(b.x+s,b.y,s,100,vy+100)     -- create 2 balls at half size
move(b.x-s,b.y,s,-100,vy+100)
b:destroy() -- destroy original
end
end
end

end
collectgarbage()
end

function move(posx,posy,size,vx,vy)
local p = physics.body(CIRCLE,size)
p.restitution = 1.01
p.linearVelocity = vec2(vx,vy)
p.x = posx
p.y = posy
p.mask={1}              -- value of object to collide with
p.categories={2}        -- value of this object
if size<5 then
size=5
end
p.size = size
p.bullet = true
p.friction=0
table.insert(ballTab,p)  -- add ball to table
end

function draw()
background(40, 40, 50)
fill(164, 210, 223, 255)
for a,b in pairs(ballTab) do
ellipse(b.x,b.y,b.size*2)   -- draw balls
end
text(1/DeltaTime,WIDTH/2,HEIGHT-25) -- fps
text(#ballTab,WIDTH/2,HEIGHT-50)    -- number of balls
end
``````
• Mod
Posts: 7,749

@dmoeller You have a problem in the touched function. While you’re in the for loop of ballTab, you’re calling the move function twice which adds two balls to the ballTab that you’re looping thru. You have to create 2 temporary balls that you add to the ballTab after you’re done with the for loop.

• Posts: 50

Why doesn't this work

``````displayMode(FULLSCREEN)

function setup()
physics.continuous = true
physics.gravity(0,-100)
ballTab={}
-- objects have a default value for collisions (0 or 1)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
w4 = physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
p1 = move(100,300,120,100,0)
table.insert(ballTab, p1)
end

function touched(t)
if t.state == BEGAN then
for a,b in pairs(ballTab) do
if t.x > b.x-b.size and t.x < b.x+b.size and t.y > b.y-b.size and t.y < b.y+b.size then
if a > 256 then
b:destroy()
else
s=b.size/2
vx=b.linearVelocity.x
vy=b.linearVelocity.y
ball1 = move(b.x+s,b.y,s,100,vy+100)     -- create 2 balls at half size
ball2 = move(b.x-s,b.y,s,-100,vy+100)
b:destroy() -- destroy original
end
end
end
table.insert(ballTab, ball1)
table.insert(ballTab, ball2)
end
collectgarbage()
end

function move(posx,posy,size,vx,vy)
local p = physics.body(CIRCLE,size)
p.restitution = 1.01
p.linearVelocity = vec2(vx,vy)
p.x = posx
p.y = posy
p.mask={1}              -- value of object to collide with
p.categories={2}        -- value of this object
if size<5 then
size=5
end
p.size = size
p.bullet = true
p.friction=0
return p
end

function draw()
background(40, 40, 50)
fill(164, 210, 223, 255)
for a,b in pairs(ballTab) do
ellipse(b.x,b.y,b.size*2)   -- draw balls
end
text(1/DeltaTime,WIDTH/2,HEIGHT-25) -- fps
text(#ballTab,WIDTH/2,HEIGHT-50)    -- number of balls
end
``````
• Posts: 50

Other than the e

• Mod
Posts: 7,749
``````displayMode(FULLSCREEN)

function setup()
physics.continuous=true
physics.gravity(0,0)
ballTab={}
-- objects have a default value for collisions (0 or 1)
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
w4 = physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
move(100,300,120,math.random(-250,250),math.random(-250,250))
end

function touched(t)
if t.state == BEGAN then
tmpx,tmpy=0,0
for a,b in pairs(ballTab) do
vx=b.linearVelocity.x
vy=b.linearVelocity.y
end
tmpx=b.x
tmpy=b.y
tmpvx=vx+math.random(-250,250)
tmpvy=vy+math.random(-250,250)
end
end
if tmpx+tmpy>0 then
move(tmpx,tmpy,tmps,tmpvx,tmpvy)
end
end
end

function move(posx,posy,size,vx,vy)
local p = physics.body(CIRCLE,size)
p.restitution = 1
p.linearVelocity = vec2(vx,vy)
p.x = posx
p.y = posy
p.mask={1}              -- value of object to collide with
p.categories={2}        -- value of this object
if size<5 then
size=5
end
p.bullet = true
p.friction=0
table.insert(ballTab,p)  -- add ball to table
end

function draw()
background(40, 40, 50)
fill(164, 210, 223, 255)
for a,b in pairs(ballTab) do