DCSIMG
XNA 2D Game Tutorial (Part 11) - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

XNA 2D Game Tutorial (Part 11)

Previous posts in this series:

In the previous part we did some collision detection between the player’s missiles and the aliens. If hit, the alien disappeared gradually (as opposed to a big explosion). Let’s add some more collision detection.

First, a small bug fix: if we keep killing aliens, eventually new one won’t be generated. The reason is the Killed event is not handled and so the number of current “live” aliens never decreases…

This is fixable by adding handling of the Killed event like so:

alien.Killed += a => {

   _currentLiveAliens--;

};

 

Currently, the player is invincible – she cannot be killed or hurt in any way. It’s time to change that. We need to check each “live” alien with the player. If there’s a hit, we’ll create an explosion.

Where should we do the collision check? As usual in these cases, we can do that from either the aliens side or the player side. Which one is “better”? In this case I’d prefer doing it from the aliens side. Why? Because we’re already iterating over the aliens – all we need is add one additional check for collision with the single player sprite. If we’d go the other way around, we’d have to create another loop for checking against all aliens – less efficient.

First, we need access to the player component from the aliens component. we’ll do that similarly to the way we exposed the aliens component – by exposing it via a readonly field:

public readonly PlayerComponent PlayerComponent;

 

and setting it in the game’s constructor while creating the component:

Components.Add(PlayerComponent = new PlayerComponent(this));

 

The next thing we need to prepare is to expose the player’s sprite for external access (currently it’s a private field):

public Sprite Player { get { return _player; } }

 

Now we can actually implement the collision check in AliensComponent.Update:

var pc = AlienRaidGame.Current.PlayerComponent;

 

foreach(var alien in _aliens)

   if(alien != null && alien.Active) {

      alien.Update(gameTime);

      if(!alien.IsDying && pc.Player.Active && alien.Collide(pc.Player)) {

         // player hit!

         alien.Hit(5);   // alien hit, too!

         pc.Player.Active = false;   // deactivate for now

      }

   }

 

If we run the game now, any alien that hits the player causes the ship to disappear, never to appear again. Only one life right now!

Let’s add some explosion sprite when the player’s ship explodes and an explosion sound, too. We’ll use the 6 frame explosion inside the file sprites.png, which is already one of our game assets.

First, we’ll add a PlayerHit method to PlayerComponent, so that the player can handle its own hit logic:

public void PlayerHit(int power = 1) {

   // player always dies

   _player.Active = false;

   // setup explosion

   _playerExplodeSound.Play();

}

 

The player is simply deactivated. I’ve also added an explosion sound (in the usual way). When an alien collides with the player, this method should be called:

if(!alien.IsDying && pc.Player.Active && alien.Collide(pc.Player)) {

   // player hit!

   alien.Hit(5);   // alien hit, too!

   pc.PlayerHit();

}

 

This shifts the responsibility of handling hitting the player to the PlayerComponent, where it’s most appropriate.

Now for the explosion: we’ll add a Sprite field to hold it, and initialize it in a deactivated state:

_playerExplosion = new Sprite(_explosionTexture, new Rectangle(0, 153, 65, 66), 6, true, 1);

_playerExplosion.Active = false;

_playerExplosion.Origin.X = _playerExplosion.FrameWidth / 2;

_playerExplosion.AnimationInterval = TimeSpan.FromMilliseconds(400);

 

_explosionTexture is Texture2D object, created in LoadContent as usual. To make the explosion visible and animating, we need to add appropriate code to the Update and Draw methods (like we do with any sprite). Now we just need to activate the explosion when the player is hit:

public void PlayerHit(int power = 1) {

   // player always dies

   _player.Active = false;

   // setup explosion

   _playerExplodeSound.Play();

   _playerExplosion.Position = _player.Position;

   _playerExplosion.Active = true;

}

 

If we run now, we find out the when the player is hit, the explosion animation plays repeatedly instead of just once. We need to add this capability to the Sprite class. Add two fields to indicate whether one shot animation is enabled:

public bool OneShotAnimation;

public bool DeactivateOnAnimationOver = true;

 

DeactivateOnAnimationOver indicates if the sprite should automatically deactivate when the animation sequence is done (true by default). We need to update the Sprite.Update method to use these new fields:

public virtual void Update(GameTime gameTime) {

   if(Active) {

      if(TotalFrames > 1 && (_animElapsed += gameTime.ElapsedGameTime) > AnimationInterval) {

         if(++_currentFrame == TotalFrames) {

            _currentFrame = 0;

            if(OneShotAnimation) {

               _currentFrame = TotalFrames - 1;

               if(DeactivateOnAnimationOver)

                  Active = false;

            }

         }

         _animElapsed -= AnimationInterval;

      }

      Position += Velocity;

   }

}

 

Now let’s initialize the explosion to use one shot animation, and voila! We have explosions. The downloadable source also includes explosion sound for the aliens (and some minor bug fixes).

Although I promised displaying stats in this part, I’ll save that for the next part.

Comments List

# how long from start to finish does it take to make money making video games if you started from scratch? | money making blog

Pingback from  how long from start to finish does it take to make money making video games if you started from scratch? | money making blog

# re: XNA 2D Game Tutorial (Part 11)

Published at Sunday, November 21, 2010 10:02 PM by דני  

בעיה בקול

למה במקרה שהורגים 2 חייזרים בטווח זמן קצר, לא שומעים את הפיצוץ של החייזר השני אלא רק את של הראשון ?

הרי עפ"י מה שלימדת בפרקים הקודמים הצליל היה אמור להישמע בכל מקרה

# re: XNA 2D Game Tutorial (Part 11)

Published at Sunday, November 21, 2010 10:52 PM by pavely  

זה אכן קורה מידי פעם. אני עדיין לא בטוח בסיבה. ייתכן שהצליל הקודם שהיה שם כבר היה בנגינה וצריך לקרוא ל-Stop ורק אח"כ ל-Play. אמשיך לחקור

# MVP published 11 part XNA 2d tutorial « Ruari's Chaos

Published at Thursday, November 25, 2010 10:29 AM by MVP published 11 part XNA 2d tutorial « Ruari's Chaos  

Pingback from  MVP published 11 part XNA 2d tutorial « Ruari's Chaos

# XNA 2D Game Tutorial (Part 13)

Published at Sunday, December 19, 2010 6:49 PM by Pavel's Blog  

Previous posts in this series: Part 1 : Getting started Part 2 : Drawing something Part 3 : Input handling

# XNA 2D Game Tutorial (Part 14–Last)

Published at Friday, December 31, 2010 6:54 PM by Pavel's Blog  

Previous posts in this series: Part 1 : Getting started Part 2 : Drawing something Part 3 : Input handling

Leave a Comment

(required) 
(
required
)
 
(optional)
(required) 

Enter the numbers above: