OOP 中的物理碰撞检测,对一个对象进行两次迭代

Physics Collision Detection in OOP with two iterations of one object

我在尝试找出游戏机制时遇到了理论写作障碍。基本上,我想让两个圆不断增长,直到它们发生碰撞,当它们发生碰撞时,它们开始缩小,直到它们的半径为 0,然后它们再次开始增长,发生碰撞,等等。

我了解物理碰撞的工作原理,我了解如何使用圆形边界框来检测碰撞。我不明白的是如何创建对象的两次迭代 "circle",并检测同一对象的两次迭代之间的碰撞。如何引用或检测函数中的两个不同圆圈?我也想要这个可扩展的,这样我就可以让 3、4 或更多的圈子相互互动。

如果这没有意义,这是我正在使用的一些代码:

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

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

当点击屏幕时,那里会出现一个半径为 3 的圆。我还没有完全弄清楚如何随着时间的推移增加半径,但这是我可以研究的东西。

这在 Lua 中,但我真的不需要 Lua 中的代码答案。感谢任何指点(呵呵)或帮助。

为什么要用物理学来射击这个?

你有(至少)两个圆圈,这意味着(对于你看到的每一对圆圈)你有两个点 p1, p2 和半径 r1, r2.

取两点之差(pv = p2-p1) 并确定此向量的长度(或 "point difference"):dist = (pv.x2+pv.y2)1/2.如果 r1+r2 ≥ dist,则两个圆重叠——即发生碰撞。


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.

您目前所做的似乎没有任何点或可用的圆圈表示,只有绘制到屏幕上的东西?或者您可能有一个变量存储最近的圈子(而您 "forget" 所有其他人?)

如果是这样的话,那做自己想做的事就不可能了。您需要将圆的坐标、半径和当前状态(增大或缩小)存储在某处,例如在数组中。

create two iterations of an object

是一个完全没有意义的东西。迭代与循环有关。您可能混淆了图层:您所说的 "object" 可能是 class 而您所说的 "iteration" 可能是 对象class?

实例

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

您需要对圈子的信息有一些表示。 (看起来你没有那个。)如果你有那个,那么你只需查看你存储东西的变量(或将你的信息传递给那个函数)。


因为我已经在不久前构建了它,所以这里有一些您可能可以改编的代码:

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

(如果你想 运行 按原样:你需要 love2d,然后只需将上面的内容粘贴到文件 main.lua 和 运行 love . 在该目录中,或者等效地将包含文件夹拖到 love2d 可执行文件或类似的东西上。)