Making your own WP7 Angry Birds – Part 8 – Introducing the target
May 28, 2011 6 Comments
So far we can shoot our pig at a stack of blocks. It is now time to introduce a proper target. What better target than a bird?
.
1. Creating a target
Save the above image as bird.png and add it to the spritesheet xml asset. Before we add it to the PrefabBodyFactory we need to add a new property to PrefabUserData:
public bool IsTarget { get; set; }
Obviously, this property is used to set apart our target bodies from regular bodies, such as our plain old GrayBox.
Now we can add the following to the PrefabBodyFactory:
Library.Add(PrefabType.Bird, (world, position) => { Body body = CreateCircle(world, position, "bird", 0.2f, 3); ((PrefabUserData) body.UserData).IsTarget = true; return body; } );
As you can see, nothing special going on, except we also mark this body as a target, using our new IsTarget property.
2. Keeping scores
The goal of the game will of course be to destroy all of the targets.
To keep track of our progress we will introduce a Scoreboard class.
Every time a body is destroyed we will inform the scoreboard. If it figures out all targets have been destroyed it will set an IsSuccess property to True.
Having said that, here’s the implementation:
public class Scoreboard { private int _numberOfTargets; private int _numberTargetsDestroyed; private bool _isSuccess; public bool IsSuccess { get { return _isSuccess; } } public static readonly Scoreboard Current = new Scoreboard(); private Scoreboard() { } public void Initialize(List<Body> bodies) { _numberTargetsDestroyed = 0; _numberOfTargets = 0; foreach (var body in bodies) { if (((PrefabUserData)body.UserData).IsTarget) { _numberOfTargets++; } } } public void ProcessDestroyedBody(Body body) { if (((PrefabUserData)body.UserData).IsTarget) { _numberTargetsDestroyed++; if (_numberTargetsDestroyed == _numberOfTargets) _isSuccess = true; } } }
To wire up the scoreboard to our game, we need to call Initialize, ProcessDestroyedBody and IsSuccess.
Initialize
Here’s what our updated LoadContent looks like. We add the bird to our level. When our _bodies list is complete we pass it to the Scoreboard‘s Initialize method.
... Body box1 = PrefabBodyFactory.CreateBody(PrefabType.GrayBox, _world, new Vector2(9.0f, 3.999274f)); _bodies.Add(box1); Body box2 = PrefabBodyFactory.CreateBody(PrefabType.GrayBox, _world, new Vector2(9.0f, 3.612630f)); _bodies.Add(box2); Body box3 = PrefabBodyFactory.CreateBody(PrefabType.GrayBox, _world, new Vector2(9.0f, 3.222778f)); _bodies.Add(box3); Body bird = PrefabBodyFactory.CreateBody(PrefabType.Bird, _world, new Vector2(9.0f, 3.0f)); _bodies.Add(bird); Body pig = PrefabBodyFactory.CreateBody(PrefabType.Pig, _world, new Vector2(1.5f, 3.9f)); _bodies.Add(pig); _projectile = new Projectile(pig); Scoreboard.Current.Initialize(_bodies); ...
As you can see, the pile of boxes is moved a little further away than before. You might want to adjust your Projectile‘s ImpulseModifier to give it enough force to reach this new distance.
ProcessDestroyedBody
In PrefabUserData we have a method Destroy. This is the place where we will inform our Scoreboard to keep count:
public void Destroy(Body body) { Status = BodyStatus.Destroyed; ExplosionAnimation.Activate(body); Scoreboard.Current.ProcessDestroyedBody(body); }
IsSuccess
In our Game‘s Draw method we will add the following code at the end of the method.
If the Scoreboard marked the game as won (IsSuccess), we draw a ‘You won!’ texture in the middle of the screen.
Notice we use a new Spritebatch begin/end block. The original Spritebatch block we used takes the camera’s position into account.
As we simply want to draw our texture in the middle of the screen, we don’t want to have the Camera‘s TransformationMatrix to interfere.
Make sure to make a sprite called ‘youwon’ and add it to the spritesheet to make the code below work correctly.
... if (Scoreboard.Current.IsSuccess) { spriteBatch.Begin(); spriteBatch.Draw( _sheet.Texture, new Vector2(302, 200), _sheet.SourceRectangle("youwon"), Color.White ); spriteBatch.End(); } base.Draw(gameTime); }
And here’s today’s result:
Pingback: Anonymous
Will there be more to this serie? I’m really curious as to how you manage the multiple levels, tombstoning, etc.
nice tutorial thanks a lot
i try to use game state managment from app hub
i have move the game in there… all working without any error but the input touch does not working
any idea?
Here is the complete tutorial full working thanks goes to Jo De Greef
http://goo.gl/3KJvd
i try to add the game state manager (MENU) from app hub
http://goo.gl/Kzw2y
the game work with menu but i have problem with touch i can’t move nothing any help?
ps. if you have errors you must add refernce as the step 2
hey Jo!
Just wondering if you are still continuing on with this it hsa been extremely helpful
Jake
I currently don’t have the time for any new content unfortunately