<Updated; summarised to save you having to read down the thread.>
Field effect is an AI pathfinding solution for complex envornments where waypoints will not suffice. it's a way of making AI avoid or be attracted to each other, while avoiding obsticles.
Basically the code works by replicating the universal gravity laws (hence the name field effect, from gravitation fields):
attraction (force in newtons) = -([mass of object 1] * [mass of object 2] * [universal gravity constant]) / ([distance form the two centres]^2)
or: -GMm/r^2, minus being because it is an attractive force
We can modify this slightly. Replace G with an attraction constant. this is how much the ai will be attracted to each other in general.
Now instead of making this a fight between the fattest, I changed the mass to the specific desire for that NPC to take out other NPCs, and then the second mass with the "ugliness", of the second NPC. we'll use r^2 in the same way.
here's the code I came up with, and below is a link to the project I'm using it with. I may write a proper tutorial on this at some point.
REM Project: multiple pf with vectors
REM Created: 03/12/2006 17:33:00
REM
REM ***** Main Source File *****
REM
sync on
randomize timer()
autocam off
global npcs as word
global targets as word
global trees as word
global objpop as word
global time
type entity
x as float
z as float
obj as word
endtype
npcs=100
targets=25
trees=10
makenpcs()
maketrees()
maketargets()
time2=perftimer()/1000
position camera 250,500,250
point camera 250,0,250
global distv
global forcev
distv=1
forcev=2
null=make vector2(distv)
null=make vector2(forcev)
shift_time=timer()
do
time1=perftimer()/1000
time=time1-time2
time2=time1
text 10,10,str$(screen fps())
text 10,30,str$(time)
if shift_time=<timer() then shifttargets() : inc shift_time,1000
updateai()
sync
loop
function makenpcs()
dim npc(npcs-1) as entity
for t=0 to npcs-1
npc(t).x=rnd(500)
npc(t).z=rnd(500)
inc objpop
npc(t).obj=objpop
make object sphere objpop,10
position object objpop,npc(t).x,0,npc(t).z
next t
endfunction
function maketargets()
dim target(targets-1) as entity
for t=0 to targets-1
target(t).x=rnd(50)*10
target(t).z=rnd(50)*10
inc objpop
target(t).obj=objpop
make object cube objpop,10
position object objpop,target(t).x,0,target(t).z
next t
endfunction
function maketrees()
dim tree(trees-1) as entity
for t=0 to trees-1
tree(t).x=rnd(50)*10
tree(t).z=rnd(50)*10
inc objpop
tree(t).obj=objpop
make object cone objpop,20
position object objpop,tree(t).x,10,tree(t).z
next t
endfunction
function updateai()
for t=0 to npcs-1
set vector2 forcev,0,0
obj=npc(t).obj
`avoid other npcs
for s=0 to npcs-1
if t<>s
set vector2 distv, (npc(t).x-npc(s).x), (npc(t).z-npc(s).z)
slv#=squared length vector2(distv)
if slv#<300
force#=800.0/slv#
`normalize vector2 distv,distv
scale vector2 distv,distv,force#
add vector2 forcev,forcev,distv
endif
endif
next s
`avoid to trees
for s=0 to trees-1
set vector2 distv, (npc(t).x-tree(s).x), (npc(t).z-tree(s).z)
slv#=squared length vector2(distv)
if slv#<800
force#=1500.0/slv#
`normalize vector2 distv,distv
scale vector2 distv,distv,force#
add vector2 forcev,forcev,distv
endif
next s
`attract to targets
nrdist=100000000000
for s=0 to targets-1
set vector2 distv, (npc(t).x-target(s).x), (npc(t).z-target(s).z)
slv=squared length vector2(distv)
if slv<nrdist
nrdist=slv
nrtarg=s
endif
next s
set vector2 distv, (npc(t).x-target(nrtarg).x), (npc(t).z-target(nrtarg).z)
force#=-1.0
scale vector2 distv,distv,force#
add vector2 forcev,distv,forcev
`move ai
yrotate object obj,atanfull(x vector2(forcev),y vector2(forcev))
move object obj,0.03*time
npc(t).x=object position x(obj)
npc(t).z=object position z(obj)
next t
endfunction
function shifttargets()
for t=0 to targets-1
target(t).x=rnd(50)*10
target(t).z=rnd(50)*10
position object target(t).obj,target(t).x,0,target(t).z
next t
endfunction
http://forum.thegamecreators.com/?m=forum_view&t=93666&b=32&p=0