3D Game Programming All in One- P25 - Pdf 70

$TypeMasks::TerrainObjectType | $TypeMasks::ShapeBaseObjectType;
%scanTarg = ContainerRayCast(%x SPC %y SPC "500", %x SPC %y SPC "-100", %search-
Masks);
if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
{
%newpos = GetWord(%scanTarg,1) SPC GetWord(%scanTarg,2) SPC GetWord(%scanTarg,3)
+ 1;
}
%coin = new Item("Copper "@%i) {
position = %newpos;
rotation = "1 0 0 0";
scale = "5 5 5";
dataBlock = "Copper";
collideable = "0";
static = "0";
rotate = "1";
};
MissionCleanup.add(%coin);
CoinGroup.add(%coin);
}
}
The first thing this function does is to obtain the particulars of the
MissionArea
. For this
game, 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 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 was
picked up, if it is picked up. The weapons of the ammo do this, but we don't want our
coins 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', %this.pickup-
Name);
%user.client.money += %this.value;
%user.client.DoScore();
}
The last two statements in there allow the player to accumulate the money values, and
then the server notifies the client of the new score. Note that it is similar in that small way
to the checkpoint scoring.
Again, until the client code is in place, you can insert
echo
statements there to verify that
things are working properly.
Deaths
We want to track the number of times we die to further satisfy requirements, so open
C:\koob\control\server\server.cs, locate the method
GameConnection::onDeath
, and add
these lines at the end:
%this.deaths++;
%this.DoScore();

playDeathCry
, which will play that profile's sound effect. These are invoked by two
lines that you should place in the
OnDisabled
function farther back up in the player.cs file.
Add 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 of

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 scor-
ing and the lap and checkpoint tracking we covered in Chapter 22. The functioning code
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 addi-
tions we made in the last chapter—we'll add some multiplayer support, a little bit more
client support, and user interfaces to access those capabilities.
Team LRN
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
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 inter-
face he can use to find servers, decide which one offers an interesting game, and then con-
nect to the server.
Another thing we need to do is make sure that when the user quits a server, he returns to
his 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 win-
dow with a text entry where players can type in messages to send to other players. Maybe
they'll want to exchange recipes or something. Yeah, that's it—recipes! It's not like they're
going to taunt anyone anyway, is it?

Chapter 23

The Game Client632
Team LRN
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
new GuiButtonCtrl() {
profile = "GuiButtonProfile";
horizSizing = "right";
vertSizing = "top";
position = "30 138";
extent = "120 20";
minExtent = "8 8";
visible = "1";
command = "Canvas.setContent(SoloScreen);";
text = "Play Solo";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
new GuiButtonCtrl() {
profile = "GuiButtonProfile";
horizSizing = "right";
vertSizing = "top";
position = "30 166";
extent = "120 20";
minExtent = "8 8";
visible = "1";
command = "Canvas.setContent(ServerScreen);";
text = "Find a Server";
groupNum = "-1";

text = "Info";
groupNum = "-1";
buttonType = "PushButton";
};
You may, if you wish, use the built-in GUI Editor (press F10) to do this. Make sure that
you set all of the properties to match those just listed.
The significant thing to note about these controls is the
command
property. Each one
replaces a displayed
MenuScreen
interface with a new interface, according to its function,
with the exception of the Info button.
The Info button uses the
getHelp
feature of the common code base. It searches all of the
directories 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 in
Figure 23.2, prepares a list of mission
files 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 code
and definition can be found in the

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
, and
the score limit is saved as
$Game::MaxPoints
.
FindServer Interface
The
FindServer
interface, shown in Figure 23.4, lets you browse for servers. Its code and
definition can be found in the ServerScreen modules. It will find servers that are running
on the local LAN you are connected to (if you are connected to one, of course), and it will
attempt to reach out via the Internet to contact the master servers at GarageGames and
find games for you to connect to. You are not required to use the GarageGames master
servers, but then you will have to write your own master server software to connect to.
This can be done using Torque Script but is beyond the scope of this book. There are mas-
ter server resources available from the GarageGames user community.
Client Interfaces 635
Figure 23.2 SoloPlay interface.
Figure 23.3 Host interface.
Team LRN
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
note
The Query LAN button on the
FindServer
interface does the same thing that was done automati-

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 the
bottom and then make the appropriate call to the functions that scroll the messages in the
message 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. We
can do this by checking the value of
%val
when we enter the function—it will be nonzero
when 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 at
the definition of the
ChatBox

minExtent = "8 8";
visible = "1";
setFirstResponder = "0";
bitmap = "./hudfill.png";
new GuiButtonCtrl(chatPageDown)
{
profile = "GuiButtonProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "217 54";
extent = "36 14";
minExtent = "8 8";
visible = "0";
text = "Dwn";
};
new GuiScrollCtrl(ChatScrollFrame)
{
profile = "ChatBoxScrollProfile";
horizSizing = "width";
vertSizing = "bottom";
position = "0 0";
Chapter 23

The Game Client638
Team LRN
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.


Nhờ tải bản gốc
Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status