In order to make that connection, we will want to provide the user with an face he can use to find servers, decide which one offers an interesting game, and then con-nect to the server..
Trang 1The first thing this function does is to obtain the particulars of the MissionArea For thisgame, you should use the Mission Area Editor (press F11 followed by F5) to expand the
MissionArea to fill the entire available terrain tile
The%H and%W values are the height and width of the MissionArea box The variables %west
and%south combined make the coordinates of the southwest corner We uses these values
to constrain our random number selection
Then we set up a search mask All objects in the Torque Engine have a mask value thathelps to identify the object type We can combine these masks using a bitwise-or opera-tion, in order to identify a selection of different types of interest
Then we use our random coordinates to do a search from 500 world units altitude ward until we encounter terrain, using the ContainerRayCast function
down-When the ray cast finds terrain, we add 1 world unit to the height and then use that plusthe random coordinates to build a position at which to spawn a coin Then we spawn thecoin using the appropriate datablock, which can be found in your new copy of item.cs
Next, we add the coin to the MissionCleanup group so that Torque will automaticallyremove the coins when the game ends We also add it to the CoinGroup in case we want toaccess it later
Trang 2After putting that code in, copy C:\3DGPAi1\RESOURCES\CH22\ITEM.CS over toC:\koob\control\server\misc You will find the datablocks for the coins (where the coinvalues are assigned) in there.
Note that when we added the coins in the preceding code, the static parameter was set to
0 This means that the game will not create a new coin at the place where the coin waspicked up, if it is picked up The weapons of the ammo do this, but we don't want ourcoins to do it It's a game play design decision
In addition to the datablocks for the coins in item.cs, you will also find this code:
if (%user.client) {
messageClient(%user.client, 'MsgItemPickup', '\c0You picked up %1', Name);
to the checkpoint scoring
Again, until the client code is in place, you can insert echo statements there to verify thatthings are working properly
Deaths
We want to track the number of times we die to further satisfy requirements, so openC:\koob\control\server\server.cs, locate the method GameConnection::onDeath, and addthese lines at the end:
%this.deaths++;
%this.DoScore();
By now these lines should be familiar We can expand the player death by adding somesound effects and animation Add the following to the end of C:\koob\control\server\players\player.cs:
function Player::playDeathAnimation(%this,%deathIdx) {
%this.setActionThread("Die1");
} datablock AudioProfile(DeathCrySound) {
fileName = "~/data/sound/orc_death.wav";
description = AudioClose3d;
Trang 3Add these two lines to OnDisabled just before the call to SetImageTrigger:
%obj.playDeathCry();
%obj.playDeathAnimation(-1);
One more thing—copy the audio wave file C:\3DGPAi1\RESOURCES\CH22\ORC_
DEATH.WAV to C:\koob\control\data\sound in order to make the sound work
Kills
The victim, who notifies the shooter's client when he dies, actually does the kill tracking
So we go back to GameConnection::onDeath and add this:
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if (%obj.getState() $= "Dead") {
if (isObject(%sourceClient)) {
%sourceClient.incScore(1);
if (isObject(%client))
%client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
} }
This bit of code figures out who shot the player and notifies the shooter's client object ofthis fact
Now it is important to remember that all this takes place on the server, and when we refer
to the client in this context, we are actually talking about the client's connection object and
not about the remote client itself
Okay, so now let's move on to the client side and finish filling the requirements!
Trang 4Moving Right Along
So, now we have our player's model ready to appear in the game as our avatar, we've gotwheels for him to get around in, and a way to figure out where he's been
We've also put some things in the game world for the player to pursue to accumulatepoints, and a way to discourage other players from accumulating too many points forthemselves (by killing them)
All of these features are created on the server In the next chapter, we will add the featuresthat will be handled by the game client
Trang 5The Game Client
By now we've met most of our requirements, at least to the point of
implementa-tion Testing them for correct operation and completeness I will leave as an cise for you, Gentle Reader, because you may (and probably will) want to modifyand enhance the requirements anyway
exer-According to my list, the requirements that remain outstanding are the following:
2 Internet multiplayer game play
3 Global in-game chat
11 All other players are enemies
12 All point values configurable from a setup file
14 3 points per vehicle destroyed
15 Ability to race around the track and score 5 points for each lap you lead (partial)
16 Laps can only be scored in the car
17 A 10-lap race with no time limit
18 A 10-point bonus for winning the race
29 When one map is finished, cycle to the next in the list
Of this list, I will leave numbers 14, 16, 17, and 18 and the remaining portion of number
15 (scoring 5 points) to you to complete as exercises They are variations of the coin ing and the lap and checkpoint tracking we covered in Chapter 22 The functioning code
scor-is available in the Koob installation kit on the CD, if you need help
Most of the remaining work requires additional client code to support the server tions we made in the last chapter—we'll add some multiplayer support, a little bit moreclient support, and user interfaces to access those capabilities
Trang 6addi-Client Interfaces
We are going to add code to allow users to run a server and to allow players to connect to
a server In order to make that connection, we will want to provide the user with an face he can use to find servers, decide which one offers an interesting game, and then con-nect to the server
inter-Another thing we need to do is make sure that when the user quits a server, he returns tohis selection interface rather than simply exiting as Koob does now
Additionally, we need to add a capability to the playing interface to provide a chat dow with a text entry where players can type in messages to send to other players Maybethey'll want to exchange recipes or something Yeah, that's it—recipes! It's not like they'regoing to taunt anyone anyway, is it?
win-In Chapter 6 you saw the MasterScreen interface module that combined these interfaces Inthis chapter we'll look at the same issue but in a slightly different way, in order to showhow easy it is to make different—yet equally valid—design decisions
Also, we'll need to modify a few of the files, like the MainScreen interface, to more closelyconform to our needs
In a later section we'll add the code required to make these interfaces functional
MenuScreen Interface
We will make some changes to our main menu screen so that it provides the user with theadditional choices to
■ view information about the games and credits
■ play in single-player mode (as it already has)
down to the closing brace ("}")
In the place of the deleted control, insert the following:
Trang 7new GuiButtonCtrl() { profile = "GuiButtonProfile";
Trang 8new GuiButtonCtrl() { profile = "GuiButtonProfile";
The Info button uses the getHelp feature of the common code base It searches all of thedirectories nested under the root main directory looking for files with the extension hfl,and then it lists them in alphanumeric order If you preface the file name with a number,such as 1., 2., and so on, it will sort them numerically
This should give you a main menu that looks like Figure 23.1
SoloPlay Interface
The SoloPlay interface, as shown inFigure 23.2, prepares a list of missionfiles that it finds in the maps subdirec-tory in the control\data directory tree.From this list, you can select the map
or mission you want to play Its codeand definition can be found in theSoloScreen modules
It's worth remembering that evenwhen you play in solo mode, under-neath the hood, the Torque Engine is
Figure 23.1 MenuScreen interface.
Trang 9still running in two parts: a clientand a server They are just closelycoupled with no cross-network callsbeing made.
Host Interface
TheHost interface is somewhat lar, as you can see in Figure 23.3, butoffers more options: the ability to set
simi-a time limit simi-and simi-a score limit, plusmap selection modes Its code anddefinition can be found in theHostScreen modules
If both time and score limits are set,the first one reached ends the game Asetting of 0 makes that limit infinite
The sequence mode causes the server
to step through the maps in order asshown in the listing, as each game fin-ishes and the new one loads The ran-dom mode causes the server to ran-domly select a map for each game
The time limit is saved by the control
in the variable $Game::Duration, andthe score limit is saved as
This can be done using Torque Script but is beyond the scope of this book There are ter server resources available from the GarageGames user community
mas-Figure 23.2 SoloPlay interface.
Figure 23.3 Host interface.
Trang 10n o t e
The Query LAN button on the FindServerinterface does the same thing that was done cally in Chapter 6 when you clicked on the Connect to Server button on the main menu screen Thediscussion in the Chapter 6 section called ServerScreen Code Module describes how the Connect toServer button operations are performed, which is the same as how the Query LAN button opera-tions work here
automati-ChatBox Interface
In order to display chat messages from other players, we need to put a control in our mainplayer interface We also need to have a control that will allow us to type in messages to besent to other players, as depicted in Figure 23.5
Open the file C:\koob\control\client\Initialize.cs and add the following lines to the tion InitializeClient:
func-Figure 23.4 FindServer interface.
Figure 23.5 ChatBox interface.
Trang 11Exec("./interfaces/MessageBox.gui");
Theseexec statements load the new files that will provide our chat interface You can copythem from C:\3DGPAi1\RESOURCES\CH23 and put them into the directories under theC:\koob\control\client\ directory in the subdirectories specified in the exec statements
Now open the file C:\koob\control\client\misc\presetkeys.cs and add the following board input binding statements to the end of the file:
key-function pageMessageBoxUp( %val ) {
if ( %val ) PageUpMessageBox();
} function pageMessageBoxDown( %val ) {
if ( %val ) PageDownMessageBox ();
} PlayerKeymap.bind(keyboard, "t", ToggleMessageBox );
PlayerKeymap.bind(keyboard, "PageUp", PageMessageBoxUp );
PlayerKeymap.bind(keyboard, "PageDown", PageMessageBoxDown );
The first two functions are glue functions that are called by two of the key bindings at thebottom and then make the appropriate call to the functions that scroll the messages in themessage box We need these functions in order to filter out the key up and key down sig-nals from the engine We only want the action to take place when the key is pressed Wecan do this by checking the value of%val when we enter the function—it will be nonzerowhen the key is pressed and zero when it is released
Then there is a binding that calls ToggleMessageBox, which is defined in MessageBox.cs (one
of the files we've recently copied that we will examine shortly)
In the interface files there are a couple of concepts you should note To illustrate, look atthe definition of the ChatBox interface, contained in ChatBox.gui:
new GuiControl(MainChatBox) { profile = "GuiModelessDialogProfile";
Trang 12setFirstResponder = "0";
noCursor = true;
new GuiNoMouseCtrl() { profile = "GuiDefaultProfile";
profile = "ChatBoxScrollProfile";
horizSizing = "width";
vertSizing = "bottom";
position = "0 0";
Trang 13Inside that is a GuiNoMouseCtrl control whose role is to shield the chat boxes within it frombeing accessible by a mouse cursor, if you were to display one on the screen.
Inside that is the GuiBitmapCtrl control named OuterChatFrame, which has two useful tions You can use it to provide a nice bitmap background for your chat box if you wantone, and it holds two subobjects
Trang 14func-One of those subobjects is an icon that appears to tell you when you've scrolled the chatbox up far enough to hide text off the bottom of the box That control is a GuiButtonCtrl
namedchatPageDown.The other control is a GuiScrollCtrl namedChatScrollFrame that provides scroll bars forboth vertical and horizontal scrolling
And finally, in the inner sanctum is the actual control that contains the text of the chatbox when it is displayed This GuiMessageVectorCtrl supports multiline buffers of text thatwill display new text at the bottom and scroll older text up You can use commands (that
we have bound to the PageUp and PageDown keys) to scroll up and down through the textbuffer
MessageBox Interface
TheMessageBox interface is where we type in our messages, as shown in Figure 23.6
It is not normally on the screen but pops up when we hit the key we bound to it This, too,has several nested levels, though not as many as the ChatBox interface
new GuiControl(MessageBox) {
Trang 15new GuiControl(MessageBox_Frame) {
It is all familiar stuff, but take note that the outer object,MessageBox, is initially invisible
The code that pops the box up will make it visible and invisible again as needed
There is a GuiTextCtrl named MessageBox_Text that is at the same level as the
GuiTextEditCtrl namedMessageBox_Edit TheMessageBox_Text can be used to put a prompt
in front of the area where the message will be typed in, although it has no text here in the
Trang 16definition The MessageBox_Edit control is the control that accepts our typed-in message.ThealtCommand property specifies what statement to execute when the Enter key is pressed,and the escapeCommand property specifies what to do when the Escape key is pressed Thehandlers for these two functions will be discussed later in the code discussion in the
"Client Code" section
Client Code
I'm not going to make you type in great reams of program code at this stage of the game,though you don't get off the hook completely You will have to make some changes toaccommodate the new stuff, and we'll also examine the contents of some of the new stuff
to see what it does
MenuScreen Interface Code
Open the file C:\koob\control\client\initialize.cs and locate the function InitializeClient
and add the following lines in the grouping with the other similar statements:
exec statements
Each of these files is basically one module split into two parts The actual interface itions are in the files with the gui extensions, while the code that manages the interfacesare in the files with the same prefix name, but ending with the cs extension
defin-If you go back to the previous code listing for MenuScreen.gui, you will see where each ofthe interfaces is invoked ServerScreen is defined in ServerScreen.gui,HostScreen is defined
in HostScreen.gui, and finally,SoloScreen is defined in SoloScreen.gui
Each interface has roughly the same form There is an OnWake method for the interfaceobject that is called by the engine when that object is displayed by the SetContent call inthe related button in the MenuScreen interface This method prepares the interface and fillsthe various data fields in the interfaces