Sorry for the slight messiness. Here is a basic draft of the chase and evade ai. Blue squares are Civilians, red are Aliens. You can spawn and place as many as you want to test.
For now, once an alien hits the civilian, the civilian is dead and stops moving.
Is this the kind of behavior that we want to see (obviously, aliens will eventually carry humans away) or do they seem like they aren't moving in a realistic fashion?
Let me know what you think as the next steps build off of this.
REM First: Each object needs an entity number
REM It is assumed that entities will exist within a given number range. For now: 1000-2000
DIM Constants(10)
EntityStart=1
EntityEnd=2
Constants(EntityStart)=1000
Constants(EntityEnd)=2000
dim civs(1)
REMSTART
Class Entities
Status - Alive(1)/Unspawned(0)/Dead(-1)
Position(3) - Stores Position Data
Speed - Stores the magnitude of the person's velocity
Angle(3) - Stores the x,y,and z angles of the object (in this case, only 1 axis will be used)
SpeedMax - Stores the MAXIMUM allowable speed
Acceleration - Stores the acceleration (scalar)
ActionRange - Stores The max range of action (attack/kidnap)
ActionAngle - Stores the max angle of action (assumed to be in XZ plane centered on heading vector)
Team - Stores Which team the entity is on (Friendly, Neutral, Hostile)
AI Subset
AI Data (waypoint, home, etc)
REMEND
EntRange=Constants(EntityEnd)-Constants(EntityStart)
DIM Entities_ObjNum(EntRange)
DIM Entities_Status(EntRange)
DIM Entities_Position#(EntRange,3)
DIM Entities_Speed#(EntRange)
DIM Entities_SpeedMAX#(EntRange)
DIM Entities_Angle#(EntRange,3)
DIM Entities_Acceleration#(EntRange)
DIM Entities_Team(EntRange)
DIM Entities_ActionRange(EntRange)
DIM Entities_ActionAngle(EntRange)
DIM Entities_Ai(EntRange)
DIM Entities_Data(EntRange)
CLS RGB(63,63,63)
REM Simulation 1: Evade stationary
REM Make 1 alien (red) and 1 civilian (blue)
Civ=SpawnEntity(2,#(300),.,#(240))
Civ2=SpawnEntity(2,#(300),.,#(260))
Civ3=SpawnEntity(2,#(320),.,#(240))
Civ4=SpawnEntity(2,#(320),.,#(260))
civs(1)=4
Aln=SpawnEntity(3,#(200),.,#(200))
` Aln2=SpawnEntity(3,#(500),.,#(100))
` Aln3=SpawnEntity(3,#(500),.,#(400))
` Aln4=SpawnEntity(3,#(300),.,#(50))
Entities_SetSpeedMax(Aln,6.)
Entities_SetAcceleration(Aln,.2)
Entities_SetSpeedMax(Aln2,6.)
Entities_SetAcceleration(Aln2,.2)
Entities_SetSpeedMax(Aln3,6.)
Entities_SetAcceleration(Aln3,.2)
Entities_SetSpeedMax(Aln4,6.)
Entities_SetAcceleration(Aln4,.2)
Entities_SetSpeed(Civ,3.)
Entities_SetAngle(Civ,.,.,.)
Entities_SetAcceleration(Civ,.1)
Entities_SetSpeed(Civ2,3.)
Entities_SetAngle(Civ2,.,45.,.)
Entities_SetAcceleration(Civ2,.1)
Entities_SetSpeed(Civ3,3.)
Entities_SetAngle(Civ3,.,135.,.)
Entities_SetAcceleration(Civ3,.1)
wait key
sync on : sync rate 0
Draw_Heading(Civ)
DO
TEXT 50,0,STR$(civs(1))
FOR I=1 to Entities_Status(0)
IF Entities_Status(I)<>0
Entities_Move(I)
ENDIF
NEXT I
Draw_Heading(Civ)
SYNC
cls
LOOP
END
FUNCTION SpawnEntity(type,x#,y#,z#)
EntNum=GetEntityNumber()
REM Set the Entity to Alive
Entities_Status(EntNum)=1
REM Set the Entity Type
Entities_Team(EntNum)=type
REM Generate/Load As Appropriate
SELECT type
CASE 1 : ENDCASE : REM Friendly
CASE 2 : GenerateCivilian(EntNum) : ENDCASE : REM Neutral
CASE 3 : GenerateAlien(EntNum) : ENDCASE : REM Enemy
ENDSELECT
REM Position Entity
Entities_SetPosition(EntNum,x#,y#,z#)
Entities_SetSpeedMax(EntNum,3.)
Entities_Status(0)=EntNum
ENDFUNCTION EntNum
FUNCTION KillEntity(EntNum)
Entities_Status(EntNUm)=-1
civs(1)=civs(1)-1
ENDFUNCTION
Function #(a)
ret#=(a+.)
ENDFUNCTION ret#
REM Entity Controls
FUNCTION Entities_SetPosition(EntNum,x#,y#,z#)
IF x#<0 then X#=0
IF x#>620 then x#=620
IF Z#<0 then Z#=0
IF Z#>460 then z#=460
Entities_Position#(EntNum,1)=x#
Entities_Position#(EntNum,2)=y#
Entities_Position#(EntNum,3)=z#
` SPRITE EntNum,x#,z#,EntNum
PASTE IMAGE EntNum,x#,z#
ENDFUNCTION
FUNCTION Entities_SetSpeed(EntNum,speed#)
Entities_Speed#(EntNum,1)=speed#
ENDFUNCTION
FUNCTION Entities_SetSpeedMax(EntNum,speed#)
Entities_SpeedMAX#(EntNum,1)=speed#
ENDFUNCTION
FUNCTION Entities_SetAngle(EntNum,x#,y#,z#)
Entities_Angle#(EntNum,1)=x#
Entities_Angle#(EntNum,2)=y#
Entities_Angle#(EntNum,3)=z#
ENDFUNCTION
FUNCTION Entities_SetAcceleration(EntNum,acc#)
Entities_Acceleration#(EntNum)=acc#
ENDFUNCTION
REM END CONTROL FUNCTIONS
REM Manipulation FUNCTIONS
FUNCTION Entities_Move(EntNum)
Px#=Entities_Position#(EntNum,1) : Py#=Entities_Position#(EntNum,2) : Pz#=Entities_Position#(EntNum,3)
IF Entities_Status(EntNum)=1
REM Apply Acceleration
Entities_Speed#(EntNum)=Entities_Speed#(EntNum)+Entities_Acceleration#(EntNum)
IF Entities_Speed#(EntNum)>Entities_SpeedMAX#(EntNum) then Entities_Speed#(EntNum)=Entities_SpeedMAX#(EntNum)
REM Decompose Speed and Angle Into Components. Note: Only Z axis is used. Extra math included for completeness
REM If drifting is a possibility (rare case), then the various components would be used for lx#,ly#,lz#
nu#=Entities_Angle#(EntNum,1) : theta#=Entities_Angle#(EntNum,2) : phi#=Entities_Angle#(EntNum,3)
R00#=cos(theta#)*cos(phi#) : R01#=(sin(nu#)*sin(theta#)*cos(phi#))-(cos(nu#)*sin(phi#)) : R02#=(cos(nu#)*sin(theta#)*cos(phi#))+(sin(nu#)*sin(phi#))
R10#=cos(theta#)*sin(phi#) : R11#=(sin(nu#)*sin(theta#)*sin(phi#))+(cos(nu#)*cos(phi#)) : R12#=(cos(nu#)*sin(theta#)*sin(phi#))-(sin(nu#)*cos(phi#))
R20#=0-sin(theta#) : R21#=sin(nu#)*cos(theta#) : R22#=cos(nu#)*cos(theta#)
lx#=Entities_Speed#(EntNum)
ly#=0
lz#=0
Vx#=(R00#*lx#)+(R01#*ly#)+(R02#*lz#)
Vy#=(R10#*lx#)+(R11#*ly#)+(R12#*lz#)
Vz#=(R20#*lx#)+(R21#*ly#)+(R22#*lz#)
For I=1 to Entities_Status(0)
IF Entities_Status(I)>0
IF Entities_Team(EntNum)=1 OR Entities_Team(EntNum)=3
`Friendly Fighter Or Alien
`Lvl 1 Attract Alien, Level 2 Attract for friendly
IF Entities_Team(EntNum)<>Entities_Team(I)
CalcAttract#(EntNum,I)
ELSE
ENDIF
ELSE
`Civilian
IF Entities_Team(I)=3
CalcRepulsion#(EntNum,I)
ENDIF
ENDIF
ENDIF
NEXT I
ELSE
Vx#=0 : Vy#=0 : Vz#=0
ENDIF
Entities_SetPosition(EntNum,Px#+Vx#,Py#+Vy#,Pz#+Vz#)
ENDFUNCTION
FUNCTION GetEntityNumber()
inc i
RetVal=i
ENDFUNCTION RetVal
FUNCTION GenerateCivilian(ImgNum)
IF Bitmap Exist(1) then delete bitmap 1
Create Bitmap 1,10,10
CLS RGB(0,0,255)
Get Image ImgNum,0,0,9,9
DELETE Bitmap 1
ENDFUNCTION
FUNCTION GenerateAlien(ImgNum)
IF Bitmap Exist(1) then delete bitmap 1
Create Bitmap 1,10,10
CLS RGB(255,0,0)
Get Image ImgNum,0,0,9,9
DELETE Bitmap 1
ENDFUNCTION
FUNCTION CalcRepulsion#(Ent1,Ent2)
Px1#=Entities_Position#(Ent1,1) : Py1#=Entities_Position#(Ent1,2) : Pz1#=Entities_Position#(Ent1,3)
Px2#=Entities_Position#(Ent2,1) : Py2#=Entities_Position#(Ent2,2) : Pz2#=Entities_Position#(Ent2,3)
theta#=Entities_Angle#(Ent1,2)
Vx#=sin(theta#)*Entities_Speed#(Ent1)
Vy#=0
Vz#=cos(theta#)*Entities_Speed#(Ent1)
dist#=((px2#-px1#)^2+(py2#-py1#)^2+(pz2#-pz1#)^2)^.5
ang1#=atanfull(px2#-px1#,pz2#-pz1#)
IF dist#<>0
repulse#=10./((dist#))
ELSE
repulse#=0
ENDIF
rx#=0-repulse#*cos(ang1#)
rz#=repulse#*sin(ang1#)
Vx#=Vx#-rx# : Vz#=Vz#-Rz#
`Second Part: Vy=0
ang#=atanfull(Vx#,Vz#)
V#=((vx#^2)+(vz#^2))^.5
Entities_SetSpeed(Ent1,V#)
Entities_SetAngle(Ent1,.,Ang#,.)
` wait key
ENDFUNCTION
FUNCTION Draw_Heading(EntNum)
r#=20
Ink 65535,RGB(63,63,63)
X=Entities_Position#(EntNum,1) : Y=Entities_Position#(EntNum,3)
X2#=r#*cos(Entities_Angle#(EntNum,2)) : Y2#=r#*(0-sin(Entities_Angle#(EntNum,2)))
Line X,Y,X+X2#,Y+Y2#
ENDFUNCTION
FUNCTION CalcAttract#(Ent1,Ent2)
Px1#=Entities_Position#(Ent1,1) : Py1#=Entities_Position#(Ent1,2) : Pz1#=Entities_Position#(Ent1,3)
Px2#=Entities_Position#(Ent2,1) : Py2#=Entities_Position#(Ent2,2) : Pz2#=Entities_Position#(Ent2,3)
theta#=Entities_Angle#(Ent1,2)
Vx#=sin(theta#)*Entities_Speed#(Ent1)
Vy#=0
Vz#=cos(theta#)*Entities_Speed#(Ent1)
dist#=((px2#-px1#)^2+(py2#-py1#)^2+(pz2#-pz1#)^2)^.5
IF dist#>20
ang1#=atanfull(px2#-px1#,pz2#-pz1#)
repulse#=-20./((dist#))
` repulse#=-10
rx#=0-repulse#*cos(ang1#)
rz#=repulse#*sin(ang1#)
Vx#=Vx#-rx# : Vz#=Vz#-Rz#
`Second Part: Vy=0
ang#=atanfull(Vx#,Vz#)
V#=((vx#^2)+(vz#^2))^.5
Entities_SetSpeed(Ent1,V#)
Entities_SetAngle(Ent1,.,Ang#,.)
else
IF Entities_Team(Ent1)<>Entities_Team(Ent2)
KillEntity(Ent2)
ENDIF
ENDIF
ENDFUNCTION
Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose