Quote: "When they reach the same zone "room" as the player they will move in a straight line toward the player using something like this:"
Here is some waypoint moving code that can be applied to enemies track to the player. Basically it makes the focused object make a smooth turn towards the destination while moving forward. This uses curveangle. The larger the speed value of curve angle, the wider or slower the turn. Instead of having enemies slide left or right, they can turn and move forward. This causes a bit of an arcing motion. Again, depending on the settings in curveangle, the arc can be minimal. In the following example, the red cones will move towrads the green cube. Move the green cube forward or backwards with the arrow keys and steer with the mouse. Moving backwards gives you a better visual of how the cones are responding. I have them set to move in a fairly wide arc for the sake of demonstration.
Change the 40 to something lower in this line
curyang#=curveangle(destyang#,curyang#,40)
in the _track_player rountine
remstart
==============================================================
= Title : Track enemies to player
= Author : latch
= Date : 12/08/2009
= Update :
= Version: .01
==============================================================
Comments Using curveangle, smooth turning and tracking can
be achieved between objects or by an object moving
through a series of waypoints
==============================================================
remend
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
autocam off
set display mode 800,600,32
sync on
sync rate 60
hide mouse
rem =============================================================
rem = MAIN
rem =============================================================
_main:
gosub _init
do
gosub _move_player
gosub _track_player
sync
loop
end
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
_init:
rem make a matrix for reference
make matrix 1,2000,2000,20,20
randomize matrix 1,50
rem create an array to hold varying enemy speeds
dim enspeed#(50)
rem create a few cones that'll be used as the enemies
for enemy=1 to 50
make object cone enemy,25
xrotate object enemy,90
fix object pivot enemy
color object enemy,rgb(255,0,0)
position object enemy,rnd(2000),13,rnd(2000)
enspeed#(enemy)=rnd(9)+1
next enemy
rem make the player object
make object cube 100,25
color object 100,rgb(0,255,0)
position object 100,1000,13,1000
return
`----------------------------------------------------------------
_move_player:
yang#=wrapvalue(object angle y(100)+mousemovex())
yrotate object 100,yang#
newx#=newxvalue(object position x(100),yang#,(upkey()-downkey())*10)
newz#=newzvalue(object position z(100),yang#,(upkey()-downkey())*10)
newy#=get ground height(1,newx#,newz#)+13
position object 100,newx#,newy#,newz#
rem follow camera behind player
set camera to follow newx#,newy#,newz#,yang#,300,newy#+100,10,0
return
`----------------------------------------------------------------
_track_player:
rem enemies will track to player
for en=1 to 50
rem get the current facing of the enemy
curyang#=object angle y(en)
rem get the destination angle where the player is
point object en,object position x(100),object position y(en),object position z(100)
rem get the new angle
destyang#=object angle y(en)
rem adjust curyang to curve towards destination
curyang#=curveangle(destyang#,curyang#,40)
rem rotate the enemies heading
yrotate object en,curyang#
rem move the enemy forward and adjust for matrix height
move object en,enspeed#(en)
eny#=get ground height(1,object position x(en),object position z(en))+13
position object en,object position x(en),eny#,object position z(en)
next en
return
rem =============================================================
rem = FUNCTIONS
rem =============================================================
rem =============================================================
rem = DATA STATEMENTS
rem =============================================================
Quote: "When the final house model is done and the outside environment is complete (rocks, hay bales, fences, etc) I can map nodes for the entire terrain so A* can be used inside and out."
I don't think A* will be necessary for outside. There will be collision set up for both static and dynamic objects. The tracking system displayed above can be used for waypoint movement as well so there can be a single routine that is called when the creatures have to track to a waypoint or the player. The difference will be the coordiantes they track to each iteration. Here is an example of using the same tracking method as above. It was originally designed as a test of collision for multiple objects. It uses a single collision object for speed that all of the cones share in turn. The green posts are obstacles that the cones will move around if the collide with them.
Using this collision method, I've gotten the polygon count past 25,000 with no real reduction in fps. To do this, change the cones to spheres try and keep as many in screen as possible:
remstart
==============================================================
= Title : Multiple Collision Objects
= Author : latch
= Date : 07/06/2008
= Update :
= Version:
==============================================================
Comments This demonstrates a method of handling multiple
object collisions using DBC native commands.
This example uses a "feeler" object in front
of each zombie
==============================================================
remend
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
autocam off
`set window on
`set window layout 0,0,0
set display mode 800,600,32
`maximize window
sync on
sync rate 60
hide mouse
rem =============================================================
rem = MAIN
rem =============================================================
_main:
gosub _init
do
text 0,0,"Actual FPS "+str$(screen fps())
`text 0,20,"Entered Sync Rate "+str$(srate)
text 0,40,"Polygons "+str$(statistic(1))
gosub _move_camera
gosub _move_zombies
sync
loop
end
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
_init:
randomize timer()
`input "Enter Sync Rate :";srate
`sync rate srate
gosub _terrain:
gosub _environment_objects
gosub _zombies
gosub _player
gosub _feeler
position camera matx#/2,200,matz#/2
xrotate camera 60
ink rgb(255,255,255),0
return
`----------------------------------------------------------------
_terrain:
mat=1
matx#=3000
matz#=3000
tilex=15
tilez=15
make matrix mat,matx#,matz#,tilex,tilez
randomize matrix mat,20
update matrix mat
return
`----------------------------------------------------------------
_environment_objects:
make object box 1,10,80,10
offset limb 1,0,0,40,0
make mesh from object 1,1
delete object 1
make object 1,1,0
x#=matx#/2
z#=matz#/2
position object 1,x#,0,z#
rem make one solid object out of square pillars
for lm=1 to 300
add limb 1,lm,1
lx#=rnd(int(matx#))-x#
lz#=rnd(int(matz#))-z#
ly#=get ground height(mat,lx#,lz#)
offset limb 1,lm,lx#,ly#,lz#
next lm
make mesh from object 1,1
delete object 1
make object 1,1,0
delete mesh 1
color object 1,rgb(0,100,0)
rem set the object collision status for these pillars
set object collision on 1
set object collision to polygons 1
sync
return
`----------------------------------------------------------------
_zombies:
rem create an array to hold the original starting positions
rem of the zombies so we can move them there if they go
rem out of view or we want to respawn them
totalzom=200
dim zposition(totalzom,2)
rem using cones to represent the zombies
for zomb=3000 to (3000+totalzom)-1
make object cone zomb,25
`make object sphere zomb,25
offset limb zomb,0,0,13,0
make mesh from object zomb,zomb
delete object zomb
make object zomb,zomb,0
delete mesh zomb
set object collision off zomb
`set object collision to boxes zomb
x#=rnd(int(matx#))
z#=rnd(int(matz#))
y#=get ground height(mat,x#,z#)
position object zomb,x#,y#,z#
rem store the zombie position
zposition(zomb-2999,0)=x#
zposition(zomb-2999,1)=y#
zposition(zomb-2999,2)=z#
next zomb
sync
return
`----------------------------------------------------------------
_move_camera:
yang#=wrapvalue(yang#+mousemovex())
yrotate camera yang#
newx#=newxvalue(object position x(pl),yang#,(upkey()-downkey())*3)
newz#=newzvalue(object position z(pl),yang#,(upkey()-downkey())*3)
`position camera newx#,camera position y(),newz#
oldx#=object position x(pl)
oldz#=object position z(pl)
position object pl,newx#,13+(get ground height(mat,newx#,newz#)),newz#
pbang=object collision(pl,1)
if pbang
position object pl,oldx#,13+(get ground height(mat,newx#,newz#)),oldz#
newx#=oldx#
newz#=oldz#
endif
rem position camera with player but a little behind
cx#=newxvalue(newx#,yang#,-80)
cz#=newzvalue(newz#,yang#,-80)
yrotate object pl,yang#
`position object pl,plx#,object position y(pl),plz#
position camera cx#,200+(get ground height(mat,cx#,cz#)),cz#
return
`----------------------------------------------------------------
_player:
pl=2
gosub _red
make object sphere pl,25
set object collision on pl
set object collision to boxes pl
texture object pl,red
position object pl,matx#/2,13,(matz#/2)+50
return
`----------------------------------------------------------------
_red:
red=2
bmp=1
while bitmap exist(bmp)
inc bmp
endwhile
create bitmap bmp,5,5
ink rgb(255,0,0),0
dot 0,0
`dot 1,1
get image red,0,0,1,2
delete bitmap bmp
return
`----------------------------------------------------------------
_move_zombies:
for zomb=3000 to (3000+totalzom)-1
rem check if the zombie is in screen
rem if so turn on it's collision
rem if not hide it
if object in screen(zomb)=0
hide object zomb
rem reposition the zombie at it's "home" location
position object zomb,zposition(zomb-2999,0),zposition(zomb-2999,1),zposition(zomb-2999,2)
`set object collision off zomb
else
if object visible(zomb)=0 and object in screen(zomb)=1
show object zomb
`set object collision on zomb
`set object collision to boxes zomb
endif
endif
rem check if zombie is hitting something
if object visible(zomb)=1
rem use the feeler object to place in front of a zombie
rem to check for collision - in this case 13 units in front
zyang#=object angle y(zomb)
zombx#=object position x(zomb)
zomby#=object position y(zomb)
zombz#=object position z(zomb)
newx#=newxvalue(zombx#,zyang#,13)
newz#=newzvalue(zombz#,zyang#,13)
position object feeler,newx#,zomby#,newz#
`bang=object collision(zomb,0)
bang=object collision(feeler,0)
rem check against environment
if bang>0
choose=rnd(1)
if choose
yrotate object zomb,(wrapvalue(object angle y(zomb)+90))
else
yrotate object zomb,(wrapvalue(object angle y(zomb)-90))
endif
move object zomb,3
endif
rem point zombie towards player smoothly
zyang#=object angle y(zomb)
point object zomb,object position x(pl),object position y(zomb),object position z(pl)
newyang#=object angle y(zomb)
yrotate object zomb,zyang#
smoothang#=curveangle(newyang#,zyang#,20)
yrotate object zomb,smoothang#
move object zomb,2
position object zomb,object position x(zomb),13+(get ground height(mat,object position x(zomb),object position z(zomb))),object position z(zomb)
endif
next zomb
return
`----------------------------------------------------------------
_feeler:
feeler=3
make object cube feeler,25
hide object feeler
set object collision on feeler
set object collision to boxes feeler
return
`----------------------------------------------------------------
rem =============================================================
rem = FUNCTIONS
rem =============================================================
rem =============================================================
rem = DATA STATEMENTS
rem =============================================================
Enjoy your day.