0
votes

I've come across a theoretical writing-block in trying to figure out mechanics for a game. Basically, I want to have two circles that grow until they collide, and when they collide they start to shrink, until their radius is 0, and they start growing again, collide, etc.

I understand how physics collisions work, I understand how to use a circular bounding box to detect a collision. What I don't understand is how I can create two iterations of an object "circle", and detect a collision between the two iterations of the same object. How do I reference or detect the two different circles in a function? I also want this expandable so I can have 3, 4 or many more circles interact with each other.

If that doesn't make sense, here's some code I'm working with:

local function screenTap(event)
    circle = display.newCircle( event.x, event.y, 3)
end

display.currentStage:addEventListener( "tap", screenTap )

When the screen is tapped, a circle appears there with a radius 3. I haven't quite figured out how to grow the radius over time but that's something I can research.

This is in Lua, but I don't really need a code answer in Lua. Any pointers (heh) or help is appreciated.

1

1 Answers

2
votes

Why shoot at this with physics?

You have (at least) two circles, which means that (for each pair of circles that you look at) you have two points p1, p2 and radii r1, r2.

Take the difference of the two points (pv = p2-p1) and determine the length of this vector (or "point difference"): dist = (pv.x2+pv.y2)1/2. If r1+r2 ≥ dist, then the two circles overlap – i.e. there's a collision.


When the screen is tapped, a circle appears there with a radius 3. I haven't quite figured out how to grow the radius over time but that's something I can research.

It seems with what you're doing currently, you don't have any points or usable circle representations, just things that are drawn to the screen? Or maybe you have a single variable that stores the most recent circle (and you "forget" all others?)

If that is the case, then doing what you want to do is impossible. You'll need to store the coordinates, radii and current states (growing or shrinking) of the circles somewhere, e.g. in an array.

create two iterations of an object

is a completely meaningless thing. Iteration has to do with looping. You're probably mixing up layers: What you call "object" is probably a class and what you call "iteration" is an object or an instance of a class?

How do I reference or detect the two different circles in a function?

You need to have some representation of the circle's information. (It seems you don't have that.) If you have that, then you just look at the variable where you stored things (or pass your info to that function).


Because I already built this a while ago, here's some code that you can probably adapt:

SPEED = 40
circles = { }

-- called once per frame (dt is the time since the last frame)
function love.update( dt )
    -- grow/shrink
    for i, circle in ipairs( circles ) do
        local dir = circle.direction == "grow" and 1 or -1 
        circle.r = circle.r + SPEED*dir*dt
        if circle.r <= 0 then
            circle.r, circle.direction = -circle.r, "grow"
        end
    end
    -- collide
    for i, c1 in ipairs( circles ) do
        for j, c2 in ipairs( circles ) do
            if i ~= j then 
                if c1.r + c2.r > ((c2.x-c1.x)^2 + (c2.y-c1.y)^2)^(1/2) then
                    c1.direction, c2.direction = "shrink", "shrink"
                end
            end
        end
    end
end

-- called once per frame, draws the circles
function love.draw( )
    for i, circle in ipairs( circles ) do
        love.graphics.circle( "fill", circle.x, circle.y, circle.r )
    end
end

-- add new circles on click
function love.mousepressed( x, y, btn ) 
    circles[#circles+1] = { x = x, y = y, r = 0, direction = "grow" }
end

-- you can press escape to quit
keys = {
    escape = love.event.quit,
}
function love.keypressed( k )
    local action = keys[k]
    if action then  return action( k )  end
end

(If you want to run this as-is: You'll need love2d, then just paste the above into a file main.lua and run love . in that directory, or equivalently drag the containing folder onto the love2d executable or something like that.)