Code archives/Networking/TCPIP 3D game example
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| A simple network game example. limited to 10.000 Connections. i made this as small as i Cold on 8 hours coding. warinig will code will crash if a client disconnect. this is only an example of how to code. and make silky smoth games with tcp/ip. | |||||
; Example blitz3d tcpip game.
; Written by wings on blitz forum wings@tiberion.eu
;
Global server
Global player
Global player_guid ; player clident global indentifyer.
Global player_guid_counter ; Here we create new ids
Global client_debug_network ; A millisecond counter for debuging
Global link ; This is player link. accaly i store session in this. i prefare name link.
;Data base for players
Type player_type
Field name$
Field player_guid
Field x#,y#,z#,rot#,status
Field mesh
Field link
End Type
;Try to Start the server. if port 7001 is not available game goes into client mode.
Server = CreateTCPServer (7001) ; if this fails game will go on as a client
Global rec_bank=CreateBank(512) ; A common datablock. used to store data from client
Global send_bank=CreateBank(512) ; A common datablock. used to store data that is sent to clients.
;Setup Graphics mode & camera envornoment
Graphics3D 800,600
SetBuffer BackBuffer()
camera=CreateCamera()
CameraViewport camera,0,0,800,600
CameraRange camera,1,100
CameraFogRange camera,2,100
CameraFogMode camera,True
CameraFogColor camera,150,200,255
CameraClsColor camera,150,200,255
PositionEntity camera,0,10,-10
TurnEntity camera,30,0,0
light=CreateLight()
;Create a grass texture 64*64 with 1 flag and that is color. one can also use loadtexture
grass=CreateTexture(64,64,1)
SetBuffer TextureBuffer(grass)
ClsColor 22,100,22
Cls
For i=0 To 256
Color 0+Rnd(10),50+Rnd(155),0+Rnd(10)
Plot Rnd(64),Rnd(64)
Next
SetBuffer BackBuffer()
ScaleTexture grass,3,3
Color 255,255,255
ClsColor 0,0,0
;Create the grass entity as a endless plane
plane=CreatePlane()
EntityTexture plane,grass
;Create player mesh
player=CreateCube()
PositionEntity player,5,1,5
;The big main. mixed server & client in same code.
While Not KeyHit(1)
server_function()
player_controlls()
update_player_positions()
UpdateWorld()
RenderWorld()
draw_status_texts()
client_networking()
Flip
Wend
;Draw varius status text on screen. and some help.
Function draw_status_texts()
Text 0,0,"Blitz3d TCPIP Example"
If server
Text 0,10,"player_guid_counter="+player_guid_counter
Else
If link=0 Then Text 0,10,"Press F1 for connect to server"
Text 0,30,"client_debug_network="+client_debug_network
End If
If link=0
Text 0,20,"Not Connected"
Else
Text 0,20,"Connected"
End If
End Function
; Here we place all server handling functions. like accept new streams and send recive data from clients.
Function server_function()
;Only run this if its the server.
If server
;TCP/IP stream check for new one.
server_check() ;
;TCP/IP Handling of streams. like sending reciving.
server_handle_player()
;update client position of server object. this makes the server also move at clients no neet to send our self to server. ;)
p.player_type = First player_type
p\x#=EntityX#(player)
p\y#=EntityY#(player)
p\z#=EntityZ#(player)
p\rot#=EntityYaw(player)
End If
End Function
;Here we handle all player controlls. left/right forward/backward even commands for connect to server.
Function player_controlls()
If KeyHit(59) And server=False Then connect_to_server() ; Connect to server F1
If KeyDown(17) ; Mover forward "w"
MoveEntity player,0,0,0.05
End If
If KeyDown(31) ; Move backward "s"
MoveEntity player,0,0,-0.05
End If
If KeyDown(30) ; Turn Left "a"
TurnEntity player,0,1,0
End If
If KeyDown(32) ; Turn right "d"
TurnEntity player,0,-1,0
End If
End Function
;Updates the meshes from data structure. that been loaded from network last. this makes players move on each other screens. and rotates
Function update_player_positions()
;Update player positions
For p.player_type=Each player_type
If p\mesh<>player
PositionEntity p\mesh,p\x#,p\y#,p\z#
RotateEntity p\mesh,EntityPitch(p\mesh),p\rot#,EntityRoll(p\mesh)
End If
Next
End Function
;Server needs to check for new players connection setup. it alls hapends here.
Function server_check()
;This code counts the registred players
i=0
For p.player_type = Each player_type
i=i+1
Next
;If there is no one register even the server is not register. then this code creates the first player with the Guid 0 The first one :)
If i=0
p.player_type= New player_type
p\x#=EntityX#(player)
p\y#=EntityY#(player)
p\z#=EntityZ#(player)
p\player_guid=0
p\mesh=player
End If
;Check for new streams connected. and if detect a new stream create a new player give it a guid.
stream=AcceptTCPStream(Server)
If stream
Cls
Print "A new stream connected !"
Delay 2000
;Create a new player for stream
p.player_type= New player_type
p\link = stream
p\mesh=CreateCube()
player_guid_counter=player_guid_counter+1
p\player_guid = player_guid_counter ; The stream has now a global indentifyer. now that is nice.
End If
;Security code
If player_guid_counter>10000 Then RuntimeError ("Some fool is hacking our little game client or you been playing far to long.") ; Be sure to put in this kind of bugs. lamo lama
End Function
;Player networking handling. here player clients get there data from server and sending it curent position.
Function client_networking()
;Only run this code if a datalink has been establish
If link
ms=MilliSecs()
;Send client data to server. evert frame this is done ;)
PokeInt send_bank,0,1000 ; CLient cord package.
PokeFloat send_bank,4,EntityX#(player)
PokeFloat send_bank,4+8,EntityY#(player)
PokeFloat send_bank,4+16,EntityZ#(player)
PokeFloat send_bank,4+24,EntityYaw#(player)
WriteBytes send_bank,link,0,512 ; Write it all to stream.
Repeat
again=False
If ReadAvail(link)>=512 ; Ya we got somthing to read.
again=True
bytes=ReadBytes(rec_bank,link,0,512)
If bytes<512 Then RuntimeError "The client stream broke sir.." ; Lamo was here
Select PeekInt(rec_bank,0)
Case 1001 ; Found a client cordinate package.
guid=PeekInt(rec_bank,4) ; global id
newplayer=True
For p2.player_type = Each player_type
If guid=p2\player_guid
newplayer = False ; Found the player.. now store data
p2\x#=PeekFloat#(rec_bank,8)
p2\y#=PeekFloat#(rec_bank,16)
p2\z#=PeekFloat#(rec_bank,24)
p2\rot#=PeekFloat#(rec_bank,32)
End If
Next
If newplayer=True
p2.player_type = New player_type
p2\mesh=CreateCube()
EntityColor p2\mesh,Rnd(255),Rnd(255),Rnd(255)
p2\player_guid=guid
p2\x#=PeekFloat#(rec_bank,8)
p2\y#=PeekFloat#(rec_bank,16)
p2\z#=PeekFloat#(rec_bank,24)
p2\rot#=PeekFloat#(rec_bank,32)
End If
End Select
End If
Until ReadAvail(link)<512
client_debug_network=MilliSecs()-ms
End If ;End of whole network block
End Function
;This functions takes care of all player network data recive and send.
Function server_handle_player()
For p.player_type= Each player_type
If p\player_guid<>0
If Eof(p\link) Then RuntimeError "A client quitet.. server crash ! Best regards Lamo coder" ;Realy put in some client kill & cleanup code here ;D
Repeat
If ReadAvail(p\link)>=512 ; Yes only 512 is a magic thing.
bytes=ReadBytes(rec_bank,p\link,0,512)
If bytes<>512 Then RuntimeError ("Awsome client dint send 512.. wat to to Regards Lamo coder"); Yes we shold kick and ban this hacker or poor internet connection for a user.
Select PeekInt(rec_bank,0) ; Reads the first byte and we go from there..
Case 1000 ; Defaul x,y,z, data player cordinate packet recived.
;Read the data from packet into the database. X,Y,Z and Rotation (yaw)
p\x#=PeekFloat(rec_bank,4)
p\y#=PeekFloat(rec_bank,4+8)
p\z#=PeekFloat(rec_bank,4+16)
p\rot#=PeekFloat(rec_bank,4+24)
;Well we shold make a payback to client as thanks for player cords ;)
For p2.player_type= Each player_type
If p2.player_type<> p.player_type;Every one except it self.
PokeInt rec_bank,0,1001 ; A client cordinate package. Note i call this one 1001.. a reply from server clients cords. its verry important
PokeInt rec_bank,4,p2\player_guid
PokeFloat rec_bank,8,p2\x# ;X position
PokeFloat rec_bank,16,p2\y# ;Y position
PokeFloat rec_bank,24,p2\z# ;Z Position
PokeFloat rec_bank,32,p2\rot# ; Rotation
WriteBytes rec_bank,p\link,0,512 ; Send the data block
End If
Next ; End of all other clients cords to the client
End Select
End If
Until ReadAvail(p\link)<512 ; we need to read all packets before continue to clear tcp buffer.
End If
Next
End Function
;Simple try to connect to server.
Function connect_to_server()
Cls
Print "Trying to connect to server"
Print "Open stream"
link=OpenTCPStream("localhost",7001)
Print link
If Not link Then RuntimeError "Failed to connect to server."
Print "Connection success"
Flip
Delay 2000
End Function |
Comments
| ||
| Thans for this. It's a nice bit of work. If it is possible, could you at some time include a detailed explanation of what each section does. I'm at a loss for the correct usage of TCP and UDP Thanks though |
| ||
| Wings, thank you! please tell why 512? is this MSS? % 512 + 40 = 552 MTU? |
| ||
| how do I connect to server? |
Code Archives Forum