The problem is that they can share the same memory I believe in certain sitations. If you do all your physics creating before your NGC creating it should work.
rem Program: Nuclear Glory Collision
rem Version: 4.01 Final Release
rem Copyright: Nuclear Glory Entertainment Arts - 2006
rem Website: http://www.nuclearglory.com
rem Instructions: Make sure the include file "NGCollision.dba" is
rem linked on the DBPro IDE. To do this, first make sure your
rem Project Manager is open. (View->Show Project Manager)
rem Click on the "Files" button on the bottom left of the project manager.
rem Click on the "browse" button near the top of the project manager
rem Surf to the "NGCollision.dba" file, select it, and click "Open"
rem Now you should be all set.
Rem ***** Main Source File *****
Rem These are collision definitions to make the code easier to read.
Rem For simplicity reasons, I suggest you leave these as they are,
rem as when we release updates we may ask you to change this block to reflect
rem the changes we made.
rem SOME globals to make (SetCollisions) and ray-cast
rem statements easier to read
#Constant TYPE_NGC_ELLIP=1
#Constant TYPE_NGC_MESH=2
#Constant ELLIP_2_ELLIP=1
#Constant ELLIP_2_POLY=2
#Constant RESP_STICK=1
#Constant RESP_SLIDE=2
#Constant RESP_SLIDE_NO_SLOPES=6
#Constant RESP_SLIDE_NO_GRAV=10
#Constant RESP_SLIDE_NO_ACCEL=18
#Constant RESP_NONE=32
#Constant DYN_NO_RESP=1
#Constant DYN_RESP=2
#Constant DYN_RESP_LOCK=4
#Constant DYN_RESP_LOCK_NOTURN=12
#Constant NCULL_CLOCK 0
#Constant NCULL_COUNTER_CLOCK 1
#Constant NCULL_NONE 2
rem End globals
rem
rem Startup settings
rem
rem sets our display mode
Set Window On
SET DISPLAY MODE 800, 600, 16
rem sync on
sync on : sync rate 30 : Autocam off
hide mouse
phy start
REM PHYSICS
phy set gravity 0,0,0
load image "banner_horse.dds",20
phy make cloth 1001
phy set cloth dimensions 1001, 4, 4, 0.2
phy set cloth position 1001,0,0,0
phy set cloth rotation 1001, 90, 0, 0
phy build cloth 1001
texture object 1001, 20
rem
rem Scene settings
rem
rem Starts the collision system, this MUST be called before you can call any other
rem collision commands
StartCollisionPRO(000000000,000000000,000000000)
rem This line puts the collision system in Debug mode. If there is an error
rem (like you try to set an object that doesn't exist) this will make a box
rem popup notifying you of the error. If you take this line out, the system
rem will do its best to silently stop any errors that occur. (without crashing
rem your program) It's recommended that you leave this line in while you're
rem developing the application, then take it out before you make the final release
StartCollisionDebugPRO()
rem These are constants to hold our "collision types". One type represents a "group"
rem of objects. (for instance: world objects, enemy objects, etc.)
rem The are Constant to make things clean, it is not required to use constants.
rem These can be anything, as long as their value is less than 300 and greater than 0.
#Constant TYPE_FOLLOW_CAM = 1
#Constant TYPE_FREE_CAM = 2
#Constant TYPE_PLAYER = 3
#Constant TYPE_ENEMY = 4
#Constant TYPE_WORLD = 5
rem The player settings.
rem What it all does ---
rem <> We want the player to collide with the world objects using ellipsoid
rem to poly collision. Then we set the standard response to "RESP_SLIDE_NO_GRAV" so
rem we'll have standard sliding collision, AND you won't slide down slopes,
rem AND when you walk up slopes any downward gravity force won't fight you.
rem Then we set Dynamic response to "DYN_RESP_LOCK" which means that you'll respond
rem properly to moving meshes AND the you won't slide off the mesh when it slides
rem sideways
rem <> The 2nd definition says that we want player object to collide with
rem enemy objects using ellipsoid to ellipsoid collision. Then we set the response
rem mode to "RESP_SLIDE" for standard sliding collision, and the last parameter is
rem not used, so set it to "DYN_NO_RESP"
rem NOTE: The last parameter is only used for "ELLIP_2_POLY" definitions
SetCollisionsPro( TYPE_PLAYER, TYPE_WORLD, ELLIP_2_POLY, RESP_SLIDE_NO_GRAV, DYN_RESP_LOCK )
SetCollisionsPro( TYPE_PLAYER, TYPE_ENEMY, ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
SetCollisionsPro( TYPE_PLAYER, TYPE_FREE_CAM, ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
rem The enemy settings
rem What it all does ---
rem <> We want the enemy to collide with the world in the same way the player
rem collides with the world
rem <> We want the enemy to collide with the player using ellipsoid to ellipsoid
rem collision and standard sliding response.
rem <> We want the enemy to collide with the enemy using ellipsoid to ellipsoid
rem collision and standard sliding response.
rem <> We want the enemy to collide with the free-flight camera using ellipsoid
rem to ellipsoid collision and standard sliding response.
SetCollisionsPro( TYPE_ENEMY, TYPE_WORLD, ELLIP_2_POLY, RESP_SLIDE_NO_GRAV, DYN_RESP_LOCK)
SetCollisionsPro( TYPE_ENEMY, TYPE_PLAYER,ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
SetCollisionsPro( TYPE_ENEMY, TYPE_ENEMY, ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
SetCollisionsPro( TYPE_ENEMY, TYPE_FREE_CAM, ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
rem The follow-camera settings
rem What it all does ---
rem <> The follow-cam collides with the world using ellipsoid to poly collision
rem with a "stick" response mode.
rem -- Why a sticky response mode?
rem Every frame the camera is placed at the player's body, reset there, then
rem it's sent backwards to it's follow position. If it hits something it'll
rem stick there on that frame. But the follow-cam may slowly rotate into position
rem when the player stops moving, and each time it'll be shot backward at a
rem slightly new angle. This gives the illusion of sliding as the screen is only
rem drawn after the camera is in the correct follow position.
rem
rem NOTE: For more info about the follow-cam, read the end of the UpdateFollowCamera()
rem function.
SetCollisionsPro( TYPE_FOLLOW_CAM, TYPE_WORLD, ELLIP_2_POLY, RESP_STICK, DYN_NO_RESP )
rem The free-camera settings
rem What it all does ---
rem <> The free-flight camera collides with the world using ellipsoid to poly
rem collision, standard sliding response, and standard dynamic response.
rem --- Why use standard sliding response and not the others?
rem Because the free-flight camera is not an object that has gravity
rem and we're therefore not worried about it sliding backwards down a slope
rem or fighting gravity going up the slope
rem --- Why a standard dynamic response and not locking?
rem Locking is mainly used for objects that need to ride on a mesh
rem that will slide sideways. Our elevator slides side-ways but we're
rem not interested in our free-flight camera being locked to the elevator
rem when it slides sideways
rem <> The free-flight camera is to collide with the player using ellip-2-ellip
rem collision and standard sliding response.
rem <> The free-flight camera is to collide with the enemy objects using
rem ellip-2-ellip collision and standard sliding response.
SetCollisionsPro( TYPE_FREE_CAM, TYPE_WORLD, ELLIP_2_POLY, RESP_SLIDE, DYN_RESP )
SetCollisionsPro( TYPE_FREE_CAM, TYPE_PLAYER, ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
SetCollisionsPro( TYPE_FREE_CAM, TYPE_ENEMY, ELLIP_2_ELLIP, RESP_SLIDE, DYN_NO_RESP )
rem *** Begin some world setup stuff
rem defines some global variables
global camera=0, cam_obj=1
rem Set this to the initial movement speed of the camera
global cam_speed# = 4.0
rem global array to hold the "hold status" of each key pressed
global dim KeyHold(256)
rem global array to hold the "hold status" of each key pressed
global dim LastKeyHold(256)
rem turns on the backdrop
backdrop on
rem creates our camera and inits the properties
Set Camera Range 2, 15000
color backdrop camera, rgb(0,0,255)
make object sphere cam_obj, 2
position object cam_obj,0,15,0
rotate object cam_obj,0,-90,0
rem Sets the camera object to "TYPE_FOLLOW_CAM" as the camera start
rem in the camera mode that follows the player
CollisionTypePRO( cam_obj, TYPE_FOLLOW_CAM )
rem Sets the sizes of the ellip of the camera object to 2.
rem Basically, a sphere with a radius of 2
SetObjRadiusPRO( cam_obj, 2, 2, 2 )
rem loads the level
level = 2
load object "media/3rd_shooter/dbp_demo_level.x",level
rem Set the object as part of the world
CollisionTypePRO( level, TYPE_WORLD )
rem Commands that could be used to save or load the level mesh from file
rem using the internal NGC file format.
rem LoadMeshPRO( level, TYPE_WORLD, "test1.wrld" )
rem SaveMeshPRO( level, "test1.wrld" )
rem sets up player global vars
global player = 3
global player_stand_anim = 4
global player_run_anim = 5
global player_anim_mode = 0
rem loads player objects
make object sphere player, 2
hide object player
load object "media/3rd_shooter/player/soldier_stand.x",player_stand_anim
load object "media/3rd_shooter/player/soldier_run.x",player_run_anim
rem Sets up the standing animation
rotate object player_stand_anim, 0, 180, 0
fix object pivot player_stand_anim
position object player_stand_anim,0,10,0
scale object player_stand_anim, 20, 20, 20
glue object to limb player_stand_anim, player, 0
rem Sets up the running animation
rotate object player_run_anim, 0, 180, 0
fix object pivot player_run_anim
position object player_run_anim,0,10,0
scale object player_run_anim, 20, 20, 20
glue object to limb player_run_anim, player, 0
hide object player_run_anim
rem Loops the player's standing animation
loop object player_stand_anim
set object speed player_run_anim, 150
rem Re-Positions the player
move object player,-120
rem Defines the player object as TYPE_PLAYER for the collision system
CollisionTypePRO( player, TYPE_PLAYER )
rem Sets the ellipsoid sizes of our player ellipsoid
rem Format is: DBObject, XSize, YSize, ZSize
SetObjRadiusPRO( player, 7, 20, 7 )
rem Sets object gravity using the automatic gravity option in the collision engine
rem According to the def below, the player object will fall at 8 units per frame
rem (Note: This IS NOT required for the NO_SLOPES definitions, etc..., to work
rem properly)
rem (Note: You can call this function during the execution of your program to
rem alter the gravity of the object, if you have need)
rem SetObjGravityPRO( player, 8 )
rem Offsets our object ellipsoid. The ellipsoid stretches out equally in all
rem directions from it's own DB object. The "player" object is at the model's feet,
rem so if we didn't do this the player would seem to be floating way up in the air.
rem (The below definition tells the system to move the ellipsoid up 11.2 units)
SetObjOffsetPRO( player, 0, 11.2, 0 )
rem Loads and animates enemy soldier
global enemy1 = 10
load object "media/3rd_shooter/player/soldier_run.x",enemy1
rotate object enemy1, 0, 180, 0
fix object pivot enemy1
position object enemy1,-100,21,0
loop object enemy1
rem Sets the enemy object as a TYPE_ENEMY object in the collision engine
CollisionTypePRO( enemy1, TYPE_ENEMY )
rem Sets the sizes of the enemy ellipsoid
SetObjRadiusPRO( enemy1, 7, 20, 7 )
rem Sets the gravity of the enemy ellipsoid
rem SetObjGravityPRO( enemy1, 8 )
rem Replaces: scale object enemy1, 20, 20, 20
ScaleObjectPRO( enemy1, 20, 20, 20 )
rem Loads and animates enemy soldier
global enemy2 = 11
load object "media/3rd_shooter/player/soldier_run.x",enemy2
rotate object enemy2, 0, 180, 0
fix object pivot enemy2
position object enemy2,-140,21,0
loop object enemy2
rem Sets the enemy object as a TYPE_ENEMY object in the collision engine
CollisionTypePRO( enemy2, TYPE_ENEMY )
rem Sets the sizes of the enemy ellipsoid
SetObjRadiusPRO( enemy2, 7, 20, 7 )
rem Sets the gravity of the enemy ellipsoid
rem SetObjGravityPRO( enemy2, 8 )
rem Replaces: scale object enemy2, 20, 20, 20
ScaleObjectPRO( enemy2, 20, 20, 20 )
rem Loads elevator object
global elevator = 12
global elevator_mode = 0
global elevator_up_ticker# = 0
global elevator_side_ticker# = 0
global sit_ticker# = 0
global elevator_size_ticker# = 0
load object "media/3rd_shooter/elevator.x",elevator
position object elevator,0,-45,0
rem Sets the elevator object as a world mesh
CollisionTypePRO( elevator, TYPE_WORLD )
rem Replaces: scale object elevator, 3000, 3000, 3000
ScaleObjectPRO( elevator, 3000, 3000, 3000 )
rem loads the lazer sight for the walls
global lzr = 20
make object plain lzr, 3, 3
load image "media/3rd_shooter/player/lazer_sight.png", lzr
texture object lzr, lzr
set object transparency lzr, 1
set object light lzr, 0
do
rem Update input data
UpdateKeyHold()
rem if 'c' key is hit
if KeyHit(46)
cam_mode = cam_mode + 1
if cam_mode > 1 then cam_mode = 0
rem The below demonstrates that the camera object's collision type
rem can be changed during runtime
rem (WARNING: Do not do this with objects that are defined as mesh objects
rem by being the 2nd parameter of an "ELLIP-2-POLY" definition
if cam_mode = 1
rem if the camera mode is set to 1 (free-flight camera)
rem then set the camera object to the "TYPE_FREE_CAM" collision type
CollisionTypePRO( cam_obj, TYPE_FREE_CAM )
rem set the camera object's radius
SetObjRadiusPRO( cam_obj, 6, 6, 6 )
else
rem if the camera mode is set to 0 (follow camera)
rem then set the camera object to the "TYPE_FOLLOW_CAM" collision type
CollisionTypePRO( cam_obj, TYPE_FOLLOW_CAM )
rem set the camera object's radius
SetObjRadiusPRO( cam_obj, 2, 2, 2 )
endif
endif
rem Display screen data
set text size 20
if cam_mode = 1
text 0,0,"Press 'c' to switch to walk mode"
text 0,20,"Cam speed: "+str$(cam_speed#)
text 0,40,"Use A/Z to change camera speed"
text 0,60,"Use mouse to rotate camera and arrow keys to move"
else
text 0,0,"Press 'c' to switch to free-flight"
text 0,40,"Use arrow keys to turn/move"
endif
text 0, 80, "FPS: "+str$(screen FPS())
if cam_mode = 1
UpdateFreeCamera()
else
UpdateFollowCamera()
UpdatePlayer()
endif
UpdateEnemyAI()
UpdateElevator()
rem Do gravity for player
position object player, object position x(player), object position y(player) - 6.0, object position z(player)
rem And here's the best line! This commands runs the entire collision system
rem and updates all of your objects for you. Easy enough?
rem
rem I hear you ask, "But wait, what if I delete an object? Won't it crash?"
rem Well, we already thought of that (apparently). The system will recognize
rem that the object is gone and safely remove it from collision memory for you
RunCollisionPRO()
rem Updates our lazer sight
UpdateLazerSight()
`position our camera back in the "camera object" position,
`since the collision system only uses objects (not cameras)
camx# = object position x(cam_obj) : camy# = object position y(cam_obj) : camz# = object position z(cam_obj)
camrx# = object angle x(cam_obj) : camry# = object angle y(cam_obj) : camrz# = object angle z(cam_obj)
position camera camera, camx#, camy#, camz#
rotate camera camera, camrx#, camry#, camrz#
phy update
sync
loop
``***********
```**** INPUT FUNCTIONS ********
``***********
rem Checks keys down to notify us if a key is being held
function UpdateKeyHold()
for t=0 to 256
LastKeyHold(t) = KeyHold(t)
next t
for t=0 to 256
KeyHold(t) = Keystate(t)
next t
endfunction
rem Checks if a Key has been hit
function KeyHit(t)
retval=0
if not LastKeyHold(t)
if KeyHold(t)
retval=1
endif
endif
endfunction retval
``***********
```**** Control/Display FUNCTIONS ********
``***********
rem Handles our elevator
function UpdateElevator()
select elevator_mode
case 0
elevator_up_ticker# = elevator_up_ticker# + 1
if elevator_up_ticker# > 350
elevator_up_ticker# = 10
elevator_mode = 2
endif
if elevator_up_ticker# = 180
elevator_mode = 1
endif
endcase
case 1
elevator_side_ticker# = elevator_side_ticker# + 1
if elevator_side_ticker# >= 360
elevator_side_ticker# = 0
elevator_mode = 0
endif
endcase
case 2
sit_ticker# = sit_ticker# + 1
if sit_ticker# > 100
sit_ticker# = 0
elevator_mode = 0
endif
endcase
endselect
rem Update the elevator position
ypos# = -45 + (sin(elevator_up_ticker#/2)*90)
xpos# = 0 - (sin(elevator_side_ticker#/2)*70)
zpos# = 0 - (sin(elevator_side_ticker#/2)*70)
position object elevator, xpos#, ypos#, zpos#
rem Turn the elevator
yrotate object elevator, object angle y(elevator)+0.3
rem changes the size of the elevator to make it 'breathe'
elevator_size_ticker# = elevator_size_ticker# + 2
elevator_size# = 30 + Cos(elevator_size_ticker#)*3
elevator_size# = elevator_size# * 100
If elevator_size_ticker# > 360 Then elevator_size_ticker# = 0
rem Calls the DLL command to size the elevator
SetObjScalePRO(elevator, elevator_size#, elevator_size#, elevator_size#)
endfunction
rem Handles our stupid AI units
function UpdateEnemyAI()
move object enemy1,1.1
zpos# = object position z(enemy1)
yrot = wrapvalue(object angle y(enemy1))
if yrot >= -1 and yrot <= 1
if zpos# > 60
yrotate object enemy1, 180
endif
endif
if yrot <= -179 or yrot >= 179
if zpos# < -55
yrotate object enemy1, 0
endif
endif
position object enemy1, object position x(enemy1), object position y(enemy1) - 6.0, object position z(enemy1)
move object enemy2,1.1
zpos# = object position z(enemy2)
yrot = wrapvalue(object angle y(enemy2))
if yrot >= -1 and yrot <= 1
if zpos# > 85
yrotate object enemy2, 180
endif
endif
if yrot <= -179 or yrot >= 179
if zpos# < -75
yrotate object enemy2, 0
endif
endif
position object enemy2, object position x(enemy2), object position y(enemy2) - 6.0, object position z(enemy2)
endfunction
rem Handles our lazer sight
function UpdateLazerSight()
rem Get the positions of the player object
player_x# = object position x(player) : player_y# = object position y(player) : player_z# = object position z(player)
rem Store the start positions and increase the Y pos so sy# reflects the
rem the Y position of the gun
sx# = player_x#
sy# = player_y# + 19
sz# = player_z#
rem Set the lzr decal object to the orienation of the player
set object to object orientation lzr, player
rem position the lzr at the start positions
position object lzr, sx#, sy#, sz#
rem turn it left 90 degrees
turn object left lzr, 90
rem move it forward 5 degrees
move object lzr, 5
rem turn it back right 90 degrees
turn object right lzr, 90
rem set start positions to object position of lzr object
sx# = object position x(lzr)
sy# = object position y(lzr)
sz# = object position z(lzr)
rem move our lzr object forward 500 units
move object lzr, 500
rHit# = 500
rem store it's new position the end position variables
ex# = object position x(lzr) : ey# = object position y(lzr) : ez# = object position z(lzr)
rem Cast a ray from the lzr start position to it's end position
rem Test against world objects, and test them as mesh objects
bHit = RayIntersectTypePRO(TYPE_WORLD, TYPE_NGC_MESH, sx#, sy#, sz#, ex#, ey#, ez#)
rem if the ray hit something
if bHit = 1
rem Gets the positions the ray intersected the object
hitX# = RayHitPosPRO( 0, 1 )
hitY# = RayHitPosPRO( 0, 2 )
hitZ# = RayHitPosPRO( 0, 3 )
rem Gets the normals of the surface that was intersected
hitNX# = RayHitNormPRO( 0, 1 )
hitNY# = RayHitNormPRO( 0, 2 )
hitNZ# = RayHitNormPRO( 0, 3 )
rem Get the angles for the the rotation
xrot# = Vec2RotPRO(hitNX#, hitNY#, hitNZ#,1)
yrot# = Vec2RotPRO(hitNX#, hitNY#, hitNZ#,2)
zrot# = Vec2RotPRO(hitNX#, hitNY#, hitNZ#,3)
rem Rotate the lazer object
rotate object lzr, xrot#, yrot#, zrot#
rem Push the hit positions away from the surface a bit
hitX# = hitX# + (hitNX# * 0.20)
hitY# = hitY# + (hitNY# * 0.20)
hitZ# = hitZ# + (hitNZ# * 0.20)
rem Position the decal at the final hit positions
position object lzr, hitX#, hitY#, hitZ#
rem gets the distance of the ray-intersection
rHit# = RayHitDistPRO( 0 )
endif
rem Cast a ray from the lzr start position to it's end position
rem Test against enemy objects, and tests them as ellipsoids
bHit = RayIntersectTypePRO(TYPE_ENEMY, TYPE_NGC_ELLIP, sx#, sy#, sz#, ex#, ey#, ez#)
if bHit = 1
rem if the distance to hit is less than the previous hit distance for the last test
if RayHitDistPRO( 0 ) < rHit#
rem gets the distance of the ray-intersection
rHit# = RayHitDistPRO( 0 )
rem Gets the positions the ray intersected the object
hitX# = RayHitPosPRO( 0, 1 )
hitY# = RayHitPosPRO( 0, 2 )
hitZ# = RayHitPosPRO( 0, 3 )
rem Gets the normals of the surface that was intersected
hitNX# = RayHitNormPRO( 0, 1 )
hitNY# = RayHitNormPRO( 0, 2 )
hitNZ# = RayHitNormPRO( 0, 3 )
rem Passing the normals in, get the Y angle we need to rotate our decal object
xrot# = Vec2RotPRO(hitNX#, hitNY#, hitNZ#,1)
yrot# = Vec2RotPRO(hitNX#, hitNY#, hitNZ#,2)
zrot# = Vec2RotPRO(hitNX#, hitNY#, hitNZ#,3)
rem Rotate the lazer object
rotate object lzr, xrot#, yrot#, zrot#
rem Push the hit positions away from the surface a bit
hitX# = hitX# + (hitNX# * 0.20)
hitY# = hitY# + (hitNY# * 0.20)
hitZ# = hitZ# + (hitNZ# * 0.20)
rem Position the decal at the final hit positions
position object lzr, hitX#, hitY#, hitZ#
endif
endif
endfunction
rem Character Handling Function
function UpdatePlayer()
rem *** Handling the player
rem if left key is hit
if KeyHold(203)
yrotate object player,wrapvalue(object angle y(player)-3.6)
endif
rem if right key is hit
if KeyHold(205)
yrotate object player,wrapvalue(object angle y(player)+3.6)
endif
rem if upkey is pressed
if KeyHold(200)
if player_anim_mode = 0
rem set run animation
hide object player_stand_anim
show object player_run_anim
loop object player_run_anim
player_anim_mode = 1
endif
rem move player object forward
move object player, 3.0
endif
rem if down key is pressed
if KeyHold(208)
if player_anim_mode = 0
rem set run animation
hide object player_stand_anim
show object player_run_anim
loop object player_run_anim
player_anim_mode = 1
endif
rem move player object forward
move object player, -3.0
endif
rem if up key and down key are NOT pressed
if not KeyHold(200)
if not KeyHold(208)
if player_anim_mode = 1
rem Set stand animation
show object player_stand_anim
hide object player_run_anim
loop object player_stand_anim
player_anim_mode = 0
endif
endif
endif
rem if up key and down key are both pressed
if KeyHold(200)
if KeyHold(208)
if player_anim_mode = 1
rem Set stand animation
show object player_stand_anim
hide object player_run_anim
loop object player_stand_anim
player_anim_mode = 0
endif
endif
endif
endfunction
rem Follow-Character Camera handling function
function UpdateFollowCamera()
rem Get the positions of the main player object
xpos# = object position x(player)
ypos# = object position y(player)
zpos# = object position z(player)
rem position 'cam_obj' at the player object coords (a little up on the Y axis)
position object cam_obj, xpos#, ypos# + 30, zpos#
rem Reset the object in collision memory
rem (This is a collision memory routine. This effectively clears
rem all movement from the object and sets it at it's current position)
ResetObjPRO(cam_obj)
rem Get the wrapped Y angle of the player
yrot# = wrapvalue(object angle y(player))
rem Set the camera to follow the player object coords
set camera to follow camera, xpos#, ypos# + 25, zpos#, yrot#, 39, 6, 6.0, 0
rem Point the camera at the player object coords
point camera camera, xpos#, ypos# + 25, zpos#
rem Get the position/rotation of the camera
camx# = camera position x(camera) : camy# = camera position y(camera) : camz# = camera position z(camera)
camrx# = camera angle x(camera) : camry# = camera angle y(camera) : camrz# = camera angle z(camera)
rem place 'cam-obj' at the camera position/rotation
position object cam_obj, camx#, camy#, camz#
rotate object cam_obj, camrx#, camry#, camrz#
rem NOTE: The camera was set at the player position with the ResetObjPRO() command
rem (which also cleared the movement data for the object)
rem Then we positioned the object back at the camera location. When the system
rem returns from this function the "RunCollisionPRO()" function will eventually
rem be called. And it will see the movement of the camera object from the player's
rem body position to the real camera position. The camera object
rem will then impact any wall between the player's body and the camera follow
rem position. (this keeps the camera from going through walls)
rem
rem So what's the point to the "ResetObjPRO()" command?
rem Imagine for a moment that we didn't call ResetObjPRO()...
rem When you try to move it to the player's body, and then project it back to
rem the follow position, and then call the "RunCollisionPRO()" command,
rem the collision system only sees the change from the last follow position
rem to the new follow position. So it could get stuck behind something.
rem By calling ResetObjPRO() the object is reset to the position it is at
rem when we call ResetObjPRO(). So we placed it at the player's body, then
rem called ResetObjPRO() and the internal collision object is immediately updated
rem and the movement data is immediately cleared. So if it's behind
rem something it will not matter because we reset it at the player's position.
rem Then we back it up. Then RunCollisionPRO() is finally called. Making it
rem impossible to get stuck behind anything.
endfunction
rem Free-Flight Camera handling function
function UpdateFreeCamera()
` Mousemove code
movex# = mousemovex() / 2
movey# = mousemovey() / 2
dx#=dx#+movey#/4 : cy#=wrapvalue(cy#+movex#*0.2)
if dx#>90 then dx#=90
if dx#<-90 then dx#=-90
cx#=wrapvalue(dx#)
rem Gets the new rotation values for the camera
cx# = cx# + object angle x(cam_obj)
cy# = cy# + object angle y(cam_obj)
rem Rotate the camera
Rotate Object cam_obj, cx#, cy#, 0
rem Move the camera from keyboard input
if UpKey() then move object cam_obj, cam_speed#
if DownKey() then move object cam_obj, -cam_speed#
rem set camera speed
if KeyHold(30) then cam_speed#=cam_speed#+0.1
if KeyHold(44) then cam_speed#=cam_speed#-0.1
endfunction
