@swissolo - yes, the dots should not collide initially with the ring of the same color. Collision just needs to be detected, but nothing should happen until they are inside of the ring. Then they should be trapped.
So this is getting a bit complex. The velocity on the dots to pull them toward the center might be a good option.
First when I set up the objects I allow them to collide for a few frames so that none are overlapping. This prevents the dots from starting inside of any of the rings. This works well.
Then I want to set up the rings so that they repel all dots that aren't the same color, but allow dots of the same color to enter the ring. I can't wrap my head around the collide and category bits to do this. On top of that, what seems to be happening is that even if I set the rings to by static, the dots that collide with the rings move the rings.
I'm still not clear on the usage of
SetSpriteGroup (do I even need this?)
SetSpriteCategoryBits
SetSpriteCollideBits
I'm trying to have 2 Groups
Rings
Dots
I want the rings to collide with all dots that are not the same color and trap dots of the same color within the ring once they are inside of it. They should not collide with the pointer. They should not move when any collision happens. Right now the rings are moving when they collide with dots even though I've changed them from a dynamic body (I initialize them that way so they can prevent overlapping) to a static body. Why are they still reacting like a dynamic body after setting them to static with SetPhysicsOn(ring , 1)? Is it the use of category/collide bits? I guess I could just set the mass of the rings to something ridiculously high... EDIT - tried adding a ton of mass, still can push the rings... EDIT 2 - Had to call SetSpritePhysicsDelete... not sure why you can't just change the darned physics type.
I feel like once I get the groups/categories/collide bits right then I can actually determine the best method for trapping the dots inside of the rings.
First is MakeDots
function MakeDots(iNumber , iClusterFactor , iNumColors)
dim dots[iNumber]
dots[0] = iNumber
h# = -1.0
for i = 1 to iNumber
dots[i] = CloneSprite(gCursorSprite)
SetSpriteVisible(dots[i] , 1)
w# = DOT_WIDTH
SetSpriteSize(dots[i] , w# , -1)
if h# < 0.0
h# = GetSpriteHeight(dots[i])
endif
SetSpriteDepth(dots[i] , 200)
SetSpritePhysicsOn(dots[i] , 2)
SetSpritePhysicsCanRotate( dots[i], 0 )
SetSpritePhysicsDamping( dots[i], 0.5)
SetSpritePhysicsRestitution( dots[i] , 1.0)
SetSpriteGroup(dots[i] , DOT_GROUP)
SetSpriteCategoryBits( dots[i] , %111111) //collide with normal sprites and al in this group
SetSpriteSnap(dots[i] , 1)
color_num = SetRandomColor(dots[i])
//set the collision group for the rings
if color_num = 1
SetSpriteCollideBits( dots[i] , %111011)
elseif color_num = 2
SetSpriteCollideBits( dots[i] , %110111)
elseif color_num = 3
SetSpriteCollideBits( dots[i] , %101111)
elseif color_num = 3
SetSpriteCollideBits( dots[i] , %011111)
endif
//determine x and y
x# = Random(1 , 9900) / 100.0
y# = Random(1 , 9900) / 100.0
for j = 1 to i
while GetSpriteInBox(dots[j] , x# , y# , x# + w# , y# + h#) = 1
x# = x# + 1.0
if x# >= 99.0
y# = y# + 1.0
if y# >= 99.0
y# = 1.0
endif
x# = 1.0
endif
endwhile
next j
SetSpritePosition(dots[i] , x# , y#)
next i
endfunction
Next is MakeRings with initial physics to allow all collision to prevent initial overlapping
function MakeRings()
numRings = GetNumColors()
dim rings[numRings]
rings[0] = numRings
for i = 1 to numRings
if i = 1
color$ = cRED
elseif i = 2
color$ = cGREEN
elseif i = 3
color$ = cBLUE
elseif i = 4
color$ = cPURPLE
endif
if GetSpriteExists(gRingBaseSprite) = 0
if GetImageExists(gRingImg) = 0
gRingImg = LoadImage("ring.png")
endif
gRingBaseSprite = CreateSprite(gRingImg)
thisRing = gRingBaseSprite
else
thisRing = CloneSprite(gRingBaseSprite)
endif
w# = 1.5 * DetermineMaxDotSize(color$)
r# = w# / 2.0
x# = random(ceil(r#) , 100 - ceil(r#))
y# = random(ceil(r#) , 100 - ceil(r#))
SetSpriteSize(thisRing , w# , -1)
SetSpriteDepth(thisRing , 300)
SetSpritePositionByOffset(thisRing , x# , y#)
SetSpritePhysicsOn(thisRing , 2) //should bump all dots out of the bounds of the ring and prevent ring overlap
SetSpriteGroup(thisRing , RING_GROUP)
SetSpriteCategoryBits(thisRing , %111110)
SetSpriteCollideBits(thisRing , %111110)
rings[i] = thisRing
_SetSpriteColor(thisRing , color$)
next i
endfunction
Then after a couple of frames I update the rings physics properties
function UpdateRingPhysics()
//allow dots of the same color to enter the rings all others repel
for i = 1 to rings[0]
ClearSpriteShapes(rings[i])
SetSpritePhysicsOff(rings[i])
SetSpritePhyiscsDelete(rings[i]) //EDIT 2 - this made them so they no longer move...geesh!
SetSpritePhysicsOn(rings[i] , 1)
r# = GetSpriteWidth(rings[i]) / 2.0 - 10.0 * 100.0 / GetDeviceWidth()
SetSpriteShapeCircle(rings[i] , 0 , 0 , r#)
//i is equivalent to the color
if i = 1
SetSpriteCategoryBits(rings[i] , %111110)
SetSpriteCollideBits(rings[i] , %111010)
elseif i = 2
SetSpriteCategoryBits(rings[i] , %111110)
SetSpriteCollideBits(rings[i] , %110110)
elseif i = 3
SetSpriteCategoryBits(rings[i] , %111110)
SetSpriteCollideBits(rings[i] , %101110)
elseif i = 4
SetSpriteCategoryBits(rings[i] , %111110)
SetSpriteCollideBits(rings[i] , %011110)
endif
next i
endfunction
I'm failing at getting the bits right for the categories and collisions.