Enjoy folks! If anyone has any questions about it, please feel free to ask.
Rem Project: Internet Pong
Rem Created: Friday, September 23, 2011 By DarthRhyno & zenassem
Rem Tutorial comments by DarthRhyno
Rem ***** Main Source File *****
// INTRODUCTION:
// This is a game of PONG I made as my first attempt at an online multiplayer game.
// I ran into quite a few problems when I first started out, due to my lack of understanding
// about network coding in DarkBASIC Pro. So, like anyone else, I went to TGC forums for
// assistance, and got quite a bit of troubleshooting help from zenassem, in which we finally
// got this code working. These comments here are to help explain the things I learned from
// this, which hopefully will help future generations of coders. :-)
//
// Cheers! -DarthRhyno
//
//
// USEFUL INFORMATION & TIPS:
// --One of the first things that you may have to do if you want to host a multiplayer game of
// any kind if your computer is behind a firewall or router is to do port forwarding for the
// game to open up the ports necessary to run it.
//
// Since DarkBASIC 1.X and DarkBASIC Professional both utilize DirectPlay as their method of
// implementing their networking functions, you'll need to forward the necessary ports for
// DirectPlay which are as follows:
//
// UDP Ports: 47624, 6073
// TCP/UDP Ports: 2300-2400 (that's a range of ports)
//
// --Another important thing to remember in your code is that you can't use WAIT KEY or SLEEP
// commands in your main loop, because they will pause it and potentially cause packet loss.
//
// --Yet another important thing is to remember when you're writing a packet management routine,
// namely when you're receiving packets, you NEED to have a "GET NET MESSAGE" command before
// you try to check if there are any packets in the queue using "NET MESSAGE EXISTS()". The
// reason behind that is the first "GET NET MESSAGE" command will process the queue so then the
// "NET MESSAGE EXISTS()" command will have something to look at.
//
// --Also, in your packet management routines, make sure if you have everything in one packet (which
// to me thusfar seems the best way to go) that you aren't skipping any delimiters when you're sending
// out your packet. That could really screw up data being received on the other end.
//
// Other places I'd check out for more info would be the MULTIPLAYER COMMANDS section of the help file,
// also under the "Technical Documents" portion of the command file, the "MULTIPLAYER SECRETS" document.
// The "MULTIPLAYER SECRETS" document is especially informative, and that's where I started with this.
//
// Thank you all for giving me your time, your patience, and your motahcycul.
// Now listen up everyone, this next one's called... COOOOOOOOOOOOOOOOOOOOOODE:
SET DISPLAY MODE 640, 480, 32
TYPE Player
y AS DWORD
score AS DWORD
ping AS DWORD
ENDTYPE
TYPE MyBall
x AS INTEGER
y AS INTEGER
x_dir AS INTEGER
y_dir AS INTEGER
ENDTYPE
player1 AS Player
player2 AS Player
player1.y = 239
player2.y = 239
player1.score = 0
player2.score = 0
ball AS MyBall
ball.x = 319
ball.y = 239
ball.x_dir = 1
ball.y_dir = -1
choice = 0
// Select connection type
PERFORM CHECKLIST FOR NET CONNECTIONS
SLEEP 100
connection_selection = 0
total_connections = CHECKLIST QUANTITY()
FOR i = 1 TO total_connections
PRINT CHECKLIST STRING$(i)
IF COMPARE CASE$(CHECKLIST STRING$(i), "Internet TCP/IP Connection For DirectPlay") = 1 THEN connection_selection = i
NEXT
PRINT "Connection selection is ", connection_selection, "."
WAIT KEY
// Figure out what you are (host/player)
CLEAR ENTRY BUFFER
REPEAT
CLS
c$ = ENTRY$(1)
TEXT 0,0, "Press 1 to Host a game/Press 2 to Join a game: "+c$
IF (RETURNKEY() = 1)
IF ((COMPARE CASE$(c$, "1") = 1) OR (COMPARE CASE$(c$, "2") = 1))
choice = INT(VAL(c$))
ENDIF
ENDIF
UNTIL choice <> 0
CLS
// If person is host
IF choice = 1
//PRINT "Enter your IP address in the prompt."
SET NET CONNECTION connection_selection, "38.102.24.113" // Insert your IP here
CREATE NET GAME "OssumPong", "Player1", 2, 1
GOSUB _wait_for_player2
GOSUB _start_game
GOSUB _main_loop_host
// If person is client
ELSE
//PRINT "Enter the host IP address in the prompt."
SET NET CONNECTION connection_selection, "192.168.1.113" `"38.102.24.113" // Insert host IP here
PERFORM CHECKLIST FOR NET SESSIONS
IF CHECKLIST QUANTITY() < 1
PRINT "No games available."
ELSE
game$ = CHECKLIST STRING$(1)
PRINT "JOINING GAME: ", game$, "."
JOIN NET GAME 1, "Player2"
GOSUB _start_game
GOSUB _main_loop_client
ENDIF
ENDIF
WAIT KEY
_wait_for_player2:
waiting_for_players = 1
REPEAT
PERFORM CHECKLIST FOR NET PLAYERS
SET CURSOR 0,0
PRINT "Waiting for player 2... waiting for players =", waiting_for_players
IF checklist quantity() > 1 THEN waiting_for_players = 0
UNTIL waiting_for_players = 0
RETURN
_start_game:
SYNC ON
SYNC RATE 60
SET CURRENT BITMAP 0
// CREATE SPRITES FOR GAME
INK RGB(0,255,0), RGB(0,0,0)
BOX 0,0,10,50
GET IMAGE 1, 0,0,10,50
SPRITE 1, 0, 239, 1
SPRITE 2, 630, 239, 1
CLS
INK RGB(0,0,255), RGB(0,0,0)
CIRCLE 5, 5, 5
GET IMAGE 2, 0,0,11,11
SPRITE 3, 319, 239, 2
Return
// Main Loop Host
_main_loop_host:
ping_rate = 250
my_time = TIMER()
DO
// Get Packets First
GOSUB _host_send_recv_packets
CLS
// Update Sprites
SPRITE 1, 0, player1.y, 1
SPRITE 2, 630, player2.y, 1
SPRITE 3, ball.x, ball.y, 2
INK RGB(255,255,255), RGB(0,0,0)
TEXT 0,0, "Player1 Score:"+Str$(player1.score)
TEXT (639-TEXT WIDTH("Player2 Score:"+Str$(player2.score))),0, "Player2 Score:"+Str$(player2.score)
// Gather Input
IF UPKEY() = 1
IF (player1.y > 0) THEN player1.y = player1.y - 1
ENDIF
IF DOWNKEY() = 1
IF (player1.y+50 < 479) THEN player1.y = player1.y + 1
ENDIF
// Increase ball position
GOSUB _increase_ball_position
// Rasterize everything
SYNC
LOOP
RETURN
_host_send_recv_packets:
GET NET MESSAGE
WHILE (NET MESSAGE EXISTS() = 1)
message$ = NET MESSAGE STRING$()
player2.y = INT(VAL(FIRST TOKEN$(message$, "*")))
player2.ping = VAL(NEXT TOKEN$("*"))
ping_rate = TIMER()-player2.ping
GET NET MESSAGE
ENDWHILE
`IF (TIMER() - my_time) >= ping_rate
my_time = TIMER()
my_message$ = Str$(player1.y)+"*"+Str$(ball.x)+"*"+Str$(ball.y)+"*"+Str$(player1.score)+"*"+Str$(player2.score)+"*"+Str$(my_time)
SEND NET MESSAGE STRING 0, my_message$
`ENDIF
RETURN
_increase_ball_position:
ball.x = ball.x + ball.x_dir
ball.y = ball.y + ball.y_dir
IF ball.y < 0 THEN ball.y_dir = 1
IF ball.y > 479 THEN ball.y_dir = -1
IF SPRITE COLLISION(3, 2)=1 THEN ball.x_dir = -1
IF SPRITE COLLISION(3, 1)=1 THEN ball.x_dir = 1
IF ball.x < 0
player2.score = player2.score + 1
ball.x = 319
ball.y = 239
ENDIF
IF (ball.x + SPRITE WIDTH(3)) > 639
player1.score = player1.score + 1
ball.x = 319
ball.y = 239
ENDIF
RETURN
// Main Loop Client
_main_loop_client:
DO
// Get Packets First
GOSUB _client_send_recv_packets
CLS
// Update Sprites
SPRITE 1, 0, player1.y, 1
SPRITE 2, 630, player2.y, 1
SPRITE 3, ball.x, ball.y, 2
INK RGB(255,255,255), RGB(0,0,0)
TEXT 0,0, "Player1 Score:"+Str$(player1.score)
TEXT (639-TEXT WIDTH("Player2 Score:"+Str$(player2.score))),0, "Player2 Score:"+Str$(player2.score)
// Gather Input
IF UPKEY() = 1
IF (player2.y > 0) THEN player2.y = player2.y - 1
ENDIF
IF DOWNKEY() = 1
IF (player2.y+50 < 479) THEN player2.y = player2.y + 1
ENDIF
SYNC
LOOP
RETURN
_client_send_recv_packets:
GET NET MESSAGE
WHILE (NET MESSAGE EXISTS() = 1)
message$ = NET MESSAGE STRING$()
player1.y = INT(VAL(FIRST TOKEN$(message$, "*")))
ball.x = INT(VAL(NEXT TOKEN$("*")))
ball.y = INT(VAL(NEXT TOKEN$("*")))
player1.score = INT(VAL(NEXT TOKEN$("*")))
player2.score = INT(VAL(NEXT TOKEN$("*")))
player1.ping = INT(VAL(NEXT TOKEN$("*")))
GET NET MESSAGE
ENDWHILE
my_message$ = Str$(player2.y)+"*"+Str$(player1.ping)
SEND NET MESSAGE STRING 0, my_message$
RETURN