1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning XNA 2.0 Game Programming From Novice to Professional phần 4 pptx

45 262 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 45
Dung lượng 609,93 KB

Nội dung

// Game Stuff protected int score; protected int power; private const int INITIALPOWER = 100; public Player(Game game, ref Texture2D theTexture, PlayerIndex playerID, Rectangle rectangle) : base(game) { texture = theTexture; position = new Vector2(); playerIndex = playerID; // Create the source rectangle. // This represents where the sprite picture is in the surface spriteRectangle = rectangle; #if XBOX360 // On the 360, we need to take care about the TV "safe" area. screenBounds = new Rectangle((int)(Game.Window.ClientBounds.Width * 0.03f),(int)(Game.Window.ClientBounds.Height * 0.03f), Game.Window.ClientBounds.Width - (int)(Game.Window.ClientBounds.Width * 0.03f), Game.Window.ClientBounds.Height - (int)(Game.Window.ClientBounds.Height * 0.03f)); #else screenBounds = new Rectangle(0, 0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height); #endif } /// <summary> /// Put the ship in your start position in screen /// </summary> public void Reset() { if (playerIndex == PlayerIndex.One) { position.X = screenBounds.Width/3; } else { CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME 109 9241CH04.qxd 3/10/08 10:34 AM Page 109 position.X = (int) (screenBounds.Width/1.5); } position.Y = screenBounds.Height - spriteRectangle.Height; score = 0; power = INITIALPOWER; } /// <summary> /// Total Points of the Player /// </summary> public int Score { get { return score; } set { if (value < 0) { score = 0; } else { score = value; } } } /// <summary> /// Remaining Power /// </summary> public int Power { get { return power; } set { power = value; } } /// <summary> /// Update the ship position, points, and power /// </summary> public override void Update(GameTime gameTime) { // Move the ship with the Xbox controller CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME110 9241CH04.qxd 3/10/08 10:34 AM Page 110 GamePadState gamepadstatus = GamePad.GetState(playerIndex); position.Y += (int) ((gamepadstatus.ThumbSticks.Left.Y*3)*-2); position.X += (int) ((gamepadstatus.ThumbSticks.Left.X*3)*2); // Move the ship with the keyboard if (playerIndex == PlayerIndex.One) { HandlePlayer1KeyBoard(); } else { HandlePlayer2KeyBoard(); } // Keep the player inside the screen KeepInBound(); // Update score elapsedTime += gameTime.ElapsedGameTime; if (elapsedTime > TimeSpan.FromSeconds(1)) { elapsedTime -= TimeSpan.FromSeconds(1); score++; power ; } base.Update(gameTime); } /// <summary> /// Keep the ship inside the screen /// </summary> private void KeepInBound() { if (position.X < screenBounds.Left) { position.X = screenBounds.Left; } if (position.X > screenBounds.Width - spriteRectangle.Width) { position.X = screenBounds.Width - spriteRectangle.Width; CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME 111 9241CH04.qxd 3/10/08 10:34 AM Page 111 } if (position.Y < screenBounds.Top) { position.Y = screenBounds.Top; } if (position.Y > screenBounds.Height - spriteRectangle.Height) { position.Y = screenBounds.Height - spriteRectangle.Height; } } /// <summary> /// Handle the keys for the player 1 (arrow keys) /// </summary> private void HandlePlayer1KeyBoard() { KeyboardState keyboard = Keyboard.GetState(); if (keyboard.IsKeyDown(Keys.Up)) { position.Y -= 3; } if (keyboard.IsKeyDown(Keys.Down)) { position.Y += 3; } if (keyboard.IsKeyDown(Keys.Left)) { position.X -= 3; } if (keyboard.IsKeyDown(Keys.Right)) { position.X += 3; } } /// <summary> /// Handle the keys for the player 2 (ASDW) /// </summary> private void HandlePlayer2KeyBoard() { KeyboardState keyboard = Keyboard.GetState(); if (keyboard.IsKeyDown(Keys.W)) CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME112 9241CH04.qxd 3/10/08 10:34 AM Page 112 { position.Y -= 3; } if (keyboard.IsKeyDown(Keys.S)) { position.Y += 3; } if (keyboard.IsKeyDown(Keys.A)) { position.X -= 3; } if (keyboard.IsKeyDown(Keys.D)) { position.X += 3; } } /// <summary> /// Draw the ship sprite /// </summary> public override void Draw(GameTime gameTime) { // Get the current spritebatch SpriteBatch sBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); // Draw the ship sBatch.Draw(texture, position, spriteRectangle, Color.White); base.Draw(gameTime); } /// <summary> /// Get the bound rectangle of ship position in screen /// </summary> public Rectangle GetBounds() { return new Rectangle((int) position.X, (int) position.Y, spriteRectangle.Width, spriteRectangle.Height); } } } CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME 113 9241CH04.qxd 3/10/08 10:34 AM Page 113 As you can see, this is practically the same class as in the previous chapter, but in the Update() method you handle the user input a little differently, testing the PlayerIndex to check for the correct gamepad or keyboard keys. In a multiplayer game, you’ll instantiate two objects for this class with different PlayerIndexes and different rectangles in texture, for different ship sprites. Bringing Everything Together Now you have all the action scene components. The meteors, the score, and the player (or players) are ready to be put to work. Now add a class called ActionScene. This scene is the most complex scene of the game. It coordinates the action of all the components, as well as controls the game state, such as pause and gameOver. Start declaring all elements of this scene, as follows: // Basics protected Texture2D actionTexture; protected Cue backMusic; protected SpriteBatch spriteBatch = null; // Game Elements protected Player player1; protected Player player2; protected MeteorsManager meteors; protected PowerSource powerSource; protected SimpleRumblePad rumblePad; protected ImageComponent background; protected Score scorePlayer1; protected Score scorePlayer2; // GUI Stuff protected Vector2 pausePosition; protected Vector2 gameoverPosition; protected Rectangle pauseRect = new Rectangle(1, 120, 200, 44); protected Rectangle gameoverRect = new Rectangle(1, 170, 350, 48); // GameState elements protected bool paused; protected bool gameOver; protected TimeSpan elapsedTime = TimeSpan.Zero; protected bool twoPlayers; CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME114 9241CH04.qxd 3/10/08 10:34 AM Page 114 It looks like the attributes from the game in the previous chapter, but you now have two Player instances (for a multiplayer game), two attributes for controlling the game state ( paused and gameOver) and the components for Score, PowerSource, Meteors, and so on. The constructor initializes all these objects, as follows: /// <summary> /// Default Constructor /// </summary> /// <param name="game">The main game object</param> /// <param name="theTexture">Texture with the sprite elements</param> /// <param name="backgroundTexture">Texture for the background</param> /// <param name="font">Font used in the score</param> public ActionScene(Game game, Texture2D theTexture, Texture2D backgroundTexture, SpriteFont font) : base(game) { // Get the current audiocomponent and play the background music audioComponent = (AudioComponent) Game.Services.GetService(typeof (AudioComponent)); background = new ImageComponent(game, backgroundTexture, ImageComponent.DrawMode.Stretch); Components.Add(background); actionTexture = theTexture; spriteBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch)); meteors = new MeteorsManager(Game, ref actionTexture); Components.Add(meteors); player1 = new Player(Game, ref actionTexture, PlayerIndex.One, new Rectangle(323, 15, 30, 30)); player1.Initialize(); Components.Add(player1); player2 = new Player(Game, ref actionTexture, PlayerIndex.Two, new Rectangle(360, 17, 30, 30)); player2.Initialize(); Components.Add(player2); scorePlayer1 = new Score(game, font, Color.Blue); scorePlayer1.Position = new Vector2(10, 10); CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME 115 9241CH04.qxd 3/10/08 10:34 AM Page 115 Components.Add(scorePlayer1); scorePlayer2 = new Score(game, font, Color.Red); scorePlayer2.Position = new Vector2( Game.Window.ClientBounds.Width - 200, 10); Components.Add(scorePlayer2); rumblePad = new SimpleRumblePad(game); Components.Add(rumblePad); powerSource = new PowerSource(game, ref actionTexture); powerSource.Initialize(); Components.Add(powerSource); } See how you create two instances for the Player class. For each player, just change the PlayerIndex and the Rectangle of the image of the ship in the texture. You also need to control the game state and define if the game is for one or two players, or check if some of the players are already dead. Add these properties to the class: /// <summary> /// Indicate the 2-players game mode /// </summary> public bool TwoPlayers { get { return twoPlayers; } set { twoPlayers = value; } } /// <summary> /// True, if the game is in gameOver state /// </summary> public bool GameOver { get { return gameOver; } } /// <summary> /// Paused mode /// </summary> public bool Paused { get { return paused; } set CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME116 9241CH04.qxd 3/10/08 10:34 AM Page 116 { paused = value; if (paused) { backMusic.Pause(); } else { backMusic.Resume(); } } } Like all the other scenes, you can use the Show() and Hide() methods to initialize and release scene components. In the Show() method you start playing the background music and setting the player2 status if you have a two-player game: /// <summary> /// Show the action scene /// </summary> public override void Show() { backMusic = audioComponent.GetCue("backmusic"); backMusic.Play(); meteors.Initialize(); powerSource.PutinStartPosition(); player1.Reset(); player2.Reset(); paused = false; pausePosition.X = (Game.Window.ClientBounds.Width - pauseRect.Width)/2; pausePosition.Y = (Game.Window.ClientBounds.Height - pauseRect.Height)/2; gameOver = false; gameoverPosition.X = (Game.Window.ClientBounds.Width - gameoverRect.Width)/2; gameoverPosition.Y = (Game.Window.ClientBounds.Height - gameoverRect.Height)/2; CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME 117 9241CH04.qxd 3/10/08 10:34 AM Page 117 // Is it a two-player game? player2.Visible = twoPlayers; player2.Enabled = twoPlayers; scorePlayer2.Visible = twoPlayers; scorePlayer2.Enabled = twoPlayers; base.Show(); } /// <summary> /// Hide the scene /// </summary> public override void Hide() { // Stop the background music backMusic.Stop(AudioStopOptions.Immediate); // Stop the rumble rumblePad.Stop(PlayerIndex.One); rumblePad.Stop(PlayerIndex.Two); base.Hide(); } And, as always, the Update() method synchronizes all these objects, checking the collisions and changing the game state for game over when some players die. /// <summary> /// Allows the GameComponent to update itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> public override void Update(GameTime gameTime) { if ((!paused) && (!gameOver)) { // Check collisions with meteors HandleDamages(); // Check if a player gets a power boost HandlePowerSourceSprite(gameTime); // Update score scorePlayer1.Value = player1.Score; scorePlayer1.Power = player1.Power; CHAPTER 4 ■ IMPROVING YOUR FIRST 2-D GAME118 9241CH04.qxd 3/10/08 10:34 AM Page 118 [...]... easy to add new features to your game, as you’ll see in the next chapter However, try putting new meteor types or new ways to acquire energy, for instance You’ll start to understand how games are “assembled” from GameComponents 127 9 241 CH 04. qxd 128 3/10/08 10: 34 AM Page 128 CHAPTER 4 s IMPROVING YOUR FIRST 2-D GAME Summary You started from a simple game and evolved that into a more elaborate game with... Provides a snapshot of timing values. protected override void Update(GameTime gameTime) { // Handle Game Inputs HandleScenesInput(); 123 9 241 CH 04. qxd 1 24 3/10/08 10: 34 AM Page 1 24 CHAPTER 4 s IMPROVING YOUR FIRST 2-D GAME base.Update(gameTime); } HandleScenesInput() just calls the handler for the active scene in the game: /// /// Handle input of all game scenes... messages passed between the groups to be as small as possible Figure 5 -4 illustrates a game network topology based on groups Figure 5 -4 A group-based network topology This approach is also used in network games, being a mix of the client/server and peer -to- peer topologies that tries to gather the benefits of each one 9 241 CH05.qxd 3/12/08 11 :44 AM Page 133 CHAPTER 5 s BASICS OF GAME NETWORKING In the next... Network Features from the Beginning It’s far better to code everything from the ground up than to try to adjust a stand-alone game to support networking, if it was not planned to do so Even in a simple program you might face situations where adjusting the program will lead to a less than optimal result, compared to writing the game with networking in mind So if you’re planning to create a game that will... constructor, just after the line that sets the content root directory: Components.Add(new GamerServicesComponent(this)); Run the game now If you already have a LIVE profile configured for automatic login, your profile will sign in, and you’ll see a button on the center bottom of the blank game screen, as shown in Figure 5-5 139 9 241 CH05.qxd 140 3/12/08 11 :44 AM Page 140 CHAPTER 5 s BASICS OF GAME NETWORKING... navigates to the Game for Windows—LIVE site Customize Profile enables you to configure your profile (for example, the profile image) according to your preferences You can close the window by clicking the Done button After configuring your profile, and joining LIVE if you want—and we recommend you do so—click the Done button and let’s go on coding our sample! 141 9 241 CH05.qxd 142 3/12/08 11 :44 AM Page 142 ... object and call this method To do this, you must define the new object in the Game1 class: NetworkHelper networkHelper; Then, in the Initialize method of the Game1 class, you must create the object: networkHelper = new NetworkHelper(); 143 9 241 CH05.qxd 144 3/12/08 11 :44 AM Page 144 CHAPTER 5 s BASICS OF GAME NETWORKING Finally, you must call the method in the Update method of the Game1 class, which will... override void Draw(GameTime gameTime) { 121 9 241 CH 04. qxd 122 3/10/08 10: 34 AM Page 122 CHAPTER 4 s IMPROVING YOUR FIRST 2-D GAME // Draw all GameComponents base.Draw(gameTime); if (paused) { // Draw the "pause" text spriteBatch.Draw(actionTexture, pausePosition, pauseRect, Color.White); } if (gameOver) { // Draw the "gameover" text spriteBatch.Draw(actionTexture, gameoverPosition, gameoverRect, Color.White);... code, from the first version, to be “network-friendly.” For example, isolate the routines that deal with user input from the rest of the game, so you can change these routines to receive remote input later Also, plan how to synchronize input from all players, even if in the first version all players are local 9 241 CH05.qxd 3/12/08 11 :44 AM Page 135 CHAPTER 5 s BASICS OF GAME NETWORKING s Note XNA network... useful to any kind of game You saw the value of the GameComponents and their reuse capability Feel free to improve and change this game and build your own awesome version of Rock Rain! 9 241 CH05.qxd 3/12/08 11 :44 AM CHAPTER Page 129 5 Basics of Game Networking I n this chapter you’ll see basic concepts involved in creating games that support networking, so you’ll be prepared to create a real multiplayer game . “assembled” from GameComponents. CHAPTER 4 ■ IMPROVING YOUR FIRST 2- D GAME 127 9 24 1CH 04. qxd 3/ 10/ 08 10: 34 AM Page 127 Summary You started from a simple game and evolved that into a more elaborate game. Update(GameTime gameTime) { // Move the ship with the Xbox controller CHAPTER 4 ■ IMPROVING YOUR FIRST 2- D GAME1 10 9 24 1CH 04. qxd 3/ 10/ 08 10: 34 AM Page 1 10 GamePadState gamepadstatus = GamePad.GetState(playerIndex); position.Y. values.</param> public override void Draw(GameTime gameTime) { CHAPTER 4 ■ IMPROVING YOUR FIRST 2- D GAME 121 9 24 1CH 04. qxd 3/ 10/ 08 10: 34 AM Page 121 // Draw all GameComponents base.Draw(gameTime); if (paused) { //

Ngày đăng: 12/08/2014, 09:20

TỪ KHÓA LIÊN QUAN