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 263 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

Tiêu đề Beginning XNA 2.0 Game Programming From Novice to Professional phần 4 pptx
Trường học University of Southern California
Chuyên ngành Game Programming
Thể loại Slide Presentation
Năm xuất bản 2008
Thành phố Los Angeles
Định dạng
Số trang 45
Dung lượng 609,93 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

// Game Stuffprotected int score;protected int power; private const int INITIALPOWER = 100; public PlayerGame game, ref Texture2D theTexture, PlayerIndex playerID, Rectangle rectangle :

Trang 1

// Game Stuffprotected 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 surfacespriteRectangle = 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 -

/// Put the ship in your start position in screen/// </summary>

public void Reset(){

if (playerIndex == PlayerIndex.One){

position.X = screenBounds.Width/3;

}else{

Trang 2

position.X = (int) (screenBounds.Width/1.5);

}position.Y = screenBounds.Height - spriteRectangle.Height;score = 0;

score = 0;

}else{score = value;

}}}/// <summary>

/// Remaining Power/// </summary>

public int Power{

get { return power; }set { power = value; }}

Trang 3

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 screenKeepInBound();

// Update scoreelapsedTime += 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){

Trang 4

if (position.Y < screenBounds.Top){

/// 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))

Trang 5

{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;

}}

// Draw the shipsBatch.Draw(texture, position, spriteRectangle, Color.White);

Trang 6

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 PlayerIndextocheck for the correct gamepad or keyboard keys In a multiplayer game, you’ll instantiatetwo 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 isthe most complex scene of the game It coordinates the action of all the components, aswell as controls the game state, such as pauseand 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;

Trang 7

It looks like the attributes from the game in the previous chapter, but you now havetwo Playerinstances (for a multiplayer game), two attributes for controlling the game

state (pausedand 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 musicaudioComponent = (AudioComponent)

meteors = new MeteorsManager(Game, ref actionTexture);

scorePlayer1 = new Score(game, font, Color.Blue);

scorePlayer1.Position = new Vector2(10, 10);

Trang 8

scorePlayer2 = new Score(game, font, Color.Red);

scorePlayer2.Position = new Vector2(

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:

Trang 9

{paused = value;

if (paused){

backMusic.Pause();

}else{backMusic.Resume();

}}}

Like all the other scenes, you can use the Show()and Hide()methods to initialize andrelease scene components In the Show()method you start playing the background music

and setting the player2status if you have a two-player game:

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;

Trang 10

/// <param name="gameTime">Provides a snapshot of timing values.</param>

public override void Update(GameTime gameTime)

scorePlayer1.Power = player1.Power;

Trang 11

if (twoPlayers){

scorePlayer2.Value = player2.Score;

scorePlayer2.Power = player2.Power;

}// Check if player is deadgameOver = ((player1.Power <= 0) || (player2.Power <= 0));

if (gameOver){

player1.Visible = (player1.Power > 0);

player2.Visible = (player2.Power > 0) && twoPlayers;

// Stop the musicbackMusic.Stop(AudioStopOptions.Immediate);

// Stop rumblerumblePad.Stop(PlayerIndex.One);

rumblePad.Stop(PlayerIndex.Two);

}// Update all other GameComponentsbase.Update(gameTime);

}// In gameOver state, keep the meteors' animation

if (gameOver){

meteors.Update(gameTime);

}}

The HandleDamages()and HandlePowerSourceSprite()methods check the collisionswith the meteors (and lose some player power), check the collision with the power source

(and add some power to the player), and check if a player has zero or less power to end

the game and put him or her in a game over state

The HandleDamages()method is also similar to the collision test method from the vious chapter Again, this method checks the collision with the players and meteors and

pre-one player with another player For each collision the player loses ten points and ten

Trang 12

// Check Collision for player 1

if (meteors.CheckForCollisions(player1.GetBounds())){

// Shake!

rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);

// Player penaltyplayer1.Power -= 10;

player1.Score -= 10;

}// Check Collision for player 2

