@Ignatz Thanks… Here’s some code simulating the problem. Basically it’s Physics Lab gutted for the purpose of illustrating what it’s doing wrong for me.
Basically if you drag the first circle and move it around it will will collide with every other circle except for the one it is directly attached to. If you drag a different circle and attempt to hit other circles you will see varying effects.
I simply want every circle to collide with every other one using a ROPE-like effect.
supportedOrientations(LANDSCAPE_ANY)
function setup()
lineCapMode(ROUND)
debugDraw = PhysicsDebugDraw()
currentTest = Test()
currentTest:setup()
end
function createCircle(x,y,r)
local circle = physics.body(CIRCLE, r)
circle.interpolate = true
circle.type=DYNAMIC
circle.x = x
circle.y = y
circle.restitution = 0.25
circle.sleepingAllowed = false
debugDraw:addBody(circle)
return circle
end
function createGround()
local ground = physics.body(POLYGON, vec2(-50,20), vec2(-50,0), vec2(WIDTH+50,0), vec2(WIDTH+50,20))
ground.type = STATIC
debugDraw:addBody(ground)
return ground
end
function draw()
background(0, 0, 0)
debugDraw:draw()
end
function touched(touch)
debugDraw:touched(touch)
end
PhysicsDebugDraw = class()
function PhysicsDebugDraw:init()
self.bodies = {}
self.joints = {}
self.touchMap = {}
end
function PhysicsDebugDraw:addBody(body)
table.insert(self.bodies,body)
end
function PhysicsDebugDraw:addJoint(joint)
table.insert(self.joints,joint)
end
function PhysicsDebugDraw:draw()
pushStyle()
smooth()
strokeWidth(5)
stroke(128,0,128)
local gain = 2.0
local damp = 0.5
for k,v in pairs(self.touchMap) do
local worldAnchor = v.body:getWorldPoint(v.anchor)
local touchPoint = v.tp
local diff = touchPoint - worldAnchor
local vel = v.body:getLinearVelocityFromWorldPoint(worldAnchor)
v.body:applyForce( (1/1) * diff * gain - vel * damp, worldAnchor)
line(touchPoint.x, touchPoint.y, worldAnchor.x, worldAnchor.y)
end
stroke(0,255,0,255)
strokeWidth(5)
for k,joint in pairs(self.joints) do
local a = joint.anchorA
local b = joint.anchorB
line(a.x,a.y,b.x,b.y)
end
stroke(255,255,255,255)
noFill()
for i,body in ipairs(self.bodies) do
pushMatrix()
translate(body.x, body.y)
rotate(body.angle)
if body.type == STATIC then
stroke(255,255,255,255)
elseif body.type == DYNAMIC then
stroke(150,255,150,255)
elseif body.type == KINEMATIC then
stroke(150,150,255,255)
end
if body.shapeType == POLYGON then
strokeWidth(3.0)
local points = body.points
for j = 1,#points do
a = points[j]
b = points[(j % #points)+1]
line(a.x, a.y, b.x, b.y)
end
elseif body.shapeType == CHAIN or body.shapeType == EDGE then
strokeWidth(3.0)
local points = body.points
for j = 1,#points-1 do
a = points[j]
b = points[j+1]
line(a.x, a.y, b.x, b.y)
end
elseif body.shapeType == CIRCLE then
strokeWidth(3.0)
line(0,0,body.radius-3,0)
ellipse(0,0,body.radius*2)
end
popMatrix()
end
stroke(255, 0, 0, 255)
fill(255, 0, 0, 255)
popStyle()
end
function PhysicsDebugDraw:touched(touch)
local touchPoint = vec2(touch.x, touch.y)
if touch.state == BEGAN then
for i,body in ipairs(self.bodies) do
if body.type == DYNAMIC and body:testPoint(touchPoint) then
self.touchMap[touch.id] = {tp = touchPoint, body = body, anchor = body:getLocalPoint(touchPoint)}
return true
end
end
elseif touch.state == MOVING and self.touchMap[touch.id] then
self.touchMap[touch.id].tp = touchPoint
return true
elseif touch.state == ENDED and self.touchMap[touch.id] then
self.touchMap[touch.id] = nil
return true
end
return false
end
Test= class()
function Test:init()
end
function Test:setup()
createGround()
local circle = createCircle(WIDTH/2, HEIGHT/2, 30)
local circle2 = createCircle(WIDTH/2+70, HEIGHT/2, 30)
local circle3 = createCircle(WIDTH/2+140, HEIGHT/2, 30)
local circle4 = createCircle(WIDTH/2+210, HEIGHT/2, 30)
local circle5 = createCircle(WIDTH/2+280, HEIGHT/2, 30)
local joint = physics.joint(ROPE, circle, circle2, circle.position,circle2.position,150)
debugDraw:addJoint(joint)
local joint = physics.joint(ROPE, circle2, circle3, circle2.position,circle3.position,150)
debugDraw:addJoint(joint)
local joint = physics.joint(ROPE, circle3, circle4, circle3.position,circle4.position,150)
debugDraw:addJoint(joint)
local joint = physics.joint(ROPE, circle4, circle5, circle4.position,circle5.position,150)
debugDraw:addJoint(joint)
end