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

Comments

  • 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))
        -- Do your drawing here
    end
    
  • dave1707dave1707 Mod
    Posts: 6,831

    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

  • dave1707dave1707 Mod
    Posts: 6,831

    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))
        -- Do your drawing here
    
    end
    
  • dave1707dave1707 Mod
    Posts: 6,831

    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
        -- Do your drawing here
    
    end
    
  • dave1707dave1707 Mod
    Posts: 6,831

    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
        -- Do your drawing here
    
    end
    

    Would you mind modifying this to do that?

  • dave1707dave1707 Mod
    Posts: 6,831

    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.

  • dave1707dave1707 Mod
    Posts: 6,831

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

  • dave1707dave1707 Mod
    edited January 12 Posts: 6,831

    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

  • dave1707dave1707 Mod
    edited January 4 Posts: 6,831

    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

    Instead of an elastic collision

  • dave1707dave1707 Mod
    edited January 12 Posts: 6,831

    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

  • dave1707dave1707 Mod
    Posts: 6,831

    @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
    
  • dave1707dave1707 Mod
    Posts: 6,831

    @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
          -- 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
    
  • Posts: 50

    Other than the e

  • dave1707dave1707 Mod
    Posts: 6,831
    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
    
Sign In or Register to comment.