if (twoPlayers){

if (meteors.CheckForCollisions(player2.GetBounds())){

// Shake!

rumblePad.RumblePad(PlayerIndex.Two, 500, 1.0f, 1.0f);

// Player penaltyplayer2.Power -= 10;

player2.Score -= 10;

}// Check for collision between the players

if (player1.GetBounds().Intersects(player2.GetBounds())){

The HandlePowerSourceSprite()method does the same job, but with the PowerSource

sprite If some player collides with this sprite, he or she gets 50 power units The methodalso checks if it’s time to send a new power source in the game, using an interval of

15 seconds

Trang 13

// Player 1 gets the power sourceaudioComponent.PlayCue("powerget");

// Player 2 gets the power source

if (powerSource.CheckCollision(player2.GetBounds())){

if (elapsedTime > TimeSpan.FromSeconds(15)){

elapsedTime -= TimeSpan.FromSeconds(15);

powerSource.Enabled = true;

}}

And finally, the Draw()method just draws some objects for a specified game state:

/// <summary>

/// Allows the GameComponent to draw itself

/// </summary>

/// <param name="gameTime">Provides a snapshot of timing values.</param>

public override void Draw(GameTime gameTime)

{

Trang 14

// Draw all GameComponentsbase.Draw(gameTime);

if (paused){

// Draw the "pause" textspriteBatch.Draw(actionTexture, pausePosition, pauseRect, Color.White);

}

if (gameOver){

// Draw the "gameover" textspriteBatch.Draw(actionTexture, gameoverPosition, gameoverRect, Color.White);

}

Observe that once again, a great deal of the game logic that you created in the ous chapter was kept You only added the two-player support and two more game states:one when the user pauses the game (pressing the Enter key or pressing the A button onthe Xbox 360 gamepad during the game), or when one of the players runs out of energy.When this happens, the game shows a message on the screen and waits for the player topress the Enter key or the A button on the Xbox 360 gamepad

previ-Navigating Between the Scenes

With all the scenes created, now you only need to show them according to users’ wishes.Through the menu in the opening scene, users can show the help scene, the action scene(with one or two players), or just leave the game Here, you’ll use a technique in whichyou concentrate all the inputs that refer to the navigation or control of the scene states inone class In this case you use the Game1class, so that you have a central point where youshoot the scenes and control the Game1class’s state Add the following code in the Game1

class:

private readonly GraphicsDeviceManager graphics;

private SpriteBatch spriteBatch;

// Textures

protected Texture2D helpBackgroundTexture, helpForegroundTexture;

protected Texture2D startBackgroundTexture, startElementsTexture;

protected Texture2D actionElementsTexture, actionBackgroundTexture;

// Game Scenes

protected HelpScene helpScene;

Trang 15

protected StartScene startScene;

protected ActionScene actionScene;

protected GameScene activeScene;

// Audio Stuff

private AudioComponent audioComponent;

// Fonts

private SpriteFont smallFont, largeFont, scoreFont;

// Used to handle input

protected KeyboardState oldKeyboardState;

protected GamePadState oldGamePadState;

In the LoadContent()method, add the code to create and load the content for the

/// Allows the game to run logic such as updating the world,

/// checking for collisions, gathering input, and playing audio

/// </summary>

/// <param name="gameTime">Provides a snapshot of timing values.</param>

protected override void Update(GameTime gameTime)

{

// Handle Game Inputs

HandleScenesInput();

Trang 16

}// Handle Help Scene Inputelse if (activeScene == helpScene){

if (CheckEnterA()){

ShowScene(startScene);

}}// Handle Action Scene Inputelse if (activeScene == actionScene){

HandleActionInput();

}}

The CheckEnterA()method is a simple code to test the Enter key and the A button on

an Xbox 360 gamepad:

/// <summary>

/// Check if the Enter Key or A button was pressed

/// </summary>

/// <returns>true, if Enter key or A button was pressed</returns>

private bool CheckEnterA()

Trang 17

