This is a lame attempt at the Boids thing...sort of works, until they fly
offscreen into a lake of DDT.
There is a logical flaw somewhere... maybe more clear thinkers can divine
the problem given this starting approach/planform though.
Robert
/*
Re:
>' "Spoim", an FB^3 program for Standard Runtime.
rc:
Have you read "Artificial Minds" by Stan Franklin? It's a
fascinating AI book. In the book, there is a program called "boids"
-- no code, just a description. The program goes like this:
'~'8
Place a bunch of points (each point a boid) within the limits of a screen.
'~'8
Have each boid then scan the surrounding area looking for other boids.
'~'8
Then have each boid determine the center of the entire mass of boids.
'~'8
Then have each boid move toward the center, but keeping a specific
distance from other boids.
'~'8
The book describes the resultant act of the program to be that of
birds flying around.
'~'8
*/
' "Boids", FB^3 program for Standard Runtime.
' Robert Covington
' Logical Flaw somewhere....
' (Hide Control Strip if animation is jerky)
_MaxBoids = 40
Begin Record BoidRec
DIM x as double
DIM y as double
End Record
DIM boid(_MaxBoids) as BoidRec
DIM gMassX as double
DIM gMassY as Double
_BoidSpace = 9
DIM gBoidWorld as Long
DIM gScreenGW as Long
DIM gScreenDV as Long
DIM lastTicks as long
DIm gRect as Rect
End Globals
'~'1
'~'1
LOCAL FN MakeLockedGWorld(theRect as Ptr To rect, depth)
dim qdErr
DIM @ myGWorld as long
qdErr = FN NEWGWORLD(myGWorld, depth, #theRect, 0,0,0)
LONG IF (qdErr != _noErr)
if myGWorld then Call DisposeGWorld(myGWorld)
myGWorld = 0
Xelse
long if FN LOCKPIXELS(FN GETGWORLDPIXMAP(myGWorld)) = _false
if myGWorld then Call DisposeGWorld(myGWorld)
myGWorld = 0
end if
End if
END FN = myGWorld
LOCAL FN CopyBlitz(sPort&,dPort&,sRect as ptr,dRect as ptr)
Call ForeColor(_BlackColor)
Call BackColor(_whiteColor)
CALL COPYBITS(#sPort&+2,#dPort&+2,#sRect,#dRect,_srcCopy,0)
END FN
'~'1
'~'1
CLEAR LOCAL
' Wu Pixel approach.
' Brightness of the 4 pixels covered by boid particle
' (top left, top right, bottom left, bottom right)
DIM as Double btl, btr, bbl, bbr
' The fraction part of the coordinates
DIM as Double fx, fy
LOCAL FN DrawBoid(wx as double,wy as double)
' Integer coordinates of Wupixel
DIM x, y
' Calculate the coordinates of the top left pixel
x = FIx(wx) // INT inverts
y = FIX(wy) '
' Calculate the <displacement> from exact integer
fx = wx - x
fy = wy - y
' Calculate the brightness of each of the 4 pixels
' and multiply by the brightness parameter
btl = (1-fx) * (1-fy)
btr = (fx) * (1-fy)
bbl = (1-fx) * (fy)
bbr = (fx) * (fy)
// Dark on Light
btl = 65535-(btl*65535)
btr = 65535-(btr*65535)
bbl = 65535-(bbl*65535)
bbr = 65535-(bbr*65535)
'~'8
'Plot the pixels
'Totality of all 4 = brightness of 1 standard pixel
'~'8
LONG COLOR btl,btl,btl
PLOT x,y
LONG COLOR btr,btr,btr
PLOT x+1,y
LONG COLOR bbl,bbl,bbl
PLOT x,y+1
LONG COLOR bbr,bbr,bbr
PLOT x+1,y+1
END FN
Local
DIM as Double mass
Local FN MassLogic
DIM as long totalX,totalY
DIM j'blue
// Should this be per boid?
gMassX = 0 : gMassY = 0
for j = 0 to _MaxBoids
gMassX = gMassX + boid.x(j)
gMassY = gMassY + boid.y(j)
next j
gMassX = gMassX/_MaxBoids
gMassY = gMassY/_MaxBoids
ENd FN
'~'8
Local
DIM dist as Double
Local FN AvoidDaBoid(thisBoid)
DIM j'blue
// Move toward Center
If boid.x(thisBoid) <= gMassX then boid.x(thisBoid)++ Else boid.x(thisBoid)--
If boid.y(thisBoid) <= gMassY then boid.y(thisBoid)++ Else boid.y(thisBoid)--
FOr j = 0 to _MaxBoids
dist = SQR((boid.x(j)-boid.x(thisBoid))^2 + (boid.y(j)-boid.y(thisBoid))^2)
long if dist < _BoidSpace // Move it away
Long if boid.x(j) - boid.x(thisBoid) <= 0
boid.x(thisBoid) = boid.x(thisBoid) + 1.1
XElse
boid.x(thisBoid) = boid.x(thisBoid) - 1.1
End If
Long if boid.y(j) - boid.y(thisBoid) <= 0
boid.y(thisBoid) = boid.y(thisBoid) + 1.1
XElse
boid.y(thisBoid) = boid.y(thisBoid) - 1.1
End If
End If
next j
End FN
'~'8
Local FN BoidThink(thisBoid)
FN MassLogic
FN AvoidDaBoid(thisBoid)
FN DrawBoid(boid.x(thisBoid) , boid.y(thisBoid) ) 'Draw New Boid
End FN
'~'1
CLEAR LOCAL
DIM adp as double
DIM as Double x,y
LOCAL FN AnimateBoids(theTicks as long)
DIM @tmpWorld as long
DIM @tmpDevice as long
DIM direction
DIM as long j
Long if theTicks-lastTicks > 2
Call getGWorld(tmpWorld,tmpDevice)
Call SetGWorld(gBoidWorld,0)
Call BackColor(_WhiteColor)
cls ' Erase Old
FOR j=0 TO _MaxBoids
FN BoidThink(j)
NEXT j
Call SetGWorld(tmpWorld,tmpDevice)
FN CopyBlitz(gBoidWorld,gScreenGW,gRect,gRect)
lastTicks = theTicks // global lastTicks
End If
END FN
'~'1
CLEAR LOCAL
LOCAL FN loadArray
DIM j
FOR j=0 TO _MaxBoids ' Fill Points array
Boid.x(j) = RND(320)+RND(10)*.1 //Starting X
Boid.y(j) = RND(320)+RND(10)*.1 //Starting Y
FN DrawBoid(Boid.x(j) , Boid.y(j) )
NEXT j
END FN
'~'1
"Main"
DIm Invert,i // Flag
DIM system(400*400*4) // 640 K for GWorld
Call SetRect(gRect,0,0,320,320)
WINDOW 1, "Spoim",@gRect,_docNoGrow
Call GetGworld(gScreenGW,gScreenDV)
gBoidWorld = FN MakeLockedGWorld(gRect,32)
Long if gBoidWorld
FN loadArray
lastTicks = FN TickCount
DO
FN AnimateBoids(FN TickCount)
HandleEvents
UNTIL FN BUTTON OR LEN(INKEY$)// Mouse or Key press
END
Xelse
Stop "Increase Dim System Total"
End If