Help with network game
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
Help with network game
I am working on a game that can be played over the network and I was wondering how the computers would communicate with each other. I know how to program all the networking commands, I am just wondering how the computers commuicate to each other.
-
- Addict
- Posts: 1648
- Joined: Mon Sep 20, 2004 3:52 pm
- Contact:
I wrote an example of a 2-player network "game" for z3phir, it may have what you are looking for.
Otherwise a good bet would be to just combine the example source codes of server, and client, with the sprite commands.
Otherwise a good bet would be to just combine the example source codes of server, and client, with the sprite commands.
Code: Select all
;*****************************************************************
; Multiplayer 2d Game Example
; Copyright 2005 DracSoft
; www.dracsoft.com
; Feel free to use this code in any application for any reason.
; I know its ugly but its just for learning purposes.
;*****************************************************************
;variables for example
Global Player1X.l
Global Player2X.l
Global Player1Y.l
Global Player2Y.l
Global isServer.b
Port.l
IP.s
connID.l
Buffer = AllocateMemory(1000)
Screen.l
;Procedures
Procedure HandleData(dataString.s)
x=Val(StringField(dataString,1,","))
y=Val(StringField(dataString,2,","))
If isServer
Player1X=x
Player1Y=y
Else
Player2X=x
Player2Y=y
EndIf
EndProcedure
Procedure DrawScreen()
ClearScreen(255,255,255)
StartDrawing(ScreenOutput())
Locate(Player1X,Player1Y)
DrawText("1")
Locate(Player2X,Player2Y)
DrawText("2")
StopDrawing()
FlipBuffers()
EndProcedure
;get initial data
OpenConsole()
PrintN("Enter 1 for Server, 2 for Client:")
in.s=Input()
PrintN("Enter the port: ")
Port.l=Val(Input())
If in="1"
isServer=#True
Else
isServer=#False
PrintN("Enter the IP to connect to: ")
IP = Input()
EndIf
PrintN("")
CloseConsole()
;start 2d screen and initialize keyboard
InitSprite()
Screen=OpenWindow(#PB_Any,1,1,640,480,#PB_Window_TitleBar,"MP 2D Test")
OpenWindowedScreen(WindowID(Screen),1,1,640,480,#False,0,0)
doQuit.b=0
InitKeyboard()
If InitNetwork()=0
doQuit=1
EndIf
If isServer
;Do server operations
CreateNetworkServer(Port)
While doQuit=0
tmp=WindowEvent()
event=NetworkServerEvent()
If event=2 ;data arrival
connID=NetworkClientID()
tmps.s=""
While CountString(tmps,"|")=0
ReceiveNetworkData(connID,Buffer,1000)
tmps=tmps+PeekS(Buffer)
Wend
HandleData(tmps)
ElseIf event=1 ;new connection
connID=NetworkClientID()
;MessageRequester("","Client connected.")
EndIf
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
Player2X=Player2X-1
SendNetworkString(connID,Str(Player2X)+","+Str(Player2Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Right)
Player2X=Player2X+1
SendNetworkString(connID,Str(Player2X)+","+Str(Player2Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Up)
Player2Y=Player2Y-1
SendNetworkString(connID,Str(Player2X)+","+Str(Player2Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Down)
Player2Y=Player2Y+1
SendNetworkString(connID,Str(Player2X)+","+Str(Player2Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Escape)
doQuit=1
EndIf
DrawScreen()
Wend
Else
;Do client operations
connID=OpenNetworkConnection(IP,Port)
If connID=#Null
MessageRequester("Error","Couldn't connect.")
doQuit=1
EndIf
While doQuit=0
tmp=WindowEvent()
event=NetworkClientEvent(connID)
If event=2
tmps.s=""
While CountString(tmps,"|")=0
ReceiveNetworkData(connID,Buffer,1000)
tmps=tmps+PeekS(Buffer)
Wend
HandleData(tmps)
EndIf
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
Player1X=Player1X-1
SendNetworkString(connID,Str(Player1X)+","+Str(Player1Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Right)
Player1X=Player1X+1
SendNetworkString(connID,Str(Player1X)+","+Str(Player1Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Up)
Player1Y=Player1Y-1
SendNetworkString(connID,Str(Player1X)+","+Str(Player1Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Down)
Player1Y=Player1Y+1
SendNetworkString(connID,Str(Player1X)+","+Str(Player1Y)+"|")
ElseIf KeyboardPushed(#PB_Key_Escape)
doQuit=1
EndIf
DrawScreen()
Wend
EndIf
;Quit
If isServer
CloseNetworkServer()
Else
CloseNetworkConnection(connID)
EndIf
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
Oh, I kind of understand now, I was acually making a file on each of the clients computers and sending it to the server. Then the server sends it to the rest of the computers and each client reads the file and updates the screen. But this looks alot faster. I will try making my game again if I have any questions, I will post them here. Thanks for helping.
EDIT: Is there a way to find servers on the network? Like instead of entering the IP everytime?
EDIT: Is there a way to find servers on the network? Like instead of entering the IP everytime?
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
-
- Addict
- Posts: 1648
- Joined: Mon Sep 20, 2004 3:52 pm
- Contact:
Yes you'll need to send a message tot he server and have part of that message specify which client to forward the message to.
It's impossible to send a message client to client unless you are using connectionless networking such as UDP, which I do not think PB supports natively at this point. You could always use API however.
It's impossible to send a message client to client unless you are using connectionless networking such as UDP, which I do not think PB supports natively at this point. You could always use API however.
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
okay, so I send the data throgh the server to all the other clients. Does anyone have a code snipet to show me how to do this? I tried something like this:
Where the server gets the ClientID of the Clients and then whenever a client sends information to the server, it sends it to the other one. But this didn't seem to work. does anyone know what I am doing wrong?
Code: Select all
Repeat
Sevent = NetworkServerEvent()
If Sevent
ClientID = NetworkClientID()
If numberofplayers = 0
numberofplayers = 1
player1ID = NetworkClientID()
Else
player2ID = NetworkClientID()
EndIf
Select Sevent
Case 1
PrintN("Someone has connected!")
Case 2
ReceiveNetworkData(ClientID,Buffer,1000)
If NetworkClientID() = player1ID
SendNetworkString(player2ID,PeekS(Buffer))
EndIf
If NetworkClientID() = player2ID
SendNetworkString(player1ID,PeekS(Buffer))
EndIf
buffer = AllocateMemory(1,1000)
Case 4
PrintN("Someone disconnected!")
EndSelect
EndIf
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
alright, here is my code. It is basically a modified version of the code you gave me. one of the computers responds and the other one doesnt work at all. The one that responds is very inacurate and choppy. please help
Code: Select all
InitNetwork()
InitKeyboard()
InitMouse()
InitSprite()
Player1X.l
Player1Y.l
Player1MX.l
Player1MY.l
Player1C.l
Player2X.l
Player2Y.l
Player2MX.l
Player2MY.l
Player2C.l
isserver.b
port.l = 6832
Buffer = AllocateMemory(1,10000)
OpenConsole()
PrintN(">>> T A N K - B U S T E R <<<")
PrintN("[1]Player1 [2]Player2")
Print(">")
selection.s = Input()
If selection = "1"
isServer = #true
ElseIf selection = "2"
isServer = #false
Else
End
EndIf
If isServer
CreateNetworkServer(port)
ClearConsole()
PrintN(">>> T A N K - B U S T E R <<<")
ExamineIPAddresses()
PrintN("IP: "+IPString(NextIPAddress()))
Print("Waiting for player 2")
Repeat
Sevent = NetworkServerEvent()
If sevent
Select sevent
Case 1
startgame = 2
EndSelect
EndIf
Until startgame = 2
CloseConsole()
Else
ClearConsole()
PrintN(">>> T A N K - B U S T E R <<<")
Print("IP: ")
ip.s = Input()
player2id = OpenNetworkConnection(ip, Port)
If player2id
beep_(1000,200)
beep_(2000,200)
Else
beep_(2000,200)
beep_(1000,200)
End
EndIf
CloseConsole()
EndIf
OpenScreen(800,600,16,"Tank Buster")
player1x = 50
player1y = 50
player2x = 350
player2y = 350
TransparentSpriteColor(-1,255,0,255)
ClearScreen(255,0,0)
CreateSprite(0,50,50)
CreateSprite(1,50,50)
If isServer
Repeat
ClearScreen(0,60,0)
DisplayTransparentSprite(0,player1x,player1y)
DisplayTransparentSprite(1,player2x,player2y)
FlipBuffers()
sevent = NetworkServerEvent()
If sevent = 2
temp.s = ""
clientid = NetworkClientID()
ReceiveNetworkData(clientid, buffer, 10000)
temp = PeekS(buffer)
buffer = AllocateMemory(1,10000)
player2x=Val(StringField(temp,1,","))
player2y=Val(StringField(temp,2,","))
EndIf
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up)
player1y - 3
SendNetworkString(clientid,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_Down)
player1y + 3
SendNetworkString(clientid,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_left)
player1x - 3
SendNetworkString(clientid,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_right)
player1x + 3
SendNetworkString(clientid,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_escape)
End
EndIf
ForEver
Else
;- clientcode
Repeat
ClearScreen(0,60,0)
DisplayTransparentSprite(0,player1x,player1y)
DisplayTransparentSprite(1,player2x,player2y)
FlipBuffers()
sevent = NetworkServerEvent()
If sevent
If sevent = 2
temp.s = ""
ReceiveNetworkData(player2id, buffer, 10000)
temp = PeekS(buffer)
buffer = AllocateMemory(1,10000)
player2x=Val(StringField(temp,1,","))
player2y=Val(StringField(temp,2,","))
EndIf
EndIf
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up)
player1y - 3
SendNetworkString(player2id ,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_Down)
player1y + 3
SendNetworkString(player2id ,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_left)
player1x - 3
SendNetworkString(player2id ,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_right)
player1x + 3
SendNetworkString(player2id ,Str(player1x)+","+Str(player1y))
EndIf
If KeyboardPushed(#PB_Key_escape)
End
EndIf
ForEver
EndIf
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
-
- Enthusiast
- Posts: 152
- Joined: Sun Jul 11, 2004 7:48 pm
- Location: Lillehammer, No(r)way
- Contact:
Well I will try to explain..
When a client send a message, it has to include things like this:
ClientID, MessageType(example '255') and the message itself..
And when the server get this message it does something like this:
msgtype = ParseMsg()
Select MsgType
Case msgtype
DoThis()
Case msgtype
DoThat()
; and so on..
EndSelect
So lets say "255" mean BroadcastToAll.
The server then has a list of all connected clients,
and sends the message to everyone,
excluding the one that sent the message.. (no need to get what you just sent right back is it(!)..)
When that's said I think that this kind of thing should be done with UDP, and not TCP..
But then again there's no 'internal' UDP support in PB.
But if you know some API there's really not that hard to get UDP working..
Not very clear, but I hope you get some of it..
EDIT: And then I re-read youre post..
You can store all connected client ids in for example a LinkedList,
and the you do like:
When a client send a message, it has to include things like this:
ClientID, MessageType(example '255') and the message itself..
And when the server get this message it does something like this:
msgtype = ParseMsg()
Select MsgType
Case msgtype
DoThis()
Case msgtype
DoThat()
; and so on..
EndSelect
So lets say "255" mean BroadcastToAll.
The server then has a list of all connected clients,
and sends the message to everyone,
excluding the one that sent the message.. (no need to get what you just sent right back is it(!)..)
When that's said I think that this kind of thing should be done with UDP, and not TCP..
But then again there's no 'internal' UDP support in PB.
But if you know some API there's really not that hard to get UDP working..
Not very clear, but I hope you get some of it..

EDIT: And then I re-read youre post..
You can store all connected client ids in for example a LinkedList,
and the you do like:
Code: Select all
ForEach client()
SendMsg()
Next
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact:
-
- Enthusiast
- Posts: 346
- Joined: Fri Oct 10, 2003 12:42 am
- Location: Tampa,FL,USA
- Contact: