I'm back,
I used your code, thank you again, it's working perfect.
My problem is: I inserted a terrain as dbo object, and tried to change to fps the player, but I cant do it. Here is the code, maybe you can give me an idea what to do...
Rem Project: enemy
Rem Created: Thursday, August 16, 2012
`Initialize
sync on
sync rate 60
set gamma 511,511,511
if check display mode(800,600,32)=1
SET DISPLAY MODE 800,600,32
else
SET DISPLAY MODE 800,600,16
endif
set window off
set display mode 800,600,32
Autocam off
Set Camera Range 10,10000
backdrop on
color backdrop 0
set ambient light 100
scale listener 100
cls
sync
splashdelay=3000
sync
`First set up some of the screen particulars
Sync On : Sync Rate 0
Autocam Off : Hide Mouse
desktopwidth=desktop width()
desktopheight=desktop height()
rem player= 10
`Set up the Camera's view frustrum
Set Camera Range .1, 5000
Global MovePerSec As Float
`set the movement rate to 20 feet per second
MovePerSec = 240
`This next variable determines If a reticle will be drawn on the screen
Global UseReticle As Boolean
`we'll set it to the default value, switching the reticle on. A value of
`0 would switch it off
UseReticle = 1
`This variable holds the height from the floor to the player's eye
`this is again in quants, with 1 quant equating roughly to an inch
Global EyeHeight As Integer
`set the eye height to 64 inches
EyeHeight = 64
`This next variable set the mouse's sensitivity for the mouse look
Global MouseSens As integer
`we'll set the default mouse sensitivity value to 3. Valid values range from 1
`(very sensitive)upwards growing less sensitive with each increase
MouseSens = 3
`This variable is used to determine if the character is jumping or falling
Global Airborn as Boolean
`This variable contains the speed at which the player will fall in inches per second
Global Gravity as Float
Gravity = 512
`now we load the map. Swap the name of your map file in here
LoadMap:
Load Object "enemy.dbo", 999
Set Object Collision To Polygons 999
Global ColliderObjNum As Integer
`...and fill it
ColliderObjNum = 2
`now we'll create the actual collider Object
Make Object Sphere 2, EyeHeight/2
`set up its collision method
Set Object Collision On ColliderObjNum
`then place the collider Object around the Camera
Position Object ColliderObjNum, -3834, 96, -6257
Fix object pivot 2
`at this point we'll set the ambient light level so we can see where we're going
`this will probably need to be tweaked to your liking
Set Ambient Light 40
backdrop on
color backdrop rgb(224,255,255)
set ambient light rgb(209, 238, 238)
fog on
fog distance 5000
fog color rgb(209, 238, 238)
rem define the characteristics that each individual enemy can have
type enemy
hp as integer rem how many hitpoints does each enemy have at the moment?
object_number as integer rem which object represents each enemy?
last_fired as float rem when did each enemy last shoot?
endtype
rem define the characteristics that each bullet can have
type bullet
active as boolean rem is the bullet currently flying or "on standby"?
object_number as integer
fired_at as float rem the timer when each particular bullet was fired
owner as integer rem who shot the bullet?
endtype
rem specify how many enemies there are and how many bullets can fly around at the same time.
number_of_bullets = 100
number_of_enemies = 10
rem set up player starting health
player_hp = 100
rem set up the arrays!
rem this means: CREATE 100 individuals of bullets how we defined them above!
rem ...and also CREATE 10 individual enemies as defined above!
dim bullets (number_of_bullets) as bullet
dim enemies (number_of_enemies) as enemy
REM LET'S CREATE ALL THE OBJECTS!
rem define some variables for the object numbers:
player = 1 rem the player object number = 1
object_index_enemies = 10 rem so the OBJECT NUMBERS of the enemies will be 10, 11, 12, 13, ... 20 (see below)
object_index_bullets = 1000 rem the OBJECT numbers of the bullets will be 1001 , 1002, 1003 , ... , 1100
rem make the player object
make object cone player, 10
xrotate object player , 90
fix object pivot player
color object player , rgb (0, 0, 250)
`then place the collider Object around the Camera
rem Position Object ColliderObjNum, -3834, 280, -6257
rem Fix object pivot 2
rem create enemies!
for e = 1 to number_of_enemies rem this means: do the following ten times, advancing the index "e" by 1 in every loop. This creates enemy 1, enemy 2, etc automatically!
rem set up every enemy's stats:
enemies(e).hp = 100
enemies(e).object_number = object_index_enemies + e
rem create the object that represents the enemy
make object cone enemies(e).object_number , 10
xrotate object enemies(e).object_number , 90
fix object pivot enemies(e).object_number
position object enemies(e).object_number , - 300 + rnd(600) , 0 , -300 + rnd(600) rem position the enemies randomly
color object enemies(e).object_number , rgb(250, 0 , 0) rem give our enemies some flavor! :)
next e
rem create bullets!
for b = 1 to number_of_bullets
bullets(b).object_number = object_index_bullets + b
bullets(b).active = 0 rem no bullets have been fired yet!
make object sphere bullets(b).object_number , 2
color object bullets(b).object_number , rgb (200 , 200 , 0)
set object ambient bullets(b).object_number , 0
hide object bullets(b).object_number rem no bullets have been fired yet! so let's hide them!
next b
do
rem control the player movement
if player_hp > 0
if upkey() = 1
move object player , 1
endif
if leftkey() = 1
yrotate object player , object angle y (player) - 3
endif
if rightkey() = 1
yrotate object player , object angle y (player) + 3
endif
if spacekey() = 1
rem check if enough time has passed since the last time the player fired a bullet
if timer() - player_last_fired_at > 300
rem execute the "fire_bullet" subroutine with the player object as the "shooter" (see sub routine at bottom of code)
shooter_object = player
gosub fire_bullet
rem remember when the player last fired a bullet:
player_last_fired_at = timer()
endif
endif
else rem if the player has < 0 hp
center text screen width() *0.5 , screen height() * 0.5 , "YOU'RE DEAD!"
endif
rem handle the enemies:
for e = 1 to number_of_enemies
rem only do the following if the current enemy is alive:
if enemies(e).hp > 0
rem check how far the enemy is from the player
distance_to_player# = sqrt( ( object position x (player) - object position x(enemies(e).object_number) )^2 + ( object position y (player) - object position y(enemies(e).object_number) )^2 + ( object position z (player) - object position z(enemies(e).object_number) )^2 )
rem check if the enemy is in range
if distance_to_player# <= 200
rem make the enemy track the player
point object enemies(e).object_number , object position x(player) , object position y(player) , object position z(player)
rem check if the last time this enemy fired was more than 1000 milli seconds (=1 second) ago
if timer() - enemies(e).last_fired >= 1000
rem FIRE!
rem remember when this enemy fired his last bullet
enemies(e).last_fired = timer()
rem EXECUTE THE "FIRE_BULLET" SUBROUTINE WITH THE CURRENTLY FIRING ENEMY AS THE SHOOTER (i.e. who the bullet is being shot by)
shooter_object = enemies(e).object_number
gosub fire_bullet
endif
endif
endif
next e
rem handle bullets, i.e. let them fly around and check if they hit anything
for b = 1 to number_of_bullets
rem by default, a bullet stays active (unless it hits something or has been flying for too long, see below)
deactivate_bullet = 0
if bullets(b).active = 1
move object bullets(b).object_number , 2
if object collision (bullets(b).object_number , player) = 1
player_hp = player_hp - 5
deactivate_bullet = 1
endif
rem check collision FOR ALL enemies
for e = 1 to number_of_enemies
rem check if the enemy is even alive
if enemies(e).hp > 0
if object collision (bullets(b).object_number , enemies(e).object_number) = 1
enemies(e).hp = enemies(e).hp - 30
deactivate_bullet = 1
rem if this bullet kills the enemy, then hide the enemy object
if enemies(e).hp < 0
hide object enemies(e).object_number
endif
endif
endif
next e
rem if the bullet has been flying for more than 5 seconds, kill it off
if timer() - bullets(b).fired_at >= 5000
deactivate_bullet = 1
endif
if deactivate_bullet = 1
bullets(b).active = 0
hide object bullets(b).object_number
endif
endif
next b REM DO THE ABOVE FOR ALL BULLETS
rem some info text:
rem display health for all enemies and count enemies alive
enemy_count = 0
for e = 1 to number_of_enemies
rem check if the enemy is even alive
if enemies(e).hp > 0
enemy_count = enemy_count + 1
center text object screen x (enemies(e).object_number) , object screen y (enemies(e).object_number) + 10 , str$(enemies(e).hp)
endif
next e
rem display victory message
if enemy_count = 0
center text screen width() *0.5 , screen height() * 0.5 + 20, "YOU WIN!"
endif
rem display player health in top left corner
text 50 , 50 , "YOUR HEALTH: " + str$(player_hp)
text 50 , 60 , "ENEMIES LEFT: " + str$(enemy_count)
sync
loop
Function CheckCollision()
`This is the meat of the sliding collision routine. It is based on a simple premise.
`any move the player makes through the map will be composed of an X and Z component.
`If the player attempts to make a move that causes a collision with the map, we will
`seperate the requested move into these two components and give them the portion of
`the move that does not create a collsion condition. If neither portion of the move
`can be allowed, the player will be simply halted. This final case could only occur
`If the player's move was exactly aligned with either the X or Z axis.
Moving = 0
`Begin Routine
`First we need to record the current Camera position before attempting the move
ox#=Object Position x(2)
oy#=Object Position y(2)
oz#=Object Position z(2)
`next we need to know how fast the machine is running so that
`we can move our player at a consistent speed
Delta#=MovePerSec/Screen FPS()
`Because the collider could pass through a wall without triggering a collision
`condition If the allowable move is too large, we need to ensure that the delta
`pacing formula does not allow it to exceed the collider's size.
If Delta#>EyeHeight
Delta#=EyeHeight
EndIf
`accept the user's input
Rotate Object 2, Object Angle x(2)+(MouseMovey()/MouseSens),Object Angle y(2)+(MouseMovex()/MouseSens),0
`this code constitutes the mouselook functionality
If Object Angle x(2)>90 then XRotate Object 2,90
If Object Angle x(2)<-90 then XRotate Object 2,-90
cx#=Object Angle x(2)
cy#=Object Angle y(2)
cz#=Object Angle z(2)
Rotate Camera cx#, cy#, cz#
Rotate Object 2, cx#, cy#, cz#
If UseReticle = 1
circle screen width()/2,screen height()/2,8
EndIf
k$=upper$(Inkey$())
`This code constitutes the movement functionality
If UpKey()=1 or k$="W"
`move the player forward
XRotate Object 2,0
Move Object 2,Delta#
XRotate Object 2,cx#
EndIf
If DownKey()=1 or k$="S"
`move the player backwards
XRotate Object 2,0
Move Object 2,0-Delta#
XRotate Object 2,cx#
EndIf
If LeftKey()=1 or k$="A"
`strafe left
XRotate Object 2,0
YRotate Object 2,cy#-90
Move Object 2,Delta#
YRotate Object 2,cy#
XRotate Object 2,cx#
EndIf
If RightKey()=1 or k$="D"
`strafe right
XRotate Object 2,0
YRotate Object 2,cy#-90
Move Object 2,0-Delta#
YRotate Object 2,cy#
XRotate Object 2,cx#
EndIf
enable escapekey
if keystate (1) = 1 then end
rem if keystate (50)=1 then gosub map
rem if keystate (50)=0 then position camera 0,object position x (2),object position y(2), object position z(2)
`with that done, we'll record the collider's new X/Z position
nx#=Object Position x(2)
nz#=Object Position z(2)
`retrieve the floor height at the new position
ny#=EyeHeight + (oy#-Intersect Object(1, nx#, oy#, nz#, nx#, -1000, nz#))
`there appears to be an inconsistancy in the way DBPro registers collsions
`in certain circumstances. The following code remedies that situation
`To fix the west wall problem check to see if the distance to collision
`is less than half the collider's size and if it is then nx# = ox#
if nx# > ox#
newxwest# = intersect object(1,nx#,ny#,nz#,nx#+(EyeHeight/2),ny#,nz#)
endif
if newxwest# > 0
if newxwest# < object size x(2)/2
nx# = ox#
endif
endif
`now that we're done moving the collider around, we'll check to see if there's
`a collision
if object collision(2,0) <> 0
`The player's requested move caused a collision, so we'll try to give them
`as much of their move as we can without allowing them to collide
`So first off we'll see if using the old X value eliminates the collision condition
position object 2, ox#, ny#, nz#
if object collision(2, 0)<>0
`Using the old X value did not eliminate the collision. Now we'll try the
`old Z value.
Position object 2, nx#, ny#, oz#
If Object Collision(2, 0)<>0
`Using the old Z value did not eliminate the collision, so now we'll
`see if the new Y value is the one causing the problem.
Position Object 2, nx#, oy#, nz#
If Object Collision(2, 0)<>0
`Ok, nothing we've tried will eliminate the collision condition, so
`we'll just put the player back where they started from.
ny#=oy#
nx#=ox#
nz#=oz#
Else
`The new Y value, was the problem, so we'll just set the Y value back to OY#
ny#=oy#
EndIf
Else
`The New Z value was the problem so we'll set it back to OZ#
nz#=oz#
EndIf
else
`The new X value was the culprit, so we'll set it back to OX#
nx# = ox#
endif
EndIf
if (oy#-ny#) > EyeHeight
`If the Y value is lower than the current Y value, by more than the Eyeheight,
`we need to start the falling process. To do that, we'll reset ny# to oy# because
`the falling routine will handle changing it. Also, we'll set the AirBorn flag to 1
`to tell the program to use the falling routine.
AirBorn = 1
ny#=oy#
`=========================================================================
`NOTE: If the player is going to be damaged by falls, here is where that
`damage is best calculated.
`=========================================================================
`Before we leave, let's just check and make sure that we can
`safely allow the player to fall at this location.
CheckFall()
EndIF
`move the Camera and collider to the final adjudicated position
Position Camera 0, nx#, ny#, nz#
Position Object 2, nx#, ny#, nz#
EndFunction
Function CheckFall()
`this function checks to see if the place you are going to fall to is going to
`create a collision.
ox#=Object Position x(2)
oy#=Object Position y(2)
oz#=Object Position z(2)
`to do that, we'll determine where the final resting location is after the fall is
`complete
ny#=EyeHeight + (oy#-Intersect Object(1, ox#, oy#, oz#, ox#, -1000, oz#))
`We'll quickly position the collider there
position object 2, ox#, ny#, oz#
`then see if there is a collision at the proposed location
if object collision(2,0) <> 0
`If there is a collision, we'll simply turn off the AirBorn flag
Airborn=0
EndIf
EndFunction
fire_bullet:
rem this is a bit complex. basically, we check for a "free" bullet, that is, one that has not been fired yet and is "on standby"
for b = 1 to number_of_bullets
rem see if the current bullet is "unused"
if bullets(b).active = 0
rem if it is not currently active, USE THIS BULLET!
rem position the bullet where the enemy is
position object bullets(b).object_number , object position x (shooter_object) , object position y (shooter_object) , object position z (shooter_object)
rem aim the bullet in the right direction
rotate object bullets(b).object_number , object angle x (shooter_object) , object angle y (shooter_object) , object angle z (shooter_object)
rem move the bullet a bit forward so that it doesn't start INSIDE the enemy
move object bullets(b).object_number , 15
rem set the bullet to active
bullets(b).active = 1
rem remember when this bullet was fired
bullets(b).fired_at = timer()
rem unhide the bullet object
show object bullets(b).object_number
rem since we have already found an unused bullet, we don't need to search any further. If bullet one (b=1) is already flying around, go on to check bullet two, and so on.
exit
endif
next b
return
Mihai