FPS Level with Source


👉 BlitzCoder will be building a new platform and other plans to preserve and continue the Blitz legacy.

To be able to achieve this goal, we need your support by becoming a Patreon Paid Member 👈

 

Tweet blitz3d code-archives miscellaneous
BlitzCoder

A fps level and graphics, you may learn from this and use the code however you may not re-use graphics without permission. unoptimised clean code, minimal comments

Author: Rob Cummings

Download

;fps level, graphics & code by rob cummings
;
;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#=3.5    ;height of player eyes
Global playerheight#=4      ;height of collision sphere
Global playerradius#=2      ;radius of collision sphere

;types
Type plasma
    Field ent,rot#
End Type

Type scorch
    Field ent,life#
End Type

Type shockwave
    Field ent,life#,size#
End Type

;display choice
AppTitle "FPS Example"
Text 20,2,"Choose mode by pressing a number key:"
Text 20,32,"(1) 800,600   windowed  "
Text 20,48,"(2) 800,600   fullscreen"
Text 20,64,"(3) 1024,768  fullscreen"
Text 20,80,"(4) 1600,1200 fullscreen"
Repeat
    If KeyDown(2) Or debug Then xres=800:yres=600:mode=2:Exit
    If KeyDown(3) Then xres=800:yres=600:mode=1:Exit
    If KeyDown(4) Then xres=1024:yres=768:mode=1:Exit
    If KeyDown(5) Then xres=1600:yres=1200:mode=1:Exit
    VWait
Forever
Graphics3D xres,yres,0,mode
HidePointer

;setup
camera=CreateCamera()
CameraRange camera,0.2,400
CameraFogMode camera,1
CameraFogColor camera,140,140,120
CameraFogRange camera,-100,800

;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

;gun
gun=LoadAnimMesh("gun.b3d")
firetex=LoadTexture("fury.png")
For i=1 To CountChildren(gun)
    If EntityName(GetChild(gun,i))="red" EntityTexture GetChild(gun,i),firetex
Next
gunsight=CreatePivot()
EntityParent gunsight,camera
MoveEntity gunsight,-2,2,500
guntarget=CreatePivot()

;weapon effects - plasma
tex=LoadTexture("plasma.png",2)
TextureBlend tex,2
plasmasprite=CreateSprite()
EntityTexture plasmasprite,tex
EntityFX plasmasprite,1
EntityBlend plasmasprite,3
EntityAlpha plasmasprite,0.8
ScaleSprite plasmasprite,1,2
HideEntity plasmasprite

;weapon effects - scorch
tex=LoadTexture("scorch.png",2)
scorchsprite=CreateSprite()
EntityTexture scorchsprite,tex
EntityFX scorchsprite,1
EntityAlpha scorchsprite,0.8
ScaleSprite scorchsprite,1,2
SpriteViewMode scorchsprite,2
HideEntity scorchsprite

;weapon effects - shockwave
tex=LoadTexture("shockwave.png",2)
TextureBlend tex,2
shockwavesprite=CreateSprite()
EntityTexture shockwavesprite,tex
EntityFX shockwavesprite,1
EntityBlend shockwavesprite,3
EntityAlpha shockwavesprite,0.8
ScaleSprite shockwavesprite,1,2
SpriteViewMode shockwavesprite,2
HideEntity shockwavesprite

;level
level=LoadAnimMesh("final.b3d")

;level collisions
EntityType level,col_level,1

