DarkAI

SOUNDS DEMO


This demo shows the use of sounds to attract the attention of nearby entities. It allows a player object to make a sound at it current location causing entities that hear it to move to investigate, resulting in an attack if the player is found at the location of the sound. Entities that attack also cause a sound in this demo which attracts further attention from entities which hear it. A conveniently placed wall allows the player to make a sound above it and run and hide from view that, as long as the player remains hidden, will cause the entities to investigate, find nothing, and return to their idle positions.

This demo is very similar to the Zone demo with a simple visual attack and obstacle layout. The obstacle setup will not be covered in this demo, you should familiarise yourself with the Path Finding demo for details on obstacle setup. The attack method will be covered in this demo.

dim shootTimer(3) as float

This line creates an array that we will use to store a timer for each entity to prevent entities firing too quickly. The AI system will return the 'ready to fire' signal continuously whilst an entity can see a valid target so we must handle delayed firing in DarkBasic to prevent continuous fire. Or we could not if continuous fire is what we wanted, but for this demo we will handle delayed firing.


for i = 2 to 3

make object i,1,0
position object i,(i-2)*40 – 20,2.5,15
color object i,rgb(255,0,0)

make object i+1000,2,1
set object light i+1000,0
hide object i+1000

AI Add Enemy i
AI Set Entity Speed i,10.0
AI Set Entity View Arc i,90,170
AI Set Entity View Range i,80
AI Set Entity Hearing Range i,80
AI Set Entity Can Strafe i,0

next i

This loop creates two entities along with two attack objects (i+1000) that we will use later to represent attacks, and sets some entity parameters for the AI system. The Set View Arc command defines the angle at which the entities can see with in an inner (90) and outer (170) angle, in this case the inner angle does not matter since automatic mode does not make use of it, it would only be used by using the Can See command. The outer angle of 170 defines just short of a forward half circle which allows the entity to effectively spot targets out of the corner of its eye but not behind it. An angle of 90 defines a forward cone which means a target has to be mostly in front of the entity to be spotted. An angle of 360, which is the default, means the entity can see all around it. The Set View Range defines the distance the entity can see in any direction that is within its outer view angle, once both the angle and distance restrictions are checked an entity can determine if is can see a target. The Hearing Range defines the radius within which the entity can hear sounds from its current location, this also applies to sounds behind walls which have no effect in blocking the detection of sounds. The Can Strafe command is used for finer control over the behaviour of the entity, in this case the entity is prevented from moving sideways relative to its target, which can normally be used to avoid fire. Since the player cannot shoot in this demo there is no reason to strafe.

make object sphere 1,5
position object 1,20,2.5,-40
AI Add Player 1

Next we create a sphere to represent the player and add it to the AI system. This is all we need to do for the player since the AI system will now read the player object's position automatically every frame and update its internal values since the default values link the player to the object.


In the main loop are the controls for moving the player object, which is automatically transferred to the AI system in when AI Update is called, along with this line:

if spacekey()=1 then AI Create Sound object position x(1),object position z(1),0,1

Which creates a sound at the player's current position. The sound is created as type 0, which is the lowest valid type and signals a low priority sound, e.g. foot steps. The entity will prefer to investigate higher priority sounds if more than one type can be heard at the same time, but since this is a quiet environment with no other sounds present the entity will investigate this low value sound. The radius is set to 1 which does not significantly increase the range of the sound, this radius is added to the entity's hearing range and if the two combined are greater than the distance between the two then it is heard. The radius provides a way of allowing larger sounds to be heard by entities that would normally be too far away to hear it.


for i = 2 to 3

if AI Entity Exist(i)=1

if AI Get Entity Can Fire(i) and shootTimer(i)<=0

tx# = AI Get Entity Target X(i)
tz# = AI Get Entity Target Z(i)
x# = object position x(i)
z# = object position z(i)
dx# = ( x# + tx# ) / 2.0
dz# = ( z# + tz# ) / 2.0
dist# = sqrt ( (tx#-x#)*(tx#-x#) + (tz#-z#)*(tz#-z#) )
ang# = acos ( (tz#-z#) / dist# )
if ( (tx#-x#) < 0 ) then ang# = 360 – ang#
position object i+1000,dx#,2.5,dz#
yrotate object i+1000,ang#+0.1
scale object i+1000,100,100,100*dist#
show object i+1000

shootTimer(i)=100

AI Create Sound x#,z#,1,1

endif

endif

if shootTimer(i)>0 then shootTimer(i) = shootTimer(i)-(speed#*3)

next i

This loop cycles through both entities, first checking that they both exist within the AI system and then checking if they can see a valid target by calling Can Fire. If this returns 1 we check the entity timer to make sure they have not already fired recently, if so we let them wait a bit longer, if not then we display a new attack and reset the timer. This is what separates the continuous attack from a delayed attack.

To position the attack object for this entity we take the co-ordinates of the target the entity is firing at and the current position of the entity and average them to place the attack object between the two (stored in dx# and dz#). Next we calculate the distance between the entity and its target to be able to scale the attack object the correct length to reach between the two. Finally we calculate the Y angle between the two to rotate the attack object correctly and apply all the values to the object (i+1000). Then the entity timer is reset to 100 to prevent the entity firing again until it has reached zero.

The difference here between this and the zone demo is we also create a new sound, of type 1, whenever an entity attacks drawing more attention to the scene of the combat.

The entity timer is decreased every frame by a value that is proportional to the frame rate, stored in speed#, to make sure the entities fire at roughly the same rate no matter the frame rate.