2011-09-24, 03:32 PM
Okay, I've been trying out the Microsoft VB game programming tutorial. I got everything working, up until I tried adding explosions. I did as was instructed in the tutorial, then ran the program- and the enemies just failed to show up. Previously I was able to get the projectiles to hit them and make them disappear, but adding explosions has spontaneously made them vanish. What did I do wrong?
Game1.cs
Player.cs
Animation.cs
ParallaxingBackgrounds.cs
Enemy.cs
Projectile.cs
There were no build errors. And it doesn't say that any of the code is unused like it tends to say when that happens. I don't understand what I did wrong.
By the way, do you guys have any good debuggers that you'd recommend?
Game1.cs
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Input.Touch;
namespace Shooter
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
// Represents the player
Player player;
// Keyboard states used to determine key presses
KeyboardState currentKeyboardState;
KeyboardState previousKeyboardState;
// Gamepad states used to determine button presses
GamePadState currentGamePadState;
GamePadState previousGamePadState;
// A movement speed for the player
float playerMoveSpeed;
// Image used to display the static background
Texture2D mainBackground;
// Parallaxing Layers
ParallaxingBackground bgLayer1;
ParallaxingBackground bgLayer2;
// Enemies
Texture2D enemyTexture;
List<Enemy> enemies;
// The rate at which the enemies appear
TimeSpan enemySpawnTime;
TimeSpan previousSpawnTime;
// A random number generator
Random random;
Texture2D projectileTexture;
List<Projectile> projectiles;
// The rate of fire of the player laser
TimeSpan fireTime;
TimeSpan previousFireTime;
Texture2D explosionTexture;
List<Animation> explosions;
//DIVIDER, HERE BEGINS THE METHODS```````````````````````````````````````````````````````````````````````````````````````````````````````
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
bgLayer1 = new ParallaxingBackground();
bgLayer2 = new ParallaxingBackground();
// Initialize the player class
player = new Player();
// Set a constant player move speed
playerMoveSpeed = 8.0f;
//Enable the FreeDrag gesture.
TouchPanel.EnabledGestures = GestureType.FreeDrag;
// Initialize the enemies list
enemies = new List<Enemy>();
// Set the time keepers to zero
previousSpawnTime = TimeSpan.Zero;
// Used to determine how fast enemy respawns
enemySpawnTime = TimeSpan.FromSeconds(1.0f);
// Initialize our random number generator
random = new Random();
projectiles = new List<Projectile>();
// Set the laser to fire every quarter second
fireTime = TimeSpan.FromSeconds(.15f);
explosions = new List<Animation>();
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// Load the player resources
Animation playerAnimation = new Animation();
Texture2D playerTexture = Content.Load<Texture2D>("shipAnimation");
playerAnimation.Initialize(playerTexture, Vector2.Zero, 115, 69, 8, 30, Color.White, 1f, true);
Vector2 playerPosition = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y
+ GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
player.Initialize(playerAnimation, playerPosition);
// Load the parallaxing background
bgLayer1.Initialize(Content, "bgLayer1", GraphicsDevice.Viewport.Width, -1);
bgLayer2.Initialize(Content, "bgLayer2", GraphicsDevice.Viewport.Width, -2);
enemyTexture = Content.Load<Texture2D>("mineAnimation");
projectileTexture = Content.Load<Texture2D>("laser");
explosionTexture = Content.Load<Texture2D>("explosion");
mainBackground = Content.Load<Texture2D>("mainbackground");
}
private void AddEnemy()
{
// Create the animation object
Animation enemyAnimation = new Animation();
// Initialize the animation with the correct animation information
enemyAnimation.Initialize(enemyTexture, Vector2.Zero, 47, 61, 8, 30, Color.White, 1f, true);
// Randomly generate the position of the enemy
Vector2 position = new Vector2(GraphicsDevice.Viewport.Width + enemyTexture.Width / 2, random.Next(100, GraphicsDevice.Viewport.Height - 100));
// Create an enemy
Enemy enemy = new Enemy();
// Initialize the enemy
enemy.Initialize(enemyAnimation, position);
// Add the enemy to the active enemies list
enemies.Add(enemy);
}
/// <summary>
/// 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)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
if (currentKeyboardState.IsKeyDown(Keys.Q))
this.Exit();
// Save the previous state of the keyboard and game pad so we can determine single key/button presses
previousGamePadState = currentGamePadState;
previousKeyboardState = currentKeyboardState;
// Read the current state of the keyboard and gamepad and store it
currentKeyboardState = Keyboard.GetState();
currentGamePadState = GamePad.GetState(PlayerIndex.One);
//Update the player
UpdatePlayer(gameTime);
// Update the parallaxing background
bgLayer1.Update();
bgLayer2.Update();
// Update the enemies
UpdateEnemies(gameTime);
// Update the collision
UpdateCollision();
// Update the projectiles
UpdateProjectiles();
// Update the explosions
UpdateExplosions(gameTime);
base.Update(gameTime);
}
private void AddProjectile(Vector2 position)
{
Projectile projectile = new Projectile();
projectile.Initialize(GraphicsDevice.Viewport, projectileTexture, position);
projectiles.Add(projectile);
}
private void UpdateCollision()
{
// Use the Rectangle's built-in intersect function to
// determine if two objects are overlapping
Rectangle rectangle1;
Rectangle rectangle2;
// Only create the rectangle once for the player
rectangle1 = new Rectangle((int)player.Position.X,
(int)player.Position.Y,
player.Width,
player.Height);
// Do the collision between the player and the enemies
for (int i = 0; i < enemies.Count; i++)
{
rectangle2 = new Rectangle((int)enemies[i].Position.X,
(int)enemies[i].Position.Y,
enemies[i].Width,
enemies[i].Height);
// Determine if the two objects collided with each
// other
if (rectangle1.Intersects(rectangle2))
{
// Subtract the health from the player based on
// the enemy damage
player.Health -= enemies[i].Damage;
// Since the enemy collided with the player
// destroy it
enemies[i].Health = 0;
// If the player health is less than zero we died
if (player.Health <= 0)
player.Active = false;
}
}
// Projectile vs Enemy Collision
for (int i = 0; i < projectiles.Count; i++)
{
for (int j = 0; j < enemies.Count; j++)
{
// Create the rectangles we need to determine if we collided with each other
rectangle1 = new Rectangle((int)projectiles[i].Position.X -
projectiles[i].Width / 2, (int)projectiles[i].Position.Y -
projectiles[i].Height / 2, projectiles[i].Width, projectiles[i].Height);
rectangle2 = new Rectangle((int)enemies[j].Position.X - enemies[j].Width / 2,
(int)enemies[j].Position.Y - enemies[j].Height / 2,
enemies[j].Width, enemies[j].Height);
// Determine if the two objects collided with each other
if (rectangle1.Intersects(rectangle2))
{
enemies[j].Health -= projectiles[i].Damage;
projectiles[i].Active = false;
}
}
}
}
private void AddExplosion(Vector2 position)
{
Animation explosion = new Animation();
explosion.Initialize(explosionTexture, position, 134, 134, 12, 45, Color.White, 1f, false);
explosions.Add(explosion);
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
private void UpdateExplosions(GameTime gameTime)
{
for (int i = explosions.Count - 1; i >= 0; i--)
{
explosions[i].Update(gameTime);
if (explosions[i].Active == false)
{
explosions.RemoveAt(i);
}
}
}
private void UpdatePlayer(GameTime gameTime)
{
player.Update(gameTime);
// Windows Phone Controls
while (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
if (gesture.GestureType == GestureType.FreeDrag)
{
player.Position += gesture.Delta;
}
}
// Get Thumbstick Controls
player.Position.X += currentGamePadState.ThumbSticks.Left.X * playerMoveSpeed;
player.Position.Y -= currentGamePadState.ThumbSticks.Left.Y * playerMoveSpeed;
// Use the Keyboard / Dpad
if (currentKeyboardState.IsKeyDown(Keys.Left) ||
currentGamePadState.DPad.Left == ButtonState.Pressed)
{
player.Position.X -= playerMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Right) ||
currentGamePadState.DPad.Right == ButtonState.Pressed)
{
player.Position.X += playerMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Up) ||
currentGamePadState.DPad.Up == ButtonState.Pressed)
{
player.Position.Y -= playerMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Down) ||
currentGamePadState.DPad.Down == ButtonState.Pressed)
{
player.Position.Y += playerMoveSpeed;
}
// Make sure that the player does not go out of bounds
player.Position.X = MathHelper.Clamp(player.Position.X, 0, GraphicsDevice.Viewport.Width - player.Width);
player.Position.Y = MathHelper.Clamp(player.Position.Y, 0, GraphicsDevice.Viewport.Height - player.Height);
// Fire only every interval we set as the fireTime
if (gameTime.TotalGameTime - previousFireTime > fireTime)
{
// Reset our current time
previousFireTime = gameTime.TotalGameTime;
// Add the projectile, but add it to the front and center of the player
AddProjectile(player.Position + new Vector2(player.Width / 2, 0));
}
}
private void UpdateProjectiles()
{
// Update the Projectiles
for (int i = projectiles.Count - 1; i >= 0; i--)
{
projectiles[i].Update();
if (projectiles[i].Active == false)
{
projectiles.RemoveAt(i);
}
}
}
private void UpdateEnemies(GameTime gameTime)
{
// Spawn a new enemy enemy every 1.5 seconds
if (gameTime.TotalGameTime - previousSpawnTime > enemySpawnTime)
{
previousSpawnTime = gameTime.TotalGameTime;
// Add an Enemy
AddEnemy();
}
// Update the Enemies
for (int i = enemies.Count - 1; i >= 0; i--)
{
enemies[i].Update(gameTime);
if (enemies[i].Active == false)
// If not active and health <= 0
if (enemies[i].Health <= 0)
{
// Add an explosion
AddExplosion(enemies[i].Position);
}
{
enemies.RemoveAt(i);
}
}
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// Start drawing
spriteBatch.Begin();
spriteBatch.Draw(mainBackground, Vector2.Zero, Color.White);
// Draw the moving background
bgLayer1.Draw(spriteBatch);
bgLayer2.Draw(spriteBatch);
// Draw the Enemies
for (int i = 0; i < enemies.Count; i++)
{
enemies[i].Draw(spriteBatch);
}
// Draw the Projectiles
for (int i = 0; i < projectiles.Count; i++)
{
projectiles[i].Draw(spriteBatch);
}
// Draw the Player
player.Draw(spriteBatch);
// Draw the explosions
for (int i = 0; i < explosions.Count; i++)
{
explosions[i].Draw(spriteBatch);
}
// Stop drawing
spriteBatch.End();
base.Draw(gameTime);
}
}
}Code:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Shooter
{
class Player
{// Animation representing the player
public Animation PlayerAnimation;
// Position of the Player relative to the upper left side of the screen
public Vector2 Position;
// State of the player
public bool Active;
// Amount of hit points that player has
public int Health;
// Get the width of the player ship
public int Width
{
get { return PlayerAnimation.FrameWidth; }
}
// Get the height of the player ship
public int Height
{
get { return PlayerAnimation.FrameHeight; }
}
// Initialize the player
public void Initialize(Animation animation, Vector2 position)
{
PlayerAnimation = animation;
// Set the starting position of the player around the middle of the screen and to the back
Position = position;
// Set the player to be active
Active = true;
// Set the player health
Health = 100;
}
// Update the player animation
public void Update(GameTime gameTime)
{
PlayerAnimation.Position = Position;
PlayerAnimation.Update(gameTime);
}
// Draw the player
public void Draw(SpriteBatch spriteBatch)
{
PlayerAnimation.Draw(spriteBatch);
}
}
}Animation.cs
Code:
// Animation.cs
//Using declarations
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Shooter
{
class Animation
{// The image representing the collection of images used for animation
Texture2D spriteStrip;
// The scale used to display the sprite strip
float scale;
// The time since we last updated the frame
int elapsedTime;
// The time we display a frame until the next one
int frameTime;
// The number of frames that the animation contains
int frameCount;
// The index of the current frame we are displaying
int currentFrame;
// The color of the frame we will be displaying
Color color;
// The area of the image strip we want to display
Rectangle sourceRect = new Rectangle();
// The area where we want to display the image strip in the game
Rectangle destinationRect = new Rectangle();
// Width of a given frame
public int FrameWidth;
// Height of a given frame
public int FrameHeight;
// The state of the Animation
public bool Active;
// Determines if the animation will keep playing or deactivate after one run
public bool Looping;
// Width of a given frame
public Vector2 Position;
public void Initialize(Texture2D texture, Vector2 position,
int frameWidth, int frameHeight, int frameCount,
int frametime, Color color, float scale, bool looping)
{
// Keep a local copy of the values passed in
this.color = color;
this.FrameWidth = frameWidth;
this.FrameHeight = frameHeight;
this.frameCount = frameCount;
this.frameTime = frametime;
this.scale = scale;
Looping = looping;
Position = position;
spriteStrip = texture;
// Set the time to zero
elapsedTime = 0;
currentFrame = 0;
// Set the Animation to active by default
Active = true;
}
public void Update(GameTime gameTime)
{
// Do not update the game if we are not active
if (Active == false)
return;
// Update the elapsed time
elapsedTime += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
// If the elapsed time is larger than the frame time
// we need to switch frames
if (elapsedTime > frameTime)
{
// Move to the next frame
currentFrame++;
// If the currentFrame is equal to frameCount reset currentFrame to zero
if (currentFrame == frameCount)
{
currentFrame = 0;
// If we are not looping deactivate the animation
if (Looping == false)
Active = false;
}
// Reset the elapsed time to zero
elapsedTime = 0;
}
// Grab the correct frame in the image strip by multiplying the currentFrame index by the frame width
sourceRect = new Rectangle(currentFrame * FrameWidth, 0, FrameWidth, FrameHeight);
// Grab the correct frame in the image strip by multiplying the currentFrame index by the frame width
destinationRect = new Rectangle((int)Position.X - (int)(FrameWidth * scale) / 2,
(int)Position.Y - (int)(FrameHeight * scale) / 2,
(int)(FrameWidth * scale),
(int)(FrameHeight * scale));
}
// Draw the Animation Strip
public void Draw(SpriteBatch spriteBatch)
{
// Only draw the animation when we are active
if (Active)
{
spriteBatch.Draw(spriteStrip, destinationRect, sourceRect, color);
}
}
}
}ParallaxingBackgrounds.cs
Code:
// ParallaxingBackground.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Shooter
{
class ParallaxingBackground
{// The image representing the parallaxing background
Texture2D texture;
// An array of positions of the parallaxing background
Vector2[] positions;
// The speed which the background is moving
int speed;
public void Initialize(ContentManager content, String texturePath, int screenWidth, int speed)
{
// Load the background texture we will be using
texture = content.Load<Texture2D>(texturePath);
// Set the speed of the background
this.speed = speed;
// If we divide the screen with the texture width then we can determine the number of tiles need.
// We add 1 to it so that we won't have a gap in the tiling
positions = new Vector2[screenWidth / texture.Width + 1];
// Set the initial positions of the parallaxing background
for (int i = 0; i < positions.Length; i++)
{
// We need the tiles to be side by side to create a tiling effect
positions[i] = new Vector2(i * texture.Width, 0);
}
}
public void Update()
{
// Update the positions of the background
for (int i = 0; i < positions.Length; i++)
{
// Update the position of the screen by adding the speed
positions[i].X += speed;
// If the speed has the background moving to the left
if (speed <= 0)
{
// Check the texture is out of view then put that texture at the end of the screen
if (positions[i].X <= -texture.Width)
{
positions[i].X = texture.Width * (positions.Length - 1);
}
}
// If the speed has the background moving to the right
else
{
// Check if the texture is out of view then position it to the start of the screen
if (positions[i].X >= texture.Width * (positions.Length - 1))
{
positions[i].X = -texture.Width;
}
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
for (int i = 0; i < positions.Length; i++)
{
spriteBatch.Draw(texture, positions[i], Color.White);
}
}
}
}Enemy.cs
Code:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Shooter
{
class Enemy
{
// Animation representing the enemy
public Animation EnemyAnimation;
// The position of the enemy ship relative to the top left corner of thescreen
public Vector2 Position;
// The state of the Enemy Ship
public bool Active;
// The hit points of the enemy, if this goes to zero the enemy dies
public int Health;
// The amount of damage the enemy inflicts on the player ship
public int Damage;
// The amount of score the enemy will give to the player
public int Value;
// Get the width of the enemy ship
public int Width
{
get { return EnemyAnimation.FrameWidth; }
}
// Get the height of the enemy ship
public int Height
{
get { return EnemyAnimation.FrameHeight; }
}
// The speed at which the enemy moves
float enemyMoveSpeed;
public void Initialize(Animation animation, Vector2 position)
{
// Load the enemy ship texture
EnemyAnimation = animation;
// Set the position of the enemy
Position = position;
// We initialize the enemy to be active so it will be update in the game
Active = true;
// Set the health of the enemy
Health = 10;
// Set the amount of damage the enemy can do
Damage = 10;
// Set how fast the enemy moves
enemyMoveSpeed = 6f;
// Set the score value of the enemy
Value = 100;
}
public void Update(GameTime gameTime)
{
// The enemy always moves to the left so decrement it's xposition
Position.X -= enemyMoveSpeed;
// Update the position of the Animation
EnemyAnimation.Position = Position;
// Update Animation
EnemyAnimation.Update(gameTime);
// If the enemy is past the screen or its health reaches 0 then deactivateit
if (Position.X < -Width || Health <= 0)
{
// By setting the Active flag to false, the game will remove this objet fromthe
// active game list
Active = false;
}
}
public void Draw(SpriteBatch spriteBatch)
{
// Draw the animation
EnemyAnimation.Draw(spriteBatch);
}
}
}Projectile.cs
Code:
// Projectile.cs
//Using declarations
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Shooter
{
class Projectile
{
// Image representing the Projectile
public Texture2D Texture;
// Position of the Projectile relative to the upper left side of the screen
public Vector2 Position;
// State of the Projectile
public bool Active;
// The amount of damage the projectile can inflict to an enemy
public int Damage;
// Represents the viewable boundary of the game
Viewport viewport;
// Get the width of the projectile ship
public int Width
{
get { return Texture.Width; }
}
// Get the height of the projectile ship
public int Height
{
get { return Texture.Height; }
}
// Determines how fast the projectile moves
float projectileMoveSpeed;
public void Initialize(Viewport viewport, Texture2D texture, Vector2 position)
{
Texture = texture;
Position = position;
this.viewport = viewport;
Active = true;
Damage = 2;
projectileMoveSpeed = 20f;
}
public void Update()
{
// Projectiles always move to the right
Position.X += projectileMoveSpeed;
// Deactivate the bullet if it goes out of screen
if (Position.X + Texture.Width / 2 > viewport.Width)
Active = false;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, Position, null, Color.White, 0f,
new Vector2(Width / 2, Height / 2), 1f, SpriteEffects.None, 0f);
}
}
}There were no build errors. And it doesn't say that any of the code is unused like it tends to say when that happens. I don't understand what I did wrong.
By the way, do you guys have any good debuggers that you'd recommend?