bool result = (oldKeyboardState.IsKeyDown(Keys.Enter) &&

audioComponent.PlayCue("menu_select3");

switch (startScene.SelectedMenuIndex){

Trang 18

HandleActionInput()handles input in the action scene to pause and cancel a game,using a keyboard or an Xbox 360 gamepad:

/// <summary>

/// Check if the Enter Key or A button was pressed

/// </summary>

/// <returns>true, if Enter key or A button was pressed</returns>

private void HandleActionInput()

{

// Get the Keyboard and GamePad stateGamePadState gamepadState = GamePad.GetState(PlayerIndex.One);

KeyboardState keyboardState = Keyboard.GetState();

bool backKey = (oldKeyboardState.IsKeyDown(Keys.Escape) &&

if (actionScene.GameOver){

ShowScene(startScene);

}else{audioComponent.PlayCue("menu_back");

actionScene.Paused = !actionScene.Paused;

}}

if (backKey){

ShowScene(startScene);

Trang 19

The ShowScene()method is just a helper to Show()a new scene and Hide()a previousscene, as follows:

/// <summary>

/// Open a new scene

/// </summary>

/// <param name="scene">Scene to be opened</param>

protected void ShowScene(GameScene scene)

/// <param name="gameTime">Provides a snapshot of timing values.</param>

protected override void Draw(GameTime gameTime)

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

Trang 20

You started from a simple game and evolved that into a more elaborate game with simpletechniques that are useful to any kind of game You saw the value of the GameComponentsand their reuse capability Feel free to improve and change this game and build your ownawesome version of Rock Rain!

Trang 21

Basics of Game Networking

In this chapter you’ll see basic concepts involved in creating games that support

net-working, so you’ll be prepared to create a real multiplayer game in the next chapter

Introducing Multiplayer Games

Online multiplayer games, also known as network-enabled games or simply networked

games, are hard to code Period

That said, it’s also important to state that, in XNA, this difficulty is not related to ing for connecting the machines (PCs or Xbox 360) or making them talk with each other

cod-That’s because XNA hides all complexities from you in this case, as it does with

every-thing else in the framework

Networked games are hard to code because there are many extra problems to dealwith: your program will receive messages from the host or other players, send messages

back to them, process the local player input, and perform the physics and artificial

intel-ligence calculations, while not letting the screen freeze between each frame drawn (one

of the worst things that might happen in a multiplayer game)

Fortunately, XNA can help us with most of the communication problems, such asproviding ways to control the message flow between players and host to guarantee that

no message is lost and that all messages arrive in the same order they were sent, if you

want to Nevertheless, there will still be some problems to solve

Before discussing the details of XNA support for networking, let’s look at some basicconcepts about networked games and some of the most common problems faced when

coding such games, in the next sections

Choosing the Network Topology

The most common topologies for networked games are peer-to-peer and client/server

connections, and because XNA network implementation is not tied to any type of

con-nection, you can code any of these types depending on the way you organize your

network code

129

C H A P T E R 5

Trang 22

In peer-to-peer connections, every player is aware of every other player in the game,sending and receiving messages from, and to, all players, as illustrated in Figure 5-1.

Figure 5-1.Peer-to-peer connection

The most obvious benefit of using this network organization is that you don’t need adedicated server to play the game, so every group of players can play it within their ownlocal area network (LAN), or even through the Internet, as long as they know the

addresses of the other members of the group

In this type of connection, one of the players acts as a host, so all the new playersconnect to that player However, once connected, the messages flow directly from oneplayer to all the others If the player who is also the host disconnects from the game, thegame might stop or simply choose another player as the new host, depending on whatthe game developers defined

The main problem you face when coding peer-to-peer games is that you can’t havetoo many players in the same game session, because the number of messages willincrease exponentially with every new player who joins For instance, in Figure 5-1 wehave 4 players, so every time a player needs to update his or her status (for example,move), you send 3 messages, one for each player Because you have 4 players, duringeach game turn you exchange 4 3 = 12 messages Making the same calculations with a 5-player game increases this to 5 4 = 20 messages per turn, and in a 6-player gameyou’ll reach 6 5 = 30 messages

Usually, having more than ten players in the same game session is not suggested,because every message can take dozens of bytes and you’ll consume the bandwidthavailable in your network quickly But it’s still possible if the game development team canmake the messages as small as possible; for example, passing only the players’ inputsacross the computers, and letting games on every player’s machine calculate everythingelse from these inputs

The second most common game network topology is client/server In this kind ofnetwork, all players connect to a host, which usually processes the messages and does

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

TỪ KHÓA LIÊN QUAN