Hey guys I really need some help here my spriteBatch keeps returning a NullReference Exception and I don't know what I am doing wrong!? (I am making a brickbreaker game) and whenever my bricks are created inside Game1.cs it works fine but when I move it to Wall.cs (which is where I want to display a pattern of bricks) the game just crashes and gives a NullReference exception. Heres my 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;
namespace BrickBreaker
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Paddle paddle;
private Ball ball;
private Texture2D background;
private static int screenWidth = 750;
private static int screenHeight = 600;
private int leftBorder = 20;
private int rightBorder = 28;
private int topBorder = 20;
private readonly int normalBrickResist = 2;
private readonly int normalBrickPoints = 10;
private Wall wall;
//DELETE this shit
private Brick brick;
/// <summary>
/// Contructor for the Game1 class.
/// </summary>
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Read only property for the screen height.
/// </summary>
public static int ScreenHeight
{
get { return screenHeight; }
}
/// <summary>
/// Read only property for the screen width.
/// </summary>
public static int ScreenWidth
{
get { return screenWidth; }
}
/// <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()
{
graphics.PreferredBackBufferHeight = screenHeight;
graphics.PreferredBackBufferWidth = screenWidth;
graphics.ApplyChanges();
paddle = new Paddle(this);
Components.Add(paddle);
wall = new Wall(this);
Components.Add(wall);
ball = new Ball(this, paddle, leftBorder, rightBorder, topBorder, brick);
Components.Add(ball);
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()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
background = Content.Load<Texture2D>("background");
}
/// <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
}
/// <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();
base.Update(gameTime);
}
/// <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);
spriteBatch.Begin();
Vector2 position = new Vector2(0, 0);
spriteBatch.Draw(background, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
public void RemoveComponent(IGameComponent obj)
{
this.Components.Remove(obj);
}
}
}
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;
namespace BrickBreaker
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class Wall : Microsoft.Xna.Framework.DrawableGameComponent
{
private Brick brick;
private Brick[,] brickLayout = new Brick[5, 8];
private Game game;
SpriteBatch spriteBatch;
private Texture2D brickImg;
public Wall(Game game)
: base(game)
{
this.game = game;
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Draw(GameTime gameTime)
{
foreach (var item in brickLayout)
{
if (item != null)
{
item.Draw(gameTime);
}
}
base.Draw(gameTime);
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
foreach (Brick item in brickLayout)
{
item.Update(gameTime);
}
base.Update(gameTime);
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
// TODO: Add your initialization code here
foreach (var item in brickLayout)
{
if (item != null)
{
item.Initialize();
}
}
base.Initialize();
}
protected override void LoadContent()
{
int x = 0;
int y = 0;
Vector2 startPosition;
for (int i = 0; i < brickLayout.GetLength(0); i++)
{
for (int j = 0; j < brickLayout.GetLength(1); j++)
{
startPosition = new Vector2(x, y);
brickLayout[i, j] = new Brick(game, 20, 1, startPosition);
x += 20;
}
y += 20;
}
base.LoadContent();
}
}
}
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;
namespace BrickBreaker
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class Brick : Microsoft.Xna.Framework.DrawableGameComponent
{
enum brickType
{
Regular1,
Regular2,
Regular3,
Regular4,
Regular5,
PowerUp,
Unbreakable
}
private Texture2D brick;
private SpriteBatch spriteBatch;
private Game game;
private int brickValue;
private Vector2 startPosition, position;
private Rectangle collisionBox;
private int brickWidth;
private bool isBroken = false;
private int resistance;
public Brick(Game game, int brickValue, int resistance, Vector2 startPosition)
: base(game)
{
this.brickValue = brickValue;
this.game = game;
this.resistance = resistance;
this.startPosition = startPosition;
}
public Boolean IsBroken
{
get
{
return this.isBroken;
}
set
{
this.isBroken = value;
}
}
/// <summary>
/// Property for the paddle collision box.
/// </summary>
public Rectangle CollisionBox
{
get { return collisionBox; }
}
/// <summary>
/// Read only property for the paddle width.
/// </summary>
public int BrickWidth
{
get { return brickWidth; }
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
base.Update(gameTime);
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Draw(GameTime gameTime)
{
if (isBroken == false)
{
spriteBatch.Begin();
spriteBatch.Draw(brick, this.position, Color.White);
spriteBatch.End();
}
base.Draw(gameTime);
}
/// <summary>
/// Comment
/// </summary>
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
brick = game.Content.Load<Texture2D>("brick");
collisionBox = new Rectangle(0, 0, brick.Width, brick.Height);
position = startPosition;
collisionBox.X = (int)position.X;
collisionBox.Y = (int)position.Y;
base.LoadContent();
}
public void TakeHit()
{
resistance--;
if (resistance == 0)
IsBroken = true;
}
}
}
Edit: Fixed the old problem by adding this in wall.cs
for (int i = 0; i < brickLayout.GetLength(0); i++)
{
for (int j = 0; j < brickLayout.GetLength(1); j++)
{
startPosition = new Vector2(x, y);
brickLayout[i, j] = new Brick(game, 20, 1, startPosition);
//Added this line:
brickLayout[i, j].Initialize();
x += 45;
}
x = 150;
y += 25;
}
BUT now the collision box isn't working at all.
Look closer at your Brick class. In your wall class you're not initializing spriteBatch, and you're not calling Begin and End
Your LoadContent method needs this:
spriteBatch = new SpriteBatch(GraphicsDevice);
And you need to be sure to call this is your Draw method:
spriteBatch.Begin();
and
spriteBatch.End();
EDIT: You're never calling LoadContent on your brick class which is why spriteBatch never gets initialized. Try:
protected override void LoadContent()
{
int x = 0;
int y = 0;
Vector2 startPosition;
for (int i = 0; i < brickLayout.GetLength(0); i++)
{
for (int j = 0; j < brickLayout.GetLength(1); j++)
{
startPosition = new Vector2(x, y);
brickLayout[i, j] = new Brick(game, 20, 1, startPosition);
// This new line...
brickLayout[i, j].LoadContent();
x += 20;
}
y += 20;
}
base.LoadContent();
}
It's giving NullReferenceException in the Brick class at the SpriteBatch.Begin() line in the Draw method.
Related
I've seen questions similar to what I'm asking, but they don't quite give me the answer I'm looking for. I want 5 instances of my sprites to show up on screen and spawn in different locations. For some reason though instead of 5 instances, each "instance" of the sprite increases the values of the one sprite that does appear on screen.
Sprite.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Lab05_2__Aaron_Benjamin_
{
class Sprite
{
Texture2D mSpriteTexture;
public Vector2 Position;
Color mSpriteColor;
public Rectangle Size;
public string AssetName;
private float mScale = 1.0f;
public float Scale
{
get { return mScale; }
set
{
mScale = value;
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
}
public void LoadContent(ContentManager theContentManager, string theAssetName)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
AssetName = theAssetName;
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
public void Update(GameTime gameTime)
{
}
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position,
new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),
Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
//theSpriteBatch.Draw(mSpriteTexture, Position);
}
}
}
Enemy.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace Lab05_2__Aaron_Benjamin_
{
class Enemy : Sprite
{
const string ENEMY_ASSETNAME = "gear";
Random Rand = new Random();
int startPos_X;
int startPos_Y;
public void LoadContent(ContentManager theContentManager)
{
Position = new Vector2(startPos_X = Rand.Next(0 , 1000), startPos_Y = Rand.Next(0, 1000)); //= Rand.Next(0, 100),Position.Y = Rand.Next(0,100));
base.LoadContent(theContentManager, ENEMY_ASSETNAME);
}
public void Update(GameTime gameTime)
{
MouseState cState = Mouse.GetState();
if (Position.X > cState.X)
{
Position.X += 1;
}
if (Position.X < cState.X)
{
Position.X -= 1;
}
if (Position.Y < cState.Y)
{
Position.Y -= 1;
}
if (Position.Y > cState.Y)
{
Position.Y += 1;
}
base.Update(gameTime);
}
}
}
Game1.cs
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Lab05_2__Aaron_Benjamin_
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Enemy> enemies = new List<Enemy>();
private void CreateEnemy()
{
Enemy gear = new Enemy();
Random rand = new Random();
//gear = new Enemy();
//gear.Position.X = rand.Next(0, 1000);
//gear.Position.Y = rand.Next(0, 1000);
Console.WriteLine(gear.Position.Y);
enemies.Add(gear);
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
/// <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()
{
// TODO: Add your initialization logic here
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);
// TODO: use this.Content to load your game content here
for (int i = 0; i < 5; i++)
{
CreateEnemy();
}
foreach (var cog in enemies)
{
cog.LoadContent(this.Content);
}
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
foreach (var cog in enemies)
{
if (cog.Position.X > Window.ClientBounds.Width - 50)
cog.Position.X = Window.ClientBounds.Width - 50;
if (cog.Position.Y > Window.ClientBounds.Height - 50)
cog.Position.Y = Window.ClientBounds.Height - 50;
if (cog.Position.X < 0)
cog.Position.X = 0;
if (cog.Position.Y < 0)
cog.Position.Y = 0;
}
foreach (var cog in enemies)
{
cog.Update(gameTime);
}
if (Keyboard.GetState().IsKeyDown(Keys.M))
{
// If 'm' is down, we create a new meteor. Note that once this is working
// this is going to make a lot of meteors. That's another issue, though.
CreateEnemy();
}
//Console.WriteLine(enemies.Count);
base.Update(gameTime);
}
/// <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.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
foreach (var cog in enemies)
{
cog.Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Shouldn't you be using gear in this part instead of this.gear ?
foreach (var gear in enemies)
{
this.gear.LoadContent(this.Content);
}
ok I got it to work. So my randoms were being assigned and then reassigned in a different section of the code so that they all stacked on top of each other. Here is the solution.
Sprite.cs
class Sprite
{
Texture2D mSpriteTexture;
public Vector2 Position;
Color mSpriteColor;
public Rectangle Size;
public string AssetName;
private float mScale = 1.0f;
public float Scale
{
get { return mScale; }
set
{
mScale = value;
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
}
public void LoadContent(ContentManager theContentManager, string theAssetName)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
AssetName = theAssetName;
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
public void Update(GameTime gameTime)
{
}
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position,
new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),
Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
//theSpriteBatch.Draw(mSpriteTexture, Position);
}
}
}
Enemy.cs
class Enemy : Sprite
{
const string ENEMY_ASSETNAME = "gear";
Random Rand = new Random();
//int startPos_X;
//int startPos_Y;
public void LoadContent(ContentManager theContentManager)
{
Position = new Vector2(Position.X ,Position.Y);
base.LoadContent(theContentManager, ENEMY_ASSETNAME);
}
public void Update(GameTime gameTime)
{
MouseState cState = Mouse.GetState();
if (Position.X > cState.X)
{
Position.X += 1;
}
if (Position.X < cState.X)
{
Position.X -= 1;
}
if (Position.Y < cState.Y)
{
Position.Y -= 1;
}
if (Position.Y > cState.Y)
{
Position.Y += 1;
}
base.Update(gameTime);
}
}
}
Game1.cs
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Enemy> enemies = new List<Enemy>();
Random rand = new Random();
private void CreateEnemy()
{
Enemy gear = new Enemy();
//gear = new Enemy();
gear.Position.X = rand.Next(0, 1000);
gear.Position.Y = rand.Next(0, 1000);
Console.WriteLine(gear.Position.Y);
enemies.Add(gear);
enemies[0].Position.X += 10;
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
/// <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()
{
// TODO: Add your initialization logic here
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);
// TODO: use this.Content to load your game content here
for (int i = 0; i < 5; i++)
{
CreateEnemy();
}
foreach (var cog in enemies)
{
cog.LoadContent(this.Content);
}
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
foreach (var cog in enemies)
{
if (cog.Position.X > Window.ClientBounds.Width - 50)
cog.Position.X = Window.ClientBounds.Width - 50;
if (cog.Position.Y > Window.ClientBounds.Height - 50)
cog.Position.Y = Window.ClientBounds.Height - 50;
if (cog.Position.X < 0)
cog.Position.X = 0;
if (cog.Position.Y < 0)
cog.Position.Y = 0;
}
foreach (var cog in enemies)
{
cog.Update(gameTime);
}
if (Keyboard.GetState().IsKeyDown(Keys.M))
{
// If 'm' is down, we create a new meteor. Note that once this is working
// this is going to make a lot of meteors. That's another issue, though.
CreateEnemy();
}
//Console.WriteLine(enemies.Count);
base.Update(gameTime);
}
/// <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.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
foreach (var cog in enemies)
{
cog.Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
I am making a tile-based game. I have my "playfield" that is 30*20 Tiles (each is 32x32 pixels). The first Tile that is drawn (at BlockPos (0,0)) is drawn correctly, but the other Tiles are drawn incorrectly. That is, the texture is "smudged". Here is the main class code:
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using Texert.Content;
using Texert.Logic;
#endregion
namespace Texert
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class MainGame : Game
{
private FrameCounter _frameCounter = new FrameCounter();
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public MainGame()
: base()
{
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()
{
// TODO: Add your initialization logic here
Vars.Textures = new List<Texture2D>();
Vars.Tiles = new List<Tile>();
for (var i = 0; i < 20; i++)
{
for (var k = 0; k < 30; k++)
{
Vars.Tiles.Add(new TileDirt(new BlockPos(k, i)));
}
}
// Set window size
graphics.IsFullScreen = false;
graphics.PreferredBackBufferHeight = Tile.TILE_SIZE*20;
graphics.PreferredBackBufferWidth = Tile.TILE_SIZE*30;
graphics.ApplyChanges();
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);
Vars.Textures.Add(Content.Load<Texture2D>("dirt"));
// TODO: use this.Content to load your game content here
}
/// <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
}
/// <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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
// Update FPS
var deltaTime = (float) gameTime.ElapsedGameTime.TotalSeconds;
_frameCounter.Update(deltaTime);
Window.Title = "Texert - " + Math.Floor(_frameCounter.AverageFramesPerSecond) + " FPS";
base.Update(gameTime);
}
/// <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);
spriteBatch.Begin();
foreach (var tile in Vars.Tiles)
{
spriteBatch.Draw(Vars.Textures[tile.textureIndex],
tile.pos.GetRealPos().GetVector2(),
new Rectangle(tile.pos.GetRealPos().X, tile.pos.GetRealPos().Y,
Tile.TILE_SIZE, Tile.TILE_SIZE),
Color.White); // draw the fucking tile
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Here is a screenshot of the game in action. I have no idea why it is drawn this way. How can I fix this?
Edit: Here's the Tile.cs file that contains Pos, BlockPos and Tile!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace Texert.Logic
{
public class Tile
{
public static int TILE_SIZE = 32;
public int textureIndex;
public string tileName;
public BlockPos pos;
public Tile()
{
textureIndex = 0;
tileName = "null";
pos = new BlockPos(0, 0);
}
public Tile(int index, string name, BlockPos pos)
{
textureIndex = index;
tileName = name;
this.pos = pos;
}
}
public class BlockPos
{
public Pos actualPos;
public int X;
public int Y;
public BlockPos(int x, int y)
{
X = x;
Y = y;
}
public Pos GetRealPos()
{
return new Pos(X*Tile.TILE_SIZE, Y*Tile.TILE_SIZE);
}
/// <summary>
/// Returns blockpos of pos, rounded down to nearest multiple of TILE_SIZE
/// </summary>
/// <param name="pos">The position to convert to BlockPos</param>
/// <returns>The BlockPos</returns>
static BlockPos GetBlockPosFromPos(Pos pos)
{
return new BlockPos(pos.X % Tile.TILE_SIZE, pos.Y % Tile.TILE_SIZE);
}
}
public class Pos
{
public int X;
public int Y;
public Pos(int x, int y)
{
X = x;
Y = y;
}
public Vector2 GetVector2()
{
return new Vector2(X, Y);
}
}
}
i am working on a game, and i want the speceship to change to another spaceship from the sprite sheet when the player presses Tab key. so its like switching between the spaceships.
i have been trying with GetSourceRectangle from the class and setting one, and updating that in game, but its not working.
here is the code fro the Spaceship class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SpaceShooterTest1
{
class Spaceship
{
public int xPos = 0;
public int yPos = 0;
private int width = 128;
private int height = 128;
private Texture2D texture;
public Rectangle currentSourceRect { get; set; } //determines which part of sprite sheet to show
public Spaceship(Texture2D tex)
{
texture = tex;
currentSourceRect = new Rectangle(0, 0, 128, 128);
}//end Spaceship
// // //
public void MoveToPosition(int x, int y)
{
xPos = x;
yPos = y;
}//end MoveToPosition
public void Update(GameTime gametime)
{
currentSourceRect = GetSourceRectangle(2, 0); // this could be getting the fiery weapons
//currentSourceRect = SetSourceRectangle(2, 0);
}
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, new Rectangle(xPos, yPos, width, height), currentSourceRect, Color.White);
}//end Draw
public Rectangle GetSourceRectangle(int row, int col)
{
Rectangle r;
//TODO: Make custom based on row and col
r = new Rectangle(0, 128, width, height);
return r;
}//end GetSourseRectangle
//public Rectangle SetSourceRectangle(int row, int col)
//{
// Rectangle r;
// //TODO: Make custom based on row and col
// r = new Rectangle(0, 128, width, height);
// return r;
//}//end GetSourseRectangle
}
}
and here is the code for the Game:
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;
namespace SpaceShooterTest1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
//Game State Enum
enum GameState { GScreen, Playing, Won, Lost };
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Random rand;
int playerScore = 0;
//Textures
Texture2D galaxyScreen;
Texture2D texShip;
GameState currentState = GameState.Playing;
//GameState currentState = GameState.GScreen; /// use after
//ship
Spaceship spaceShip;
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()
{
// TODO: Add your initialization logic here
base.Initialize();
rand = new Random();
}
/// <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);
texShip = Content.Load<Texture2D>(#"Images\ships_sm");
spaceShip = new Spaceship(texShip);
spaceShip.xPos = 0;
spaceShip.yPos = Window.ClientBounds.Height - 128;
//galaxyScreen = Content.Load<Texture2D>(#"Images\galaxy");
// TODO: use this.Content to load your game content here
}
/// <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
}
/// <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();
KeyboardState keyboardState = Keyboard.GetState();
if (Keyboard.GetState().IsKeyDown(Keys.Tab))
{
spaceShip.GetSourceRectangle(2, 0);
}
if (Keyboard.GetState().IsKeyDown(Keys.D))
{
spaceShip.xPos += 5;
}
else if (Keyboard.GetState().IsKeyDown(Keys.A))
{
spaceShip.xPos -= 5;
}
if (spaceShip.xPos < 0)
spaceShip.xPos = 0;
if (spaceShip.xPos + 128 > Window.ClientBounds.Width)
{
spaceShip.xPos = Window.ClientBounds.Width - 128;
}
/*if (currentState == GameState.GScreen && keyboardState.IsKeyDown(Keys.Space))
{
currentState = GameState.Playing;
}
spaceShip.Update(gameTime);
*/
base.Update(gameTime);
}
/// <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);
//draw ship
spriteBatch.Begin();
if (currentState == GameState.Playing)
{
spaceShip.Draw(gameTime, spriteBatch);
}
//800 wide x 400 high
else if (currentState == GameState.GScreen)
{
spriteBatch.Draw(galaxyScreen, new Rectangle(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height), Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
apparently i cant post the spritesheet because i dont have enough reputation (seriously stack?) but i hope you guys understand what i mean.
With what you gave, what I can think of is:
Have 2 Vector2 (or Rectangle, whichever object you use on your Draw method) objects on the Spaceship class, one for the coordinates of spaceship when the Tab is not pressed, another one for when the key is pressed on the tilesheet.
Then you can have a bool value on the Game class to specify which texture to use.
On the Update method, update the bool value.
On the Draw method, draw the texture according the bool value.
So basically on the Spaceship class:
Texture2D spaceship;
Vector2 spaceship1, spaceship2;
bool tabPressed;
On the Update method of the Game class:
tabPressed = Keyboard.GetState().IsKeyDown(Keys.Tab);
Now you can either pass the bool value to your Spaceship Draw method and draw accordingly, or access a property/method of the class to signal the change in the desired drawing behavior.
first of all, i am new to xna. Trying to craete blackjack game. And i have created 2 lists to add random card to the list. But i cannot understand why doesnt it add pics to the list tekstuur2
Heres code :
public class Kaart
{
public Vector2 asukoht = new Vector2(0, 0);
public List<Texture2D> tekstuur = new List<Texture2D>();
public List<Texture2D> tekstuur2 = new List<Texture2D>();
Random rand = new Random();
public void loadContent2(ContentManager manager2)
{
for (int x = 3; x < 7; x++)
tekstuur2.Add(manager2.Load<Texture2D>("Risti" + x.ToString()));
}
public void loadContent(ContentManager manager)
{
for (int j = 3; j < 7; j++)
tekstuur.Add(manager.Load<Texture2D>("Risti" + j.ToString()));
}
public void Draw(SpriteBatch sprite)
{
sprite.Draw(tekstuur[rand.Next(tekstuur.Count)], asukoht, Color.White);
sprite.Draw(tekstuur2[rand.Next(tekstuur2.Count)], asukoht, Color.White);
// an error occurs (ArgumentOutofRangeException) , tekstuur2.count = 0 at that point, but at the tekstuur.Count it is 4.
}
}
}
Heres another class where these methods are called :
namespace WindowsGame1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Vector2 koht = new Vector2(0,0);
Kaart yks;
Kaart kaks;
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()
{
// TODO: Add your initialization logic here
yks = new Kaart();
kaks = new Kaart();
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);
//kaardi laadimine
yks.loadContent(this.Content);
kaks.loadContent2(this.Content);
// yhe kaarti asukoht
yks.asukoht.X = 100;
yks.asukoht.Y = 300;
// teise kaardi asukoht
kaks.asukoht.X = 200;
kaks.asukoht.Y = 400;
// TODO: use this.Content to load your game content here
}
/// <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
}
/// <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();
base.Update(gameTime);
}
/// <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)
{
// kaartide joonistamine
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
yks.Draw(this.spriteBatch);
kaks.Draw(this.spriteBatch);
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
ok the problem is you should call for every instance of Kaart (in your case yks and kaks) loadContent AND loadContent2
this in your method LoadContent:
//kaardi laadimine
yks.loadContent(this.Content);
kaks.loadContent2(this.Content);
become:
//kaardi laadimine
yks.loadContent(this.Content);
yks.loadContent2(this.Content);
kaks.loadContent2(this.Content);
kaks.loadContent(this.Content);
note that since the texture are the same there's no need to use two different list for containing them, you can do this in your Kaart Draw method:
sprite.Draw(tekstuur[rand.Next(tekstuur.Count)], asukoht, Color.White);
sprite.Draw(tekstuur[rand.Next(tekstuur.Count)], asukoht, Color.White);
this way you have to only call LoadContent.
Another note:
at the moment you're instantiating a Random rand; the problem with that is that sequential instantiation of this class (in a short time) is not recommended and your two KArt are going to use the same random texture. To resolve this make the Random rand a static variable:
private static Random rand = new Random();
I am working on a game, and the spaceship is supposed to move when I press right and left. Unfortunately, this is not working well. Here is the code that I think is relevant, if you need the rest, just ask.
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.Net;
using Microsoft.Xna.Framework.Storage;
namespace thedodger
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
int scorevalue = 0;
SpriteFont font;
List<gameObject> objectList = new List<gameObject>();
Random rand = new Random(1);
Asteroid asteroid;
public static int screenHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
public static int screenWidth =GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
int asteroidCount = 0;
Player player = new Player();
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()
{
// TODO: Add your initialization logic here
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);
font = Content.Load<SpriteFont>("font");
gameObject.texture = Content.Load<Texture2D>("asteroid");
Player.texture = Content.Load<Texture2D>("EnemyShip005");
// TODO: use this.Content to load your game content here
}
/// <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
}
/// <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)
{
scorevalue++;
player.Update(gameTime);
if (rand.Next(0, 8) == 2 && asteroidCount < 50)
{
for (int i = 0; i < 5; i++)
{
asteroid = new Asteroid(rand.Next(32,screenWidth));
objectList.Add(asteroid);
asteroidCount++;
}
}
foreach (Asteroid asteroid in objectList)
{
asteroid.Update(gameTime);
}
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <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);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.DrawString(font, "Score: " + scorevalue, new Vector2(5, 5), Color.White);
foreach (Asteroid asteroid in objectList)
{
asteroid.Draw(spriteBatch);
}
player.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Net;
using Microsoft.Xna.Framework.Storage;
namespace thedodger
{
class Player
{
public static Texture2D texture;
int xPos = 100;
int yPos = 100;
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, new Rectangle(xPos,yPos,75,59), Color.White);
}
public void Update(GameTime gameTime)
{
KeyboardState keyboard = new KeyboardState();
if (keyboard.IsKeyDown(Keys.Left))
{
xPos--;
}
if (keyboard.IsKeyDown(Keys.Right))
{
xPos++;
}
}
}
}
In Player.Update, you are doing new KeyboardState() - I think this is giving you an empty keyboard state object. Try using Keyboard.GetState() instead.