[bb] FPSNet by Jeremy Alessi [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : FPSNet
Author : Jeremy Alessi
Posted : 1+ years ago

Description : This is a simple Networked FPS that includes server listing/matching through GNet and uses the built in DirectPlay features of Blitz3D.

Code :
Code (blitzbasic) Select
;====== FPSNet: A NETWORKED FIRST PERSON SHOOTER EXAMPLE ==================
;====== UTILIZING ONLY BUILT IN BLITZ3D FEATURES ==========================
;====== A CODESKETCH BY JEREMY ALESSI =====================================
;====== THANKS MARK SIBLY FOR GNET ========================================

;====== WASD OR CURSORS MOVE, MOUSE LOOKS, LEFT MOUSE BUTTON SHOOTS =======
;====== SPACE BAR OR 0 ON NUMPAD JUMPS ====================================
;====== PRESS 2 TO UNLOCK MOUSE FROM CENTER (USEFUL TO PLAY ===============
;====== AND ALSO BE ABLE TO MULTITASK IF NEED BE) PRESS 1 TO RELOCK =======
;====== MOUSE BACK TO CENTER OF SCREEN ====================================
;====== YEAH EVERYONE HAS THE SOURCE ... DON'T CHEAT! =====================


;====== INCLUDES ==========================================================

;Include "gnet_inc.bb" This is included at the bottom of this source!

;==========================================================================



;====== GRAPHICS ==========================================================

Graphics3D(640, 480, 16, 2)
SetBuffer BackBuffer()
HidePointer

;==========================================================================



;====== COLLISIONS ========================================================

Global BODY = 1
Global SCENE = 2
Collisions(BODY,SCENE, 2, 2)
Collisions(BODY,BODY, 2, 2)

;==========================================================================



;====== GLOBALS ===========================================================

Global gameState$ = "Title Screen"

;Mousehit Vars
Global mb1pressed, mb2pressed

;Keyhit Vars
Global upKeyPressed, downKeyPressed, leftKeyPressed, rightKeyPressed, enterKeyPressed, spaceKeyPressed

;Font Vars
Global font, bigFont

;Menu Var
Global menuCount

;Server Vars
Global serverCount
Global serverPointer

;Local Player Network Vars
Global localPlayerName$, localPlayerPointer

;Scenery Vars
Global level,copySprite

;Camera Var
Global camera

;Player Gameplay Vars
Global health#, shot, shotTimer#, positionUpdateTimer#, serverRefreshTimer#, hosting
Global vY#,centerMouse = True

;==========================================================================



;====== INCOMING ==========================================================

Dim incoming$(100)

;==========================================================================



;====== TYPES =============================================================

Type Player

Field iD, name$, mesh[10], score

End Type

Type particle

Field mesh, name$, alpha#
Field vX#, vY#, vZ#

End Type

;==========================================================================



;====== INITIAL SETUP =====================================================

Setup("Title Screen")

;==========================================================================



;==========================================================================
.Main
;====== RUN ===============================================================
period=1000 / 30
tweentime = MilliSecs()-period
While 1
;====== CALCULATE TWEEN ===================================================
Repeat
elapsed = MilliSecs() - tweentime
Until elapsed
ticks = elapsed/period
tween# = Float(elapsed Mod period) / Float(period)
;==========================================================================

;====== MAIN LOOP =========================================================
For k=1 To ticks
tweentime = tweentime+period
If k = ticks Then CaptureWorld
If KeyDown(1)
If Not GNET_RemoveServer("FPSNet")
If hosting = True
RuntimeError "Failed to remove server"
EndIf
EndIf
ClearWorld()
End
EndIf
UpdateLogic()
UpdateWorld
Next
RenderWorld(tween#)
Draw()
Flip
Wend
;===========================================================================



;====== UPDATE LOGIC =======================================================

Function UpdateLogic()

Select gameState$

Case "Title Screen"
UpdateInput()
UpdateTitleScreen()
Case "Game"
UpdateLights()
UpdateCamera()
UpdatePlayerMovement()
UpdateParticles()
UpdateNetwork()
UpdateCenterMouse()
End Select

End Function

;===========================================================================



;====== DRAW ===============================================================

Function Draw()

Select gameState$

Case "Title Screen"
DrawTitleScreen()
Case "Game"
DrawGamePlay()

End Select

End Function

;===========================================================================



;====== UPDATE INPUT =======================================================

Function UpdateInput()

mb1pressed = MouseHit(1)

mb2pressed = MouseHit(2)

upKeyPressed = KeyHit(17) Or KeyHit(200)

downKeyPressed = KeyHit(31) Or KeyHit(208)

leftKeyPressed = KeyHit(30) Or KeyHit(203)

rightKeyPressed = KeyHit(32) Or KeyHit(205)

enterKeyPressed = KeyHit(28)

spaceKeyPressed = KeyHit(57)


End Function

;===========================================================================



;====== UPDATE CENTER MOUSE ================================================

Function UpdateCenterMouse()

If centerMouse = True
MoveMouse(CorrectX(320), CorrectY(240))
EndIf
If KeyHit(2)
centerMouse = True
EndIf
If KeyHit(3)
centerMouse = False
EndIf

End Function

;===========================================================================



;====== UPDATE TITLE SCREEN ================================================

Function UpdateTitleScreen()

If upKeyPressed And menuCount > 0
menuCount = menuCount - 1
EndIf

If downKeyPressed And menuCount < serverCount - 1
menuCount = menuCount + 1
EndIf

If enterKeyPressed
gns.GNET_Server = Object.GNET_Server(serverPointer)
If JoinNetGame(gnsserver$, gnsip$)
FlushKeys
Color(255,0,0)
Locate(200,130)
localPlayerName$ = Input("Name - ")
Delay(500)
FlushKeys
p.Player = New Player
localPlayerPointer = Handle(p.Player)
piD = CreateNetPlayer(localPlayerName$)
Setup("Game")
hosting = False
EndIf
EndIf

If spaceKeyPressed
FlushKeys
Color(255,0,0)
Locate(200,130)
localPlayerName$ = Input("Name - ")
Delay(500)
FlushKeys
If HostNetGame(localPlayerName$) = 2

If GNET_AddServer("FPSNet", localPlayerName$)
p.Player = New Player
localPlayerPointer = Handle(p.Player)
piD = CreateNetPlayer(localPlayerName$)
Setup("Game")
hosting = True
serverRefreshTimer# = MilliSecs()
Else
RuntimeError("Failed to Add Server!")
EndIf

Else

RuntimeError("Failed to Create Net Game!")

EndIf


EndIf



End Function

;===========================================================================



;====== UPDATE PLAYER MOVEMENT =============================================

Function UpdatePlayerMovement()

p.Player = Object.Player(localPlayerPointer)
If KeyDown(17) Or KeyDown(200)
MoveEntity(pmesh[1], 0, 0, .5)
EndIf
If KeyDown(31) Or KeyDown(208)
MoveEntity(pmesh[1], 0, 0, -.5)
EndIf
If KeyDown(30) Or KeyDown(203)
MoveEntity(pmesh[1], -.5, 0, 0)
EndIf
If KeyDown(32) Or KeyDown(205)
MoveEntity(pmesh[1], .5, 0, 0)
EndIf

numColls = CountCollisions(pmesh[1])
If (KeyDown(57) Or KeyDown(82)) And numColls > 0
vY# = .2
TranslateEntity(pmesh[1],0, vY#, 0)
EndIf
If numColls = 0
TranslateEntity(pmesh[1],0, vY#, 0)
vY# = vY# - .01
EndIf

RotateEntity(pmesh[1], 0, EntityYaw(pmesh[1]) - MouseXSpeed(), 0)

End Function

;===========================================================================



;====== UPDATE LIGHTS ======================================================

Function UpdateLights()

TurnEntity(FindChild(level,"Light Pivot"), 0, 10, 0)

End Function

;===========================================================================



;====== UPDATE CAMERA ======================================================

Function UpdateCamera()

shot = 0
If MouseDown(1)
If shotTimer# + 200 < MilliSecs()
shot = CameraPick(camera, CorrectX(320), CorrectY(240))
shotTimer# = MilliSecs()
If shot
CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 50, 50, 50, 10)
p.Player = Object.Player(localPlayerPointer)
SendNetMsg(4,PickedX() + "," + PickedY() + "," + PickedZ() + "-",piD,0,0)
EndIf
EndIf
EndIf

RotateEntity(camera,EntityPitch(camera) + MouseYSpeed(),0,0)
If EntityPitch(camera) > 90
RotateEntity(camera, 90, 0, 0)
EndIf
If EntityPitch(camera) < - 90
RotateEntity(camera, -90, 0, 0)
EndIf

End Function

;===========================================================================



;====== UPDATE NETWORK =====================================================

Function UpdateNetwork()

While RecvNetMsg()

Select NetMsgType()

Case 1
For p.Player = Each Player
If piD = NetMsgFrom()
DecodeIncomingMessage(NetMsgData$())
PositionEntity(pmesh[1], incoming$(1), incoming$(2), incoming$(3))
RotateEntity(pmesh[1], incoming$(4), incoming$(5), 0)
If incoming$(6) <> ""
pscore = incoming$(6)
EndIf
EndIf
Next
Case 2
p.Player = Object.Player(localPlayerPointer)
CreateSomeParticles(EntityX(pmesh[1]), EntityY(pmesh[1]), EntityZ(pmesh[1]), 255, 0, 0, 10)
health = health - 5
If health <= 0
health = 100
PositionEntity(pmesh[1],5,1,Rand(0, 50))
SendNetMsg(3, "1", piD, NetMsgFrom(), 1)
CreateSomeParticles(EntityX(pmesh[1]), EntityY(pmesh[1]), EntityZ(pmesh[1]), 255, 0, 0, 100)
SendNetMsg(5, "1",piD, 0, 0)
EndIf
Case 3
p.Player = Object.Player(localPlayerPointer)
pscore = pscore + 1
Case 4
DecodeIncomingMessage(NetMsgData$())
CreateSomeParticles(incoming$(1), incoming$(2), incoming$(3), 50, 50, 50, 10)
Case 5
For p.Player = Each Player
If piD = NetMsgFrom()
CreateSomeParticles(EntityX(pmesh[1]), EntityY(pmesh[1]), EntityZ(pmesh[1]), 255, 0, 0, 100)
EndIf
Next
Case 100
p.Player = New Player
piD = NetMsgFrom()
pmesh[1] = CreateSphere(8)
p
ame$ = NetPlayerName$(piD)
EntityColor(pmesh[1], 0, 255, 0)
PositionEntity(pmesh[1], 5, 1.5, Rand(50,100))
EntityType(pmesh[1],BODY)
EntityRadius(pmesh[1], 1.5)
EntityPickMode(pmesh[1], 2)

pmesh[2] = CreateCube(pmesh[1])
PositionEntity(pmesh[2], 1, -.5, 1)
ScaleEntity(pmesh[2], .1, .1, .4)
EntityColor(pmesh[2], 20, 20, 20)
Case 101
For p.Player = Each Player
If piD = NetMsgFrom()
FreeEntity(pmesh[1])
Delete(p)
EndIf
Next
Case 102
GNET_AddServer("FPSNet", localPlayerName$)
hosting = True

End Select

Wend

p.Player = Object.Player(localPlayerPointer)
If positionUpdateTimer# + 50 < MilliSecs()
SendNetMsg(1, EntityX(pmesh[1]) + "," + EntityY(pmesh[1]) + "," + EntityZ(pmesh[1]) + "," + EntityPitch(camera) + "," + EntityYaw(pmesh[1]) + "," + pscore + "-", piD, 0, 0)
positionUpdateTimer# = MilliSecs()
EndIf

For op.Player = Each Player
If shot = opmesh[1]
CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10)
SendNetMsg(2, "", piD, opiD, 0)
EndIf
Next

If hosting = True
If serverRefreshTimer# + 250000 < MilliSecs()
GNET_RefreshServer( "FPSNet",localPlayerName$ )
serverRefreshTimer# = MilliSecs()
EndIf
EndIf

End Function

;===========================================================================



;====== UPDATE PARTICLES ===================================================

Function UpdateParticles()

For p.particle = Each particle
If palpha# <= 0
FreeEntity(pmesh)
Delete(p)
Else
pvY# = pvY# - .01
TranslateEntity(pmesh,pvX#, pvY#, pvZ#)
palpha# = palpha# - .02
EntityAlpha(pmesh, palpha#)
EndIf
Next

End Function

;===========================================================================


;====== DRAW TITLE SCREEN ==================================================

Function DrawTitleScreen()

Cls
FPSNetText(font, 320, 0, String$("+",80), 1, 1, 100, 100, 100)
FPSNetText(font, 320, 480, String$("+",80), 1, 1, 100, 100, 100)

For i = 0 To 640 Step 640
For j = 10 To 470 Step 10
FPSNetText(font, i, j, "+", 1, 1, 100, 100, 100)
Next
Next

FPSNetText(bigFont, 320, 30, "FPSNet:", 1, 1, 255, 0, 0)
FPSNetText(font, 320, 60, "A NETWORKED First Person Shooter Example", 1, 1, 100, 100, 100)
FPSNetText(font, 320, 80, "Press Up/Down to Select a Game to Join!", 1, 1, 100, 100, 100)
FPSNetText(font, 320, 100, "Press Space to Host a New Game!", 1, 1, 100, 100, 100)
FPSNetText(font, 320, 120, "Games In Progress:" , 1, 1, 200, 255, 150)

serverCount = 0
For gns.GNET_Server = Each GNET_Server

Select serverCount

Case menuCount
FPSNetText(font, 320, 160 + 20 * serverCount, gnsserver$ + " - Press Enter to Join ...", 1, 1, 255, 255, 255)
serverPointer = Handle(gns)
Default
FPSNetText(font, 320, 160 + 20 * serverCount, gnsserver$, 1, 1, 100, 100, 100)

End Select
serverCount = serverCount + 1

Next

End Function

;===========================================================================



;====== DRAW GAMEPLAY ======================================================

Function DrawGamePlay()

FPSNetText(font, 320, 240, "+", 1, 1, 255, 255, 255)
p.Player = Object.Player(localPlayerPointer)
FPSNetText(font, 0, 0, "Your Score - " + pscore, 0, 0, 255, 0, 0)

For p.Player = Each Player
If Handle(p.Player) <> localPlayerPointer
CameraProject(camera, EntityX(pmesh[1]), EntityY(pmesh[1]), EntityZ(pmesh[1]))
FPSNetText(font, ProjectedX(), ProjectedY() - 20, p
ame$ + "  -  " + pscore, 1, 1, 255, 255, 255)
EndIf
Next

End Function

;===========================================================================



;====== CREATE SOME PARTICLES ==============================================

Function CreateSomeParticles(x, y, z, r, g, b, numParticles)

For i = 1 To numParticles
p.Particle = New Particle
pmesh = CopyEntity(copySprite)
PositionEntity(pmesh,x, y, z)
EntityColor(pmesh, r, g, b)
pvX# = Rnd(-.2, .2)
pvY# = Rnd(.2)
pvZ# = Rnd(-.2, .2)
palpha = 1
Next

End Function

;===========================================================================


;====== SETUP ==============================================================

Function Setup(mode$)

Select mode$

Case "Title Screen"

font = LoadFont("Arial",20,1)
bigFont = LoadFont("Arial",50,1)
GNET_ListServers()

Case "Game"

gameState$ = "Game"

p.Player = Object.Player(localPlayerPointer)
pmesh[1] = CreatePivot()
PositionEntity(pmesh[1], 5, 1.5, Rand(0, 50))
EntityType(pmesh[1],BODY)
EntityRadius(pmesh[1], 1.5)
health = 100
pscore = 0
p
ame$ = localPlayerName$

camera = CreateCamera(pmesh[1])
CameraRange(camera,.1, 500)

pmesh[2] = CreateCube(camera)
PositionEntity(pmesh[2], 1, -.5, 1)
ScaleEntity(pmesh[2], .1, .1, .4)
EntityColor(pmesh[2], 20, 20, 20)

LoadLevel()
PointEntity(pmesh[1], level)
MoveMouse(CorrectX(320), CorrectY(240))




End Select

End Function

;===========================================================================



;====== LOAD LEVEL =========================================================

Function LoadLevel()

copySprite = CreateSprite()
ScaleSprite(copySprite, .1, .1)
EntityFX(copySprite, 1+8)
HideEntity(copySprite)

level = CreatePlane(16)
EntityPickMode(level, 2)

For i = -1 To 1 Step 2
For j = -4 To 4
cube = CreateCube(level)
EntityType(cube, SCENE)
EntityPickMode(cube, 2)
EntityColor(cube, 100, 100, 100)
PositionEntity(cube, i * 10, 1, j * 10)
Next
Next

For i = 1 To 8
cube = CreateCube(level)
EntityType(cube, SCENE)
EntityPickMode(cube, 2)
EntityColor(cube,100,100,100)
PositionEntity(cube, 0, i * 2, i * 5)
Next

For i = 1 To 8
cube = CreateCube(level)
EntityType(cube, SCENE)
EntityPickMode(cube, 2)
EntityColor(cube,100,100,100)
PositionEntity(cube, 0, i * 2, i * -5)
Next

EntityType(level,SCENE)

lightPivot = CreatePivot(level)
NameEntity(lightPivot,"Light Pivot")

light = CreateLight(3,lightPivot)
NameEntity(light, "light1")
PositionEntity(light,25, 25, 0)
RotateEntity(light, 90, 0, 0)
LightRange(light, 500)
LightColor(light, 255, 0, 0)

light = CreateLight(3,lightPivot)
NameEntity(light, "light2")
PositionEntity(light,-25, 25, 0)
RotateEntity(light, 90, 0, 0)
LightRange(light, 500)
LightColor(light, 0, 0, 255)

light = CreateLight(3,lightPivot)
NameEntity(light, "light3")
PositionEntity(light,0, 25, 25)
RotateEntity(light, 90, 0, 0)
LightRange(light, 500)
LightColor(light, 0, 255, 0)

End Function

;===========================================================================



;====== FPSNET TEXT ========================================================

Function FPSNetText(fontType, X, Y, theText$, centerX = 0, centerY = 0,r = 255, g = 255, b = 255)

Color(r, g, b)
SetFont(fontType)
Text(CorrectX(X), CorrectY(Y), theText$, centerX, centerY)

End Function

;==========================================================================



;====== CORRECTX ==========================================================

Function CorrectX(pixel)

Return (pixel * GraphicsWidth() / 640)

End Function

;==========================================================================



;====== CORRECTY ==========================================================

Function CorrectY(pixel)

Return (pixel * GraphicsHeight() / 480)

End Function

;==========================================================================



;====== DECODE INCOMING MESSAGE ===========================================

Function DecodeIncomingMessage(message$)

For i = 1 To 100
incoming$(i) = ""
Next
i = 1
part = 1
incoming$(part) = Mid(message$, i, 1)
i = i + 1
While Mid(message$, i, 1)<>"-"
While Mid(message$, i, 1)<>","
incoming$(part)=incoming$(part)+Mid(message$, i, 1)
i = i + 1
If Mid(message$, i, 1)="-"
Exit
EndIf
Wend
If Mid(message$, i, 1)=","
i = i + 1
part = part + 1
incoming$(part) = Mid(message$, i, 1)
i = i + 1
EndIf
Wend

End Function

;==========================================================================



;====== GNET SOURCE CODE ==================================================


Const GNET_HOST$="www.blitzbasic.com"
Const GNET_PORT=80
Const GNET_GET$="/gnet/gnet.php"

Type GNET_Server
Field game$,server$,ip$
End Type

Function GNET_Esc$( t$ )
t$=Replace$( t$,"&","" )
t$=Replace$( t$,"%","" )
t$=Replace$( t$,"'","" )
t$=Replace$( t$,Chr$(34),"" )
t$=Replace$( t$," ","_" )
Return t$
End Function

Function GNET_Open( opt$ )
t=OpenTCPStream( GNET_HOST$,GNET_PORT )
If Not t Return 0

WriteLine t,"GET "+GNET_GET$+"?opt="+opt$+" HTTP/1.0"
WriteLine t,"HOST: "+GNET_HOST$
WriteLine t,""

While ReadLine$(t)<>""
Wend

Return t
End Function

Function GNET_Exec( opt$,game$,server$ )
opt$=opt$+"&game="+GNET_Esc$(game$)
If server$<>"" opt$=opt$+"&server="+GNET_Esc$(server$)
t=GNET_Open( opt$ )
If Not t Return 0

ok=False
If( ReadLine$(t)="OK" ) ok=True

CloseTCPStream t
Return ok
End Function

Function GNET_Ping$()
t=GNET_Open( "ping" )
If Not t Return 0

ip$=ReadLine$(t)

CloseTCPStream t
Return ip$
End Function

Function GNET_AddServer( game$,server$="" )
Return GNET_Exec( "add",game$,server$ )
End Function

Function GNET_RefreshServer( game$,server$="" )
Return GNET_Exec( "ref",game$,server$ )
End Function

Function GNET_RemoveServer( game$ )
Return GNET_Exec( "rem",game$,"" )
End Function

Function GNET_ListServers( game$="" )
Delete Each GNET_Server
t=GNET_Open( "list" )
If Not t Return 0

Repeat
t_game$=ReadLine$(t)
If t_game$="" Exit
t_server$=ReadLine$(t)
t_ip$=ReadLine(t)
If game$="" Or game$=t_game$
p.GNET_Server=New GNET_Server
pgame$=t_game$
pserver$=t_server$
pip$=t_ip$
EndIf
Forever

CloseTCPStream t
Return 1

End Function

;==========================================================================


Comments :


Dirk Krause(Posted 1+ years ago)

 Great! works like a charm!


Jeremy Alessi(Posted 1+ years ago)

 Need more people to play!


N(Posted 1+ years ago)

 Actually, I played with bot builder, but that git cheats.


Jeremy Alessi(Posted 1+ years ago)

 Yeah, he was cheating ... then he stopped though.  I really want to get like an 8 person mosh going.


Dirk Krause(Posted 1+ years ago)

 just name time and place (and timezone :-). Oh, and please implememt a chatting feature :-)).


Jeremy Alessi(Posted 1+ years ago)

 Yeah, I was going to add chat but then I was like eh maybe too much just for a simple demo, but I think I'll try and crank it all up a notch and make it more full featured.


Regular K(Posted 1+ years ago)

 Cna someone make this into an exe so I can play?I dont have B3D


Dirk Krause(Posted 1+ years ago)

 Sent it to you.


Regular K(Posted 1+ years ago)

 Well, hotmail is being dumb and McAffee is whining about something with the file you sent me! Its a txt now, with some German in it.


Dirk Krause(Posted 1+ years ago)

 I'll zip it and send it again.[EDIT] your mailbox is full or your limit is under 600k which is the file size.


Jeremy Alessi(Posted 1+ years ago)

 Get the current .exe here:<a href="http://www.leadfootproductions.com/FPSNet/FPSNet.exe" target="_blank">http://www.leadfootproductions.com/FPSNet/FPSNet.exe</a>


CodeOrc(Posted 1+ years ago)

 Help, I can't play!Ok, I ma behind a Netopia 9100 router, and it is my DHCP server. I can load the game on my computers, and I can see the game on the BB/Gnet server list.The problem is when I press enter to play a game I am hosting, no matter what computer I am using it does not connect.Does this game require you to have "real world" IP's and not "LAN-192.168's"?thanx!


_PJ_(Posted 1+ years ago)

 CodeOrc - do you have a firewall preventing BB or the exe from connecting?


Mustang(Posted 1+ years ago)

 Hey, this was cool! :)


LiamShearer(Posted 1+ years ago)

 I know this is 3 years old, but could I have the source of that PHP file on the blitzbasic.com server, so I could use my site as a server, I really like this code, it's helped me alot!Thanks,Liam