Simple Chat to Demonstrate Using Multiplayer Commands by Fluffy Paul30th Jul 2004 5:42
|
---|
Summary A very simple chat program that highlights the use of multiplayer commands to start or connect to a game and send messages. Description This program was initially supposed to demonstrate the multiplayer commands but evolved into a really simple chat program. The idea was NOT to make a chat program - that's just what it ended up being. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com rem Title : Simple Multiplayer Demo rem Project : mpdemo.dbpro rem Source : mpdemo.dba rem Author : Paul "Fluffy" Morgan rem Purpose : To demonstrate use of multiplayer commands. rem Comments: For everyone! Use as you see fit. Get in touch via the forums if you have questions. rem Disable escape so we can exit in a controlled manner, otherwise we might break the network! disable escapekey set text font "Tahoma" set text size 12 maxPlayers = 8 Dim players$(maxPlayers) rem Define an array to record key presses so we can monitor user input. dim key$(1) rem The player list and the chat space can't overlap, but we don't want them pushing rem each other off the screen so the chat space resizes itself depending on how many rem players we're showing. dim chatlines$(28 - maxPlayers) chatflag$="" latestline=0 action$="" rem These 6 are the important variables used to make and find games connection=0 connection$="" host$="" playername$="" netsession=0 netsession$="" rem Ask the user if they're starting or finding a session as this changes things later while action$ = "" cls update_keystate() text 0, 15, "Press 1 if you want to start a new session or 2 if you want to find an existing session." rem Check for key-ups. See the comments in the update_keystate() function. select key$(1) case "1" : action$ = "START" : text 0, 30, "Checking for connections..." :endcase case "2" : action$ = "FIND" : text 0, 30, "Checking for connections...": endcase endselect if escapekey()=1 then end endwhile rem Get the list of available connection types from the OS perform checklist for net connections rem The connection selection screen. Usually would need TCP/IP but might get rem used for other things. while connection$ = "" cls update_keystate() text 0, 15, "Please select a connection to use: " rem Get DB to print out the list of connection types. for n=1 to checklist quantity() output$ = str$(n) + ": " output$ = output$ + checklist string$(n) text 0, (n*15)+15, output$ next n rem Check for the user pressing a key. if val(key$(1)) > 0 and checklist quantity() > 0 and val(key$(1)) <= checklist quantity() connection = val(key$(1)) connection$ = checklist string$(connection) endif if escapekey()=1 then end endwhile rem Now we need the IP or hostname of the computer running the game. rem If you're using the "session_finder" companion program then you rem need to type the same IP or host name there as was typed here. while host$ = "" cls update_keystate() text 0, 15, "Using " + connection$ gosub _handle_chat_key_input text 0, 30, "Please enter your host name or IP address: " + chatline$ rem take the user-entered chatline$ and store it in a variable called host$ if chatflag$ = "DONE" host$ = chatline$ text 0, 45, "Attempting to open session on " + host$ + " - please wait a moment..." endif if escapekey()=1 then end endwhile set net connection connection, host$ Rem The net game needs a name while playername$ = "" cls update_keystate() text 0, 15, "Using " + connection$ + " on " + host$ gosub _handle_chat_key_input text 0, 30, "Please enter the name you wish to use: " + chatline$ rem take the user-entered chatline$ and store it in a variable called session$ if chatflag$ = "DONE" playername$ = chatline$ endif if escapekey()=1 then end endwhile select action$ case "START" Rem The net game needs a name while netsession$ = "" cls update_keystate() text 0, 15, "Using " + connection$ + " on " + host$ + " as " + playername$ gosub _handle_chat_key_input text 0, 30, "Please enter a name for your session: " + chatline$ rem take the user-entered chatline$ and store it in a variable called session$ if chatflag$ = "DONE" netsession$ = chatline$ text 0, 45, "Attempting to start session on " + netsession$ + " - please wait a moment..." endif endwhile if escapekey()=1 then end create net game netsession$, playername$, 16, 1 endcase case "FIND" Rem Look for sessions on the host and make a list. empty checklist perform checklist for net sessions if checklist quantity()=0 text 0, 15, "Using " + connection$ + " on " + host$ + " as " + playername$ text 0, 45, "NO SESSIONS FOUND. Press any key to exit..." wait key end endif while netsession$ = "" cls update_keystate() text 0, 15, "Using " + connection$ + " on " + host$ + " as " + playername$ text 0, 30, "Please select a session to join: " rem Print the list of sessions out for n=1 to checklist quantity() output$ = str$(n) + ": " + checklist string$(n) text 0, (n*15)+30, output$ next n rem Check for key presses that match up to a checklist item if val(key$(1)) > 0 and checklist quantity() > 0 and val(key$(1)) <= checklist quantity() netsession = val( key$(1) ) netsession$ = checklist string$(netsession) temp$ = str$(netsession) + ": " + checklist string$(netsession) text text width(temp$),30+netsession*15," - CONNECTING..." endif endwhile if escapekey()=1 then end join net game netsession, playername$ endcase endselect rem note the difference in the netsession variable. rem To create a game it's a string and to join a game it's an integer! gosub _make_list_of_players if checklist quantity()=0 rem If there are no players then we didn't make/join successfully. text 0, 15, "Using " + connection$ + " on " + host$ + " as " + playername$ text 0, 45, "FAILED TO " + action$ + " GAME. Press any key to exit..." wait key end endif do cls update_keystate() rem Report continuously on other players connected to the game. gosub _show_connection_and_players rem Read the keybaord input and send it out as a chat line where necessary gosub _handle_chat_key_input gosub _handle_sending_chatline rem Show chat line as user types it (chatline$ is use in _handle_chat_key_input) chatlinebase = endofplayerlist + 15 rem Draw some lines around the chat area to make it a bit more obvious gosub _draw_chat_box text 0, chatlinebase, " SEND:" + chatline$ gosub _handle_chat_net_input chatbase = chatlinebase + 15 gosub _show_chat rem Print out the total count of messages sent and received in the bottom right rem corner of the screen. text screen width() - 1 - text width("Sent: " + str$(msgoutcount)), screen height() - 30, "Sent: " + str$(msgoutcount) text screen width() - 1 - text width("Received: " + str$(msgincount)), screen height() - 15, "Recieved: " + str$(msgincount) if escapekey()=1 then free net game : exit loop end _make_list_of_players: rem Prepare the player checklist empty checklist perform checklist for net players rem Clear out the old data for n=1 to maxPlayers players$(n) = "<none>" next n rem Bring in the new data for n=1 to checklist quantity() players$(checklist value a(n)) = checklist string$(n) next n return _show_connection_and_players: rem If a player joins or leaves then re-make our list of players as there's no rem multiplayer command that asks them for their name. if net player created() > 0 or net player destroyed() > 0 gosub _make_list_of_players endif text 0, 15, "Using " + connection$ + " on " + host$ + " in " + netsession$ + " as " + playername$ text 0, 30, "Players Found: " rem loop through the list of players, printing them to the screen along with their player number. for n=1 to array count( players$(0)) output$ = str$(n) + ": " + players$(n) text 0, (n*15)+30, output$ endofplayerlist = (n*15)+30 next n return _handle_chat_key_input: rem Reset the flag and clear the input line. if chatflag$="DONE" then chatflag$="" : chatline$="" rem If a key is pressed if key$(1)<>"" rem Did the user press backspace? (ascii 8) if asc( key$(1) )=8 rem backspace - chop off the character at the end of the line chatline$ = left$( chatline$, len(chatline$)-1) else rem did the user hit return? (ascii 13) if asc( key$(1) )=13 rem Yep - they hit return. rem Mark the chat line as being DONE and ready for sending. chatflag$="DONE" else rem add anything else the user types to the chat line chatline$ = chatline$ + key$(1) endif endif endif return _handle_sending_chatline: if chatflag$="DONE" rem send out our chat line send net message string 0, chatline$ rem Update the currentmessage$ variable for use with the subroutine. rem Add our own name to the line for our own benefit. currentmessage$ = playername$ + ": " + chatline$ rem we won't receive our chat message over te network so we have to "cheat" and add rem it to our chat array manually. gosub _add_current_message_to_chat rem update our counter msgoutcount = msgoutcount+1 endif return _draw_chat_box: rem Top of box line 0, chatlinebase, screen width()-1, chatlinebase rem Left side of box line 0, chatlinebase, 0, chatlinebase+15 rem Right side of box line screen width()-1, chatlinebase, screen width()-1, chatlinebase+15 rem Bottom of box line 0, chatlinebase+15, screen width()-1, chatlinebase+15 return _handle_chat_net_input: rem get net message tells DB what the next message is. get net message rem Now we ask DB if there is a message waiting for us or not. while net message exists() > 0 rem We have a message. This is a chat program so it better be a string (message type 3). if net message type()=3 rem it's a string so find out who it's from and add this data to the chat area. currentmessage$ = players$(net message player from()) + ": " + net message string$() gosub _add_current_message_to_chat endif rem Update the counter for posterity. msgincount = msgincount+1 rem now that we've sorted that message out, let's see if there's another one. get net message endwhile return _show_chat: rem Go through all the chat lines we've recorded and print them out to the screen. rem Have to do it backwards, though, so the newest one appears at the bottom of the screen. for n = 0 to array count(chatlines$(0))-1 thisline = latestline-n rem check to make sure we wrap around to the end of the array if we count backwards rem past the beginning. if thisline < 1 then thisline = array count(chatlines$(0)) + thisline text 0, chatbase+15*array count(chatlines$(0))-((n+1)*15), chatlines$(thisline) next n return _add_current_message_to_chat: rem Move along to the next slot in our message array latestline = latestline+1 rem Make sure we wrap around to the start if we count past the end of the array. if latestline > array count(chatlines$(0)) then latestline = 1 rem Overwrite whatever is here with the current message. chatlines$(latestline)=currentmessage$ return function update_keystate() remstart A very simple way of detecting when a key is pressed and when it's released. key$(0) represents a "key down" i.e. when a key is pressed. key$(1) represents a "key up" i.e. when a key is released. If key$(1) isn't empty then it's equal to a key that's just been released. We use this to determine what the user is typing so that we don't pause the program with an INPUT command. If we used the letter that was currently being pressed then we would get one letter for every frame per second. remend key$(1)="" if key$(0) <> inkey$() key$(1) = key$(0) endif key$(0)=inkey$() endfunction |