Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 21 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
21
Dung lượng
616,59 KB
Nội dung
MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 518 node. Once you have done this, you can load your model files from the LoadContent() methods: alien0Model = Content.Load<Model>("Models\\alien0"); alien0Matrix = new Matrix[alien0Model.Bones.Count]; alien0Model.CopyAbsoluteBoneTransformsTo(alien0Matrix); alien1Model = Content.Load<Model>("Models\\alien1"); alien1Matrix = new Matrix[alien1Model.Bones.Count]; alien1Model.CopyAbsoluteBoneTransformsTo(alien1Matrix); To orient the aliens according to their direction on the Y axis, the YDirection() method is required in the game class: float YDirection(Vector3 view, Vector3 position){ Vector3 forward = view - position; return (float)Math.Atan2((double)forward.X, (double)forward.Z); } To transform the alien models when drawing and updating them, add these meth- ods to the game class: Matrix Scale(){ const float SCALAR = 0.5f; return Matrix.CreateScale(SCALAR, SCALAR, SCALAR); } Matrix TransformAliens(bool host, bool controlledLocally, Vector3 position, Vector3 view){ // 1: declare matrices Matrix yRotation, translateOffset, rotateOffset, translation; // 2: initialize matrices yRotation = Matrix.CreateRotationY(0.0f); float offsetAngle = YDirection(view, position); rotateOffset = Matrix.CreateRotationY(offsetAngle); const float YOFFSET = 0.3f; const float Z_OFFSET = 2.0f; translateOffset = Matrix.CreateTranslation(0.0f, YOFFSET, Z_OFFSET); translation = Matrix.CreateTranslation( new Vector3(position.X, 0.0f, position.Z)); // 3: build cumulative world matrix using I.S.R.O.T. sequence // identity, scale, rotate, orbit(translate & rotate), translate return yRotation * translateOffset * rotateOffset * translation; } 519 CHAPTER 29 Networking To update the local position and view data each frame, add Update- GameNetwork() to your game class. Vector3.Transform() updates the view and position coordinates according to the changes of the locally controlled aliens. Once the local view and position data is calculated, these values are passed to the net- work class for distribution across the network: public void UpdateGameNetwork(){ if (network.session == null){ // update menu if no game yet UpdateGameStart(); } else{ // otherwise update network // with latest position and view data Matrix world = Scale() * TransformAliens(host, LOCAL_CONTROL, cam.position, cam.view); Vector3 position = Vector3.Zero; Vector3 view = Vector3.Zero; view.Z =-VIEWOFFSET_Z; Vector3.Transform(ref position, ref world, out position); Vector3.Transform(ref view, ref world, out view); network.UpdateNetwork(cam.position, cam.view); } } To update your game, call UpdateGameNetwork() at the end of the Update() method in the game class: UpdateGameNetwork(); This generic DrawModels() routine will draw your models: void DrawModels(Model model, Matrix[] matrix, Matrix world){ foreach (ModelMesh mesh in model.Meshes){ foreach (BasicEffect effect in mesh.Effects){ // 4: set shader variables effect.World = matrix[mesh.ParentBone.Index] * world; effect.View = cam.viewMatrix; effect.Projection = cam.projectionMatrix; effect.EnableDefaultLighting(); effect.CommitChanges(); } // 5: draw object mesh.Draw(); } } Add DrawAliens() to your game class to render your alien models. This method is called when the game is active, and it switches views depending on whether the game is being run on the network host or from a network client: public void DrawAliens(){ Matrix world; if (network.session.RemoteGamers.Count > 0){ if (host){ // host world = Scale() * TransformAliens(host, LOCAL_CONTROL, cam.position, cam.view); DrawModels(alien0Model, alien0Matrix, world); world = Scale() * TransformAliens(host, !LOCAL_CONTROL, network.remotePosition, network.remoteView); DrawModels(alien1Model, alien1Matrix, world); } else{ // client world = Scale() * TransformAliens(host, !LOCAL_CONTROL, network.remotePosition, network.remoteView); DrawModels(alien0Model, alien0Matrix, world); world = Scale() * TransformAliens(host, LOCAL_CONTROL, cam.position, cam.view); DrawModels(alien1Model, alien1Matrix, world); } } // 1 player only else{ world = Scale() * TransformAliens(host, LOCAL_CONTROL, cam.position, cam.view); DrawModels(alien0Model, alien0Matrix, world); } } The code for drawing your aliens is triggered from the Draw() method. Since menus are displayed before 3D graphics (when the game begins), a conditional struc- ture is used to select the appropriate output based on the user’s choice. To implement this drawing code, replace the existing DrawGround() statement in Draw() with this revision: if (network.session == null){ DrawMenu(); } MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 520 521 else{ DrawGround(); DrawAliens(); } When you have finished adding this code, you will then be able to run your game on two machines. Each player will be able to control one of the aliens in the game. N ETWORK EXAMPLE: CLIENT/SERVER This next example starts with the code from the peer-to-peer solution and converts it to a client/server-based network. The main difference with this example is that the clients send their data directly to the server rather than to all of the other clients. The server then distributes the entire collection of data to the clients. To start, an extra class is needed in Network.cs to store the alien position, view, and identification: public class Alien{ public Vector3 position; public Vector3 view; public int alienID; public Alien() { } public Alien(int alienNum){ alienID = alienNum; } } The server collects all of the remote client and local data and stores it in a list, so a list declaration is needed in the XNANetwork class: public List<Alien> alienData = new List<Alien>(); A new version of GamerJoinEvent() stores the instance of each new gamer lo- cally as each new player joins the game. The structure, e.Gamer.Tag, stores each new gamer’s identity. e.Gamer.Tag will be referenced later during reads and writes to identify the gamer data. Each new gamer is added to the XNANetwork list. To add this code, replace GamerJoinEvent() with this new version: void GamerJoinEvent(object sender, GamerJoinedEventArgs e){ int gamerIndex = session.AllGamers.IndexOf(e.Gamer); CHAPTER 29 Networking e.Gamer.Tag = new Alien(gamerIndex); Alien tempAlien = new Alien(); tempAlien.alienID = gamerIndex; alienData.Add(tempAlien); } ClientWrite() belongs in the XNANetwork class to write local data from the client to the network: void ClientWrite(LocalNetworkGamer gamer, Vector3 localPosition, Vector3 localView){ Alien localAlien = gamer.Tag as Alien; // find local players in list and write their data to the network for (int i = 0; i < alienData.Count; i++){ if (alienData[i].alienID == localAlien.alienID && gamer.IsLocal){ Alien tempAlien = new Alien(); tempAlien.alienID = localAlien.alienID; tempAlien.position = localPosition; tempAlien.view = localView; alienData[i] = tempAlien; // Write our latest input state into a network packet. packetWriter.Write(alienData[i].alienID); packetWriter.Write(localPosition); packetWriter.Write(localView); } } // Send our input data to the server. gamer.SendData(packetWriter, SendDataOptions.InOrder, session.Host); } The routine that writes data packets from the server, ServerWrite(), is differ- ent than ClientWrite(). ServerWrite() sends local data to the network and also distributes all data generated on other clients as one collection. ServerWrite() must be placed inside the XNANetwork class to perform this data transfer: void ServerWrite(Vector3 localPosition, Vector3 localView){ // iterate through all local and remote players MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 522 523 foreach (NetworkGamer gamer in session.AllGamers){ Alien alien = gamer.Tag as Alien; for (int i = 0; i < alienData.Count; i++){ // update local data only if (gamer.IsLocal && alienData[i].alienID == alien.alienID){ Alien tempAlien = new Alien(); tempAlien.alienID = alien.alienID; tempAlien.position = localPosition; tempAlien.view = localView; alienData[i] = tempAlien; } // write data for all players packetWriter.Write(alienData[i].alienID); packetWriter.Write(alienData[i].position); packetWriter.Write(alienData[i].view); } } // send all data to everyone on session LocalNetworkGamer server = (LocalNetworkGamer)session.Host; server.SendData(packetWriter, SendDataOptions.InOrder); } Next, add ServerRead() to the XNANetwork class to read all remote data and store it locally in the list: void ServerRead(LocalNetworkGamer gamer){ // read all incoming packets while (gamer.IsDataAvailable){ NetworkGamer sender; // read single packet gamer.ReceiveData(packetReader, out sender); // store remote data only if (!sender.IsLocal){ int tag = packetReader.ReadInt32(); remotePosition = packetReader.ReadVector3(); remoteView = packetReader.ReadVector3(); for (int i = 0; i < alienData.Count; i++){ CHAPTER 29 Networking MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 524 if (alienData[i].alienID == tag){ Alien tempAlien = new Alien(); tempAlien.alienID = tag; tempAlien.position = remotePosition; tempAlien.view = remoteView; alienData[i] = tempAlien; } } } } } Then, add ClientRead() to read all data from the network and to store the re- mote data in the alien data list: void ClientRead(LocalNetworkGamer gamer){ while (gamer.IsDataAvailable){ NetworkGamer sender; // read single packet gamer.ReceiveData(packetReader, out sender); int gamerId = packetReader.ReadInt32(); Vector3 pos = packetReader.ReadVector3(); Vector3 view = packetReader.ReadVector3(); // get current gamer id NetworkGamer remoteGamer = session.FindGamerById(gamer.Id); // don't update if gamer left game if (remoteGamer == null) return; Alien alien = remoteGamer.Tag as Alien; // search all aliens and find match with remote ones for (int i = 0; i < alienData.Count; i++){ if (alienData[i].alienID == gamerId) { Alien tempAlien = new Alien(); tempAlien.alienID = gamerId; tempAlien.position = pos; 525 tempAlien.view = view; alienData[i] = tempAlien; remotePosition = alienData[i].position; remoteView = alienData[i].view; } } } } A revised UpdateNetwork() method must replace the existing one to handle the client/server processing. If the session is in progress, this method triggers read and write routines on the client and the server: public void UpdateNetwork(Vector3 localPosition, Vector3 localView){ // ensure session has not ended if (session == null) return; // read incoming network packets. foreach (LocalNetworkGamer gamer in session.LocalGamers) if (gamer.IsHost) ServerRead(gamer); else ClientRead(gamer); // write from clients if (!session.IsHost) foreach (LocalNetworkGamer gamer in session.LocalGamers) ClientWrite(gamer, localPosition, localView); // write from server else ServerWrite(localPosition, localView); // update session object session.Update(); } When you run your code now, your client/server network will allow you to con- trol two different aliens, each on its own machine. With either the peer-to-peer framework or the client/server framework, you have a performance-friendly way to exchange data between machines in your game as long as you design the game for ef- ficient data transfer. CHAPTER 29 Networking C HAPTER 29 REVIEW EXERCISES To get the most from this chapter, try out these chapter review exercises. 1. If you have not already done so, follow the step-by-step examples shown in this chapter to implement the peer-to-peer network sample and the client/server network sample. 2. Modify the code to allow more than one player locally. You will need to use a split-screen environment to do this. MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 526 Index A abs function, 76 Acceleration of projectiles, 308 Accept New Key option, 14 Accuracy settings for skyboxes, 147 Add/Detach Sounds option, 470–471 Add Existing Item dialog images, 34 shaders, 77 source files, 12 Add New Item dialog fonts, 193, 415 projectiles, 309 shaders, 76 Add Reference dialog, 446 Add Watch option, 18 Add Xbox 360 Name and Connection Key dialog, 14 Addition of vectors, 234–236 AddSessionEvents method, 512 AddSphere method, 292–293 AdjustBlueLevel method, 83 AdvanceAnimation method, 453 AIF files, 460 AIFF files, 460 Airplane, 109–110 direction angle, 115–118 flying with spinning propeller, 114–115 stationary with spinning propeller, 110–114 Alias FBX File format, 213 Alien class, 521 alien0.fbx file, 473, 501, 517 alien1.fbx file, 473, 501, 517 Aliens creating, 500–503 peer-to-peer networks, 517–521 Alpha channels, 127 AlphaBlendEnable method, 138 Ambient light, 355 AmbientLight method, 367 Angles airplane direction, 115–118 dot products, 244 Animated textures, 174–178 Animation, 92 asteroids, 43–45 characters. See Character movement keyframe, 344–351 matrices, 93–95 Quake II. See Quake II model Right Hand Rule, 92–93 spaceships, 473–477 sprites. See Sprites windmill, 217–219 animations enum, 446, 451–452 Application flow, 22 Apply3D method, 464, 483 Apply3DAudio method, 483–484 Arcing Projectile algorithm, 306 Arcing projectiles example, 319–320 overview, 306–309 Arctangent function, 104–107 Assemblies, 23 Assembly language, 73 Asteroid example, 42 asteroid animation, 43–45 collision detection, 48–52 completing, 52–53 images for, 42–43 rocket ship control, 45–48 Atan function, 105–106, 115–116 Atan2 function, 107, 116, 140 Atmosphere setting, 147 AttachedSounds property, 471 Attenuation of audio, 471–472 Audio, 460 adding, 477–482 attenuation, 471–472 XACT. See XACT (Cross Platform Audio Creation Tool) Zune, 487–489 Audio3DCue class, 483 AudioEmitter class, 463, 482 AudioEngine class, 461–462 AudioListener class, 463, 482 audioProject.xap file, 473, 477–478 Auditioning Utility, 468 Authoring tool, 461, 464–468 AutoComplete format, 12 AvailableNetworkSessionCollection class, 508 B backwall.jpg file, 135 Ballistics arcing projectiles, 306–309 arcing projectiles example, 319–320 linear projectiles, 306–307 linear projectiles example, 309–319 Bandwidth for networks, 506–507 Bank setting for images, 148 base.fbx file, 216 Base for windmill creating, 205–206 exporting, 213 Base Surface tab, 422 Basic Sculpting tool, 421 BasicEffect class, 70 car object, 226 default lighting, 356–357 directional lighting, 357–362 Quake II model, 448–449 shaders, 86–89 windmill, 215–216 527 [...]... 199 GUIDE Friction with projectiles, 308 Frustum, 270 fx extension, 76 G Game controllers See Controllers Game pad buttons, 391–392 Game stats fonts for, 193–198 frames-per-second count, 198–199 Game Studio projects, 8 Game windows, 22 closing, 26 drawing and updating, 25–26 example, 26–28 game foundation, 22–25 Game1 class, 27–28 Game1 .cs file audio, 477 cameras, 272 color shaders, 83 fire example, 336... 23 new projects, 12, 27 particles, 336 projectiles, 312 vertices, 97 GamePadState class input, 494, 497 Quake II animation, 453 states, 41, 380–381, 390 GamerEnded event, 508 GamerJoined event, 508–509 GamerJoinEvent method, 509, 512, 521–522 GamerLeft event, 508 GamerServices class, 507, 514 GamerServicesComponent class, 507, 514 GameStarted event, 508 Generate Connection Key option, 14 generateNormals... Merging groups Quake II model, 441 windmill, 210–211 Meshes drawing, 216, 218–219 Quake II model, 438, 441–442 MGH360BaseCode projects, 60, 79 MGHGame namespace, 291–292 MGHWinBaseCode projects, 60, 79 Microsoft. Xna. Framework library, 234 Microsoft XNA Game Studio, 8 MiddleButton property, 379 I N D E X MilkShape application, 202–203 animated models, 440–457 windmill example See Windmill Milliseconds... Martian, 60, 65–66 NUM_COLS setting, 421 NUM_ROWS setting, 421 O OBJ files, 203 OffsetFromCamera method, 224 Opaque textures, 134–137 Open dialog materials, 207 wave files, 465 Opening Game Studio projects, 8–9 Microsoft XNA Game Studio, 8 Orbits, 92, 94 Origins animated sprites, 36 windmill, 211 Outputs, shaders, 73–74 Overlapping objects See Collision detection N P Namespaces, 23 Near clip planes, 270 Network.cs... 360 Game projects, 8 compiling and running, 12–13 creating, 10–11 deploying, 14–15 saving, 13 Xbox LIVE Arcade, 32 Xbox36 0Game1 namespace, 23 XNA Creators Club, 3 XNA Game Studio Connect application, 3–4, 14 XNA game template wizard, 34 XNANetwork class, 511–514, 521–523 Y Y axes in Right Hand Rule, 92–93 Y coordinates mouse, 389 pixels, 32 vectors, 234 Y planes 3D graphics, 56 linear projectiles,... cylinders for, 206 drawing, 215–219 exporting, 213 group merging, 210–211 GAME STUDIO CREATOR’S joints, 211–212 loading, 214–217 positioning, 211 project for, 204–205 saving, 212–213 spheres for, 206, 209 textures, 206–207 windmill.bmp file, 207, 213, 216 Windows Game projects, 8 creating, 9–10 custom content processors, 405–417 WindowsGame1 namespace, 23, 26–27 World matrix, 93 building, 96, 99 description,... 477 Engines sound, 466 Error Lists, 10–11, 15–16 Errors, debugging, 15–16 Events input devices, 385–388 network sessions, 508–509 Examples, downloading, 5–6 Existing Game Studio projects, 8–9 Export Heightfield dialog, 422 GAME STUDIO CREATOR’S Exporting height maps, 422–423 to md2 format, 445–446 windmill, 213 ExtractBoundingSphere method, 296–297 Eyebrows, Martian, 60, 66–67 Eyes, Martian, 59–60,... 56–58 Linear interpolation, 123 Linear Projectile algorithm, 306 Linear projectiles example, 309–319 overview, 306–307 GAME STUDIO CREATOR’S LineList type, 58 LineStrip type, 58 Lists Martian eyebrows, 66–67 Martian eyes, 63–65, 67–68 primitive objects, 56–58 LIVE Arcade, 32 LIVE Community Games, 5 Load method shaders, 77 textures, 121, 132 windmill, 217 LoadContent method audio, 487 car object, 221 cursor,... loading, 446–451 meshes, 441–442 pivoting animation, 443–444 previewing animation, 445 GAME STUDIO CREATOR’S skeletons, 441–442 weapons, 454–457 Quality setting for skybox images, 147 Quaternion theory, 277–280 R Random class, 336 RankedAll network connectivity type, 508 Raw image files, 33 Read method ContentTypeReader, 404 XNANetwork, 513–514 ReadAllBytes method, 403, 408 ReadAllText method, 403 ReadBoolean... network, 506 DeleteAudio method, 478 Delta Halo level, 139 Deploying games Xbox 360 projects, 14–15 to Zune, 4–5 Depth of animated sprites layers, 36 Detail setting for skyboxes, 147 Developer basics, 8 code project management, 8–9 debugging, 15–19 deploying, 14–15 editing, 12–13 Windows Game projects, 9–10 Xbox 360 Game projects, 10–11 Zune game projects, 11 Development environment setup, 2–5 DeviceReset . 60, 79 MGHGame namespace, 291–292 MGHWinBaseCode projects, 60, 79 Microsoft. Xna. Framework library, 234 Microsoft XNA Game Studio, 8 MiddleButton property, 379 MICROSOFT XNA GAME STUDIO CREATOR’S. (LocalNetworkGamer gamer in session.LocalGamers) if (gamer.IsHost) ServerRead(gamer); else ClientRead(gamer); // write from clients if (!session.IsHost) foreach (LocalNetworkGamer gamer in session.LocalGamers) ClientWrite(gamer,. packetReader.ReadVector3(); // get current gamer id NetworkGamer remoteGamer = session.FindGamerById(gamer.Id); // don't update if gamer left game if (remoteGamer == null) return; Alien alien = remoteGamer.Tag as Alien; //