Ball split physics?

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.

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

@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.

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

@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.

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
      -- 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

Other than the e

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
            if t.x>b.x-b.radius*2 and t.x<b.x+b.radius*2 and
                    t.y>b.y-b.radius*2 and t.y<b.y+b.radius*2 then
                vx=b.linearVelocity.x
                vy=b.linearVelocity.y
                b.radius=b.radius/2
                if b.radius<5 then
                    b.radius=5
                end
                tmpx=b.x
                tmpy=b.y
                tmps=b.radius
                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.radius = 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.radius*2)   -- draw balls
    end
    text(1/DeltaTime,WIDTH/2,HEIGHT-25) -- fps
    text(#ballTab,WIDTH/2,HEIGHT-50)    -- number of balls
end