Microsoft XNA Unleashed - Errata
This errata page has been a long time coming. I finally took all of the posts from the Amazon forum for the book and compiled them into a single source. I'll update this if any additional errors are found in the book. If something is unclear with this errata page or anything else in the book, please post the question in the book's amazon.com forum.
Any Chapters not listed here do not have any known errors. The complete list of chapters can be found on the main Microsoft XNA Unleashed book information page.
Chapter 2
Page 27
Creating a Test Demo for the Xbox 360
The first segment of code on the page says to use the texture variable when it really should be spriteTexture. Change
spriteBatch.Draw(texture, new Vector2(titleSafeArea.X, titleSafeArea.Y), Color.White);
to
spriteBatch.Draw(spriteTexture, new Vector2(titleSafeArea.X, titleSafeArea.Y), Color.White);
Chapter 3
Page 47
Optimization Suggestions
The RotateWithMod method uses 30 in the cameraYaw calculation instead of 360.
Chapter 5
Page 100
Creating a Stationary Camera
The text preceeding the first code fragment suggests it should be added to the demo's Update method. This is incorrect. The code should be added to the demo's Draw method.
The actual code should also be modified. It seems there was a formatting issue when I pasted the code to the text and I became a little too happy with the delete key. The world variable should be changed from
world = Matrix.CreateRotationY(Matrix.CreateTranslation(new Vector3(3.0f, 0, 10.0f));
to
world = Matrix.CreateRotationY(MathHelper.ToRadians(180f)) *
Matrix.CreateTranslation(new Vector3(3.0f, 0, 10.0f));
Page 107
Creating a Split Screen
The second player's input controls do not function as they should. The axis are inverted, which may be a nice option but to have it react "normally" the camera2.Orientation property should get the same value as camera.Orientation. So change
camera2.Orientation = new Vector3(0.0f, 0.0f, 1.0f);
to
camera2.Orientation = camera.Orientation;
Chapter 8
Page 165
Using the Skybox
It was my intention to have all of the code in the book so you didn't have to refer to the code on the CD. However, I forgot to add a couple of code segments. First, add this line in LoadContent method.
skybox = Content.Load<Skybox>(@"Content\Skyboxes\skybox");
Second, you actually need to draw the skybox by adding the following two lines of code at the bottom of the Draw method, but right before the base.Draw call:
world = Matrix.CreateScale(5000.0f);
skybox.Draw(camera.View, camera.Projection, world);
Chapter 9
Page 172
Sprite Batches
The text at the top of the page as well as Figure 9.1 suggests that for a resolution of 1024 by 768 that X would run from 0 to 1024 and Y would run from 0 to 768. There is an "off by one" error there. X would really run from 0 to 1023 and Y would run from 0 to 767.
Page 177
Splash or Loading Screen Demo
Bottom of the page, the final line of code uses "Contents" when the directory is actually "Content". Change
splashScreen = content.Load<Texture2D>(@"Contents\Textures\splashScreen");
to
splashScreen = content.Load<Texture2D>(@"Content\Textures\splashScreen");
Page 184
Progress Bar Demo
The list of private member fields are missing one. It seems when I copied the list from the code, I neglected to grab the very first one. At the top of the list (or where ever you want) add the following variable:
private Texture2D progressBar;
Chapter 10
Pages 194 - 195
Cel Animation
There are 3 overloaded Draw methods in Listing 10.1 - CelAnimationManager.cs. The final overloaded method never uses the int frame parameter passed to it. Since this the case, the three Draw dethods can be simplified to the following two:
public void Draw(GameTime gameTime, string animationKey, SpriteBatch batch, Vector2 position)
{
Draw(gameTime, animationKey, batch, position, Color.White);
}
public void Draw(GameTime gameTime, string animationKey, SpriteBatch batch, Vector2 position, Color color)
{
if (!animations.ContainsKey(animationKey))
return;
CelAnimation ca = animations[animationKey];
//first get our x increase amount (add our offset-1 to our current frame)
int xincrease = (ca.Frame + ca.CelRange.FirstCelX - 1);
//now we need to wrap the value so it will loop to the next row
int xwrapped = xincrease % ca.CelsPerRow;
//finally we need to take the product of our wrapped value and a cel's width
int x = xwrapped * ca.CelWidth;
//to determine how much we should increase y, we need to look at how much we
//increased x and do an integer divide
int yincrease = xincrease / ca.CelsPerRow;
//now we can take this increase and add it to our Y offset-1 and multiply the sum by
//our cel height
int y = (yincrease + ca.CelRange.FirstCelY - 1) * ca.CelHeight;
Rectangle cel = new Rectangle(x, y, ca.CelWidth, ca.CelHeight);
batch.Draw(textures[ca.TextureName], position, cel, color);
}
Page 196
Cel Animation
The text in the book is incorrect as the code is a normal constructor and not a static Create method. Remove the Create method and replace it with the following:
public CelAnimation(string textureName, CelRange celRange, int framesPerSecond)
{
this.textureName = textureName;
this.celRange = celRange;
this.framesPerSecond = framesPerSecond;
this.timePerFrame = 1.0f / (float)framesPerSecond;
this.Frame = 0;
}
Page 201
Cel Animation
After updating the Update method and explaining it, I suggest that we run the code to see the animations. Well, it would be beneficial if we actually added the appropriate draw calls. The following code needs to be added to the Draw method:
spriteBatch.Begin();
cam.Draw(gameTime, "enemy1", spriteBatch, new Vector2(50, 50));
cam.Draw(gameTime, "enemy2", spriteBatch, new Vector2(150, 75));
cam.Draw(gameTime, "enemy3", spriteBatch, new Vector2(70, 130));
cam.Draw(gameTime, "complex1", spriteBatch, new Vector2(400, 50));
cam.Draw(gameTime, "complex2", spriteBatch, new Vector2(400, 150));
cam.Draw(gameTime, "complex3", spriteBatch, new Vector2(400, 250));
cam.Draw(gameTime, "complex4", spriteBatch, new Vector2(400, 350));
spriteBatch.End();
Chapter 11
Page 221
Creating Parallax Scrolling
The ScrollingBackgroundManager class should implement the IScrollingBackgroundManager. The code has this, but the listing neglects to include it. A game service must inherit from a unique interface. Change the class declaration to be:
public class ScrollingBackgroundManager : Microsoft.Xna.Framework.GameComponent, IScrollingBackgroundManager
Page 222
Creating Parallax Scrolling
The AddBackground method in the book did not modify the ScrollRate property. The entire method can be replaced with the following:
public void AddBackground(string backgroundKey, string textureName,
Vector2 position, Rectangle? sourceRect, float scrollRateRatio,
Color color)
{
ScrollingBackground background = new ScrollingBackground(
textureName, position, sourceRect, scrollRateRatio, color);
background.ScrollRate = scrollRate * scrollRateRatio;
if (!textures.ContainsKey(textureName))
{
textures.Add(textureName, cGame.Content.Load<Texture2D>(
contentPath + textureName));
}
if (backgrounds.ContainsKey(backgroundKey))
backgrounds[backgroundKey] = background;
else
backgrounds.Add(backgroundKey, background);
}
Page 223
Creating Parallax Scrolling
There is a typo in the code in the book in Listting 11.1 - ScrollingBackgroundManager.cs. The ScrollRate property has a void return. It should be a float. Change the ScrollRate property to the following:
public float ScrollRate
{
get { return (scrollRate); }
}
Page 225
Creating Parallax Scrolling
In the constructor of the Background class, the last line of code should be removed. It has no use as we are not utilizing the specific game methods inside of this class. Remove this line:
simpleGame = (SimpleGame)game;
Chapter 13
Page 276
Vertex Displacement
There is an additional change not mentioned in the book that needs to take place before the code will functoin correctly. The code on the CD included this modification, but the text did not point it out. In the effect file, change
output.Position = mul(input.Position, WorldViewProjection);
to
output.Position = mul(Pos, WorldViewProjection);
Without changing input.Position to Pos none of the changes we made to the position to create the vertex displacement would matter.