# Microsoft XNA Game Studio Creator’s Guide- P19

Chia sẻ: Cong Thanh | Ngày: | Loại File: PDF | Số trang:21

0
56
lượt xem
9

## Microsoft XNA Game Studio Creator’s Guide- P19

Mô tả tài liệu

Microsoft XNA Game Studio Creator’s Guide- P19:The release of the XNA platform and specifically the ability for anyone to write Xbox 360 console games was truly a major progression in the game-programming world. Before XNA, it was simply too complicated and costly for a student, software hobbyist, or independent game developer to gain access to a decent development kit for a major console platform.

Chủ đề:

Bình luận(0)

Lưu

## Nội dung Text: Microsoft XNA Game Studio Creator’s Guide- P19

1. 518 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE node. Once you have done this, you can load your model files from the LoadContent() methods: alien0Model = Content.Load("Models\\alien0"); alien0Matrix = new Matrix[alien0Model.Bones.Count]; alien0Model.CopyAbsoluteBoneTransformsTo(alien0Matrix); alien1Model = Content.Load("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; }
2. C H A P T E R 2 9 519 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(); } }
3. 520 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 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(); }
4. C H A P T E R 2 9 521 Networking 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 alienData = new List(); 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);
5. 522 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 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
8. C H A P T E R 2 9 525 Networking 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.
9. 526 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE 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.