;a;fps level, graphics & code by rob cummings (rob@...)
;job offers welcome as always
;
;you may learn from this and use the code however you may not
;re-use graphics without permission.
;unoptimised clean code, minimal comments
;framerate variables
Const FPS=85
Const debug=0
;collision variables
Global col_level=1,col_player=2,col_bullet=3
;player variables
Global pitch#,yaw#,mxspd#,myspd#,vx#,vy#,vz#,camera,player,gun,pick,gunsight,guntarget,hand
;other vars
Global firetex,firetexpos#,bob#,target,scorchsprite,plasmasprite,shockwavesprite,recoil#
Global cameraheight#=5 ;height of player eyes
Global playerheight#=6 ;height of collision sphere
Global playerradius#=3 ;radius of collision sphere
xres=800:yres=600:depth=32:mode=1
Graphics3D xres,yres,depth,mode
HidePointer
;setup
camera=CreateCamera()
CameraRange camera,0.2,400
CameraFogMode camera,0
;hud
tex=LoadTexture("target.png",2)
TextureBlend tex,2
target=CreateSprite()
EntityTexture target,tex
EntityFX target,1
EntityOrder target,-1
EntityBlend target,3
EntityParent target,camera
MoveEntity target,0,0,12
EntityAlpha target,0.8
;player
player=CreatePivot()
hand=CreatePivot()
EntityParent hand,camera
MoveEntity hand,.8,-.8,.8
lite = CreateLight(1) ; change this to 2 or 3 to see different lights
LightRange lite,15000
LightColor lite,255,255,255
;level
level=LoadAnimMesh("testlevel1.b3d")
;level collisions
EntityType level,col_level,1
ScaleEntity level,.03,.03,.03
;set up picking - this is because shooting and stair climbing needs pickable geometry. You can use picks for other stuff too
ent = level ; specify your level
While ent
EntityPickMode ent,2
ent = NextChild(ent)
Wend
;other collisions
EntityType player,col_player
EntityRadius player,playerradius,playerradius/2
Collisions col_player,col_level,2,2
PositionEntity player,0,10,0
PositionEntity level,0,0,0
ResetEntity player
;mainloop with standard timing code
period=1000/FPS
time=MilliSecs()-period
While Not KeyHit(1)
Repeat
elapsed=MilliSecs()-time
Until elapsed
ticks=elapsed/period
tween#=Float(elapsed Mod period)/Float(period)
For k=1 To ticks
time=time+period
If k=ticks Then CaptureWorld
;basic game tasks
UpdateWorld
UpdatePlayer
Next
RenderWorld
;hit spacebar to save a screenshot
If KeyHit(57) n=n+1 : SaveBuffer(BackBuffer(),n+".bmp")
Flip
Wend
End
Function UpdatePlayer()
;look
mxspd=MouseXSpeed()*0.25
myspd=MouseYSpeed()*0.25
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
pitch=pitch+myspd
yaw=yaw-mxspd
If pitch<-90 Then pitch=-90
If pitch>90 Then pitch=90
RotateEntity camera,pitch,yaw,0
RotateEntity player,0,yaw,0
;movement
If KeyDown(17)
vz=vz+0.04
ElseIf KeyDown(31)
vz=vz-0.04
EndIf
vz=vz*0.9
If KeyDown(30)
vx=vx-0.04
ElseIf KeyDown(32)
vx=vx+0.04
EndIf
vx=vx*0.9
;steps and floor collisions
pick=LinePick (EntityX(player),EntityY(player),EntityZ(player),0,-playerheight,0)
If pick
PositionEntity player,EntityX(player),PickedY()+playerheight#,EntityZ(player)
vy=0
EndIf
vy=vy-.2
vy=vy*0.9
;move player pivot
MoveEntity player,vx,0,vz
TranslateEntity player,0,vy,0
;move camera + player meshes smoothly
PositionEntity camera,EntityX(player),EntityY(camera),EntityZ(player)
TranslateEntity camera,0,(EntityY(player)-(EntityY(camera)-cameraheight))*0.1,0
End Function
Function NextChild(ent)
If CountChildren(ent)>0
Return GetChild(ent,1)
EndIf
Local foundunused=False
Local foundent = 0, parent,sibling
While foundunused=False And ent<>0
parent = GetParent(ent)
If parent<>0
If CountChildren(parent)>1
If GetChild(parent,CountChildren(parent))<>ent
For siblingcnt = 1 To CountChildren(parent)
sibling = GetChild(parent,siblingcnt)
If sibling=ent
foundunused = True
foundent = GetChild(parent,siblingcnt+1)
EndIf
Next
EndIf
EndIf
EndIf
ent = parent
Wend
Return foundent
End Function
Fixed version up! the old version had bad code for setting up pickable geometry. This version solves the problem and adds a comment. I am also changing the original source to reflect this now...
:)