;remove collision on sky (a hack cos I didn't want to go back and change the level - not necessary)
sky=FindChild(GetChild(level,1),"Plane02")
EntityType sky,0

;picks
;level has a root node, so get first child of that
child=GetChild(level,1)
For i=1 To CountChildren(child)
    EntityPickMode GetChild(child,i),2
Next

;other collisions
EntityType player,col_player
EntityRadius player,playerradius,playerradius/2
Collisions col_player,col_level,2,2
PositionEntity player,100,10,-65
ResetEntity player
Collisions col_bullet,col_level,2,1

;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
        UpdatePlasma
        UpdateScorch
        UpdateShockwave

    Next

    RenderWorld
    Text 0,20, "zoom: "+CountChildren( gun) 
    ;hit spacebar to save a screenshot
    If KeyHit(57) n=n+1 : SaveBuffer(BackBuffer(),n+".bmp")

    Text 0,20, "zoom: "+CountChildren(gun)
    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(200)
        vz=vz+0.05
    ElseIf KeyDown(208)
        vz=vz-0.05
    EndIf
    vz=vz*0.9
    If KeyDown(203)
        vx=vx-0.05
    ElseIf KeyDown(205)
        vx=vx+0.05
    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-0.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

    ;gun
    x1#=EntityX(gun,1)
    y1#=EntityY(gun,1)
    z1#=EntityZ(gun,1)
    x2#=EntityX(gunsight,1)
    y2#=EntityY(gunsight,1)
    z2#=EntityZ(gunsight,1)
    pick=LinePick(x1,y1,z1,x2-x1,y2-y1,z2-z1)
    If pick
        PositionEntity guntarget,PickedX(),PickedY(),PickedZ()
    EndIf

    PositionEntity gun,EntityX(hand,1),EntityY(hand,1)-((Cos(bob)*Sqr(vx*vx+vz*vz))*.2),EntityZ(hand,1)
    MoveEntity gun,0,0,recoil#
    PointEntity gun,guntarget
    PositionTexture firetex,firetexpos,firetexpos
    firetexpos=firetexpos+0.01
    bob=bob+4
    recoil=recoil*.9

    ;firing code
    If MouseHit(1) ShootPlasma() : recoil=-.6

End Function

;this function will spawn a bullet
Function ShootPlasma()
    p.plasma=New plasma
    p\ent=CopyEntity(plasmasprite)
    PositionEntity p\ent,EntityX(gun),EntityY(gun),EntityZ(gun)
    PointEntity p\ent,guntarget
    MoveEntity p\ent,0,0,-1
    p\rot=Rand(360)
    EntityType p\ent,col_bullet
End Function

;updates plasma bullets
Function UpdatePlasma()
    For p.plasma=Each plasma
        MoveEntity p\ent,0,0,2.5
        RotateSprite p\ent,p\rot
        p\rot=p\rot+20
        If EntityCollided(p\ent,col_level)

            ;find angle of collision based on the normals of the impact
            nx#=0
            ny#=0
            nz#=0
            num#=CountCollisions(p\ent)
            For i=1 To num
                nx=nx+CollisionNX(p\ent,i)
                ny=ny+CollisionNY(p\ent,i)
                nz=nz+CollisionNZ(p\ent,i)
                x#=x#+CollisionX(p\ent,i)
                y#=y#+CollisionY(p\ent,i)
                z#=z#+CollisionZ(p\ent,i)
            Next

            ;position and normals of impact are averaged in case of an odd angle
            nx=nx/num
            ny=ny/num
            nz=nz/num
            x=x/num
            y=y/num
            z=z/num

            ;scorch
            s.scorch=New scorch
            s\ent=CopyEntity(scorchsprite)
            s\life#=0.8
            RotateSprite s\ent,Rand(360)
            temp#=1+Rnd(2)
            ScaleSprite s\ent,temp#,temp#
            PositionEntity s\ent,x,y,z

            ;align to vector will align an entity to normals too
            AlignToVector s\ent,-nx,-ny,-nz,0
            MoveEntity s\ent,0,0,-0.5

            ;shockwave
            w.shockwave=New shockwave
            w\ent=CopyEntity(shockwavesprite)
            w\life#=2
            w\size=0.2
            RotateSprite w\ent,Rand(360)
            PositionEntity w\ent,x,y,z
            RotateEntity w\ent,EntityPitch(s\ent),EntityYaw(s\ent),0
            MoveEntity w\ent,0,0,-0.5

            FreeEntity p\ent
            Delete p
        EndIf
    Next
End Function

Function UpdateScorch()
    For s.scorch=Each scorch
        EntityAlpha s\ent,s\life
        s\life=s\life-0.005
        If s\life<0
            FreeEntity s\ent
            Delete s
        EndIf
    Next
End Function

Function UpdateShockwave()
    For s.shockwave=Each shockwave
        EntityAlpha s\ent,s\life
        ScaleSprite s\ent,s\size,s\size
        s\life=s\life-0.06
        s\size=s\size+0.1
        If s\life<0
            FreeEntity s\ent
            Delete s
        EndIf
    Next
End Function

Image

Hrobo88 commented:

Nice!
I could possibly use this as a way to start my own FPS game

Reply To Topic (minimum 10 characters)

Please log in to reply