I have problem. I have tryed how to make my texture move, but my solution is slow and it is not working. Does anybody know how to make texture2D move using C# XNAGamestudio. ANybody please help me!
EDIT:
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Hashtable Objects = new Hashtable();
public Hashtable XPOS = new Hashtable();
public Hashtable YPOS = new Hashtable();
public int NUM = 0;
public bool UP = true;
public bool DOWN = false;
public bool LEFT = false;
public bool RIGHT = false;
......
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
this.AddObject("Nameee", "C:\\Box.png");
// TODO: Add your update logic here
if (UP)
{
if (NUM != 25)
{
AppendObject(new Vector2((float)this.XPOS["Nameee"], (float)this.XPOS["Nameee"] - NUM), "Nameee");
NUM++;
Thread.Sleep(100);
}
else
UP = false;
}
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();
//spriteBatch.End();
//base.Draw(gameTime);
}
public void AddObject(string TagName, string ObjectImage)
{
Texture2D fileTexture;
using (FileStream fileStream = new FileStream(#ObjectImage, FileMode.Open))
{
fileTexture = Texture2D.FromStream(graphics.GraphicsDevice, fileStream);
}
if (!this.Objects.ContainsKey(TagName))
{
this.Objects.Add(TagName, fileTexture);
this.XPOS.Add(TagName, 0.0F);
this.YPOS.Add(TagName, 50.0F);
}
}
public void AppendObject(Vector2 pos, string tagName)
{
spriteBatch.Begin();
spriteBatch.Draw((Texture2D)this.Objects[tagName], new Vector2((float)this.XPOS[tagName], (float)this.YPOS[tagName]), Color.White);
spriteBatch.End();
}
Hmm, well technically, this looks like it should move a texture along the X axis.
As for performance, you may want to take these things into consideration:
You are calling this.AddObject("Nameee", "C:\\Box.png"); on every update. That's not a good thing. Call this once in your LoadContent() method.
Instead of using Thread.Sleep(100);, I would suggest tracking the time elapsed with GameTime. (Hit the comment if you need an example of how to do this)
You are creating a new vector2 on each pass for the texture position. While this probably doesn't have a noticeable performance hit since its only creating 10 a second (thanks to your Thread.Sleep(100);, I would suggest using the same one.
On a side note, I would recommend completely refactoring this code for a more object oriented approach. Create a class that holds a Texture2D and a Vector2. Then give it an Update() method and a Draw(SpriteBatch sb) method and perform your work in there.
That's just a suggestion though.
You can do something similar to this, and you should use the content manager to load assets.
public class Sprite
{
public Vector2 Position = Vector2.Zero;
public Texture2D Texture;
public float Scale = 1;
public void LoadAsset(Game game, string asset)
{
Texture = game.Content.Load<Texture2d>(asset);
}
public Draw(SpriteBatch batch)
{
batch.Draw(Texture, Position, null, Color.White, ...,... Scale,...);
}
}
//In your game:
List<Sprite> Sprites = new List<Sprite>();
Initialize()
{
base.Initialize();
Sprite myBox = new Box();
myBox.LoadAsset("Box");
Sprites.Add(myBox);
}
Update(GameTime gametime)
{
myBox.Position += Vector2.UnitX * Speed * (float) gametime.elapsed.TotalSeconds;
}
Draw()
{
batch.begin();
foreach (Sprite sprite in Sprites) sprite.Draw(batch);
batch.end();
}
Both good answers by Blau and justnS. I would also advise to take a look at some XNA tutorials to get a better understanding of the XNA Framework and how it should be used (i.e. the purpose of the separate Initialize(), LoadContent(), Update(), Draw(), etc methods).
Try these for starters:
Riemer's
MSDN
XNA Game Dev
Related
How do I clone an object then pick a random position, then draw it.
This is the code I have for the object:
public class Trash : ICloneable
{
private Texture2D _texture;
private float _rotation;
public Vector2 Position;
public Vector2 Origin;
public float RotationVelocity = 3f;
public float LinearVelocity = 4f;
public Trash(Texture2D texture)
{
_texture = texture;
}
public void Update()
{
// Do epic stuff here
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(_texture, Position, null, Color.White, _rotation, Origin, 1, SpriteEffects.None, 0f);
}
public object Clone()
{
return this.MemberwiseClone();
}
And this is code I have in Game1.cs so far:
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private SeaJam.Objects.Trash Trash;
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();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
var texture = Content.Load<Texture2D>("Prototype");
Trash = new Objects.Trash(texture)
{
Position = new Vector2(100, 100),
Origin = new Vector2(texture.Width / 2, texture.Height - 25),
};
}
protected override void Update(GameTime gameTime)
{
Trash.Update();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
Trash.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
private void AddTrash()
{
var rnd = new System.Random();
var NewTrash = Trash.Clone();
}
The problem is Whenever I'd try to give a random position for the clone in the AddTrash() Method, I'd only get errors, such as "'object' does not contain a definition for 'Position' and no accessible extension method 'Position' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)"
your constructor:
public Trash(Texture2D texture)
{
_texture = texture;
}
Needs to be extended with the desired changeable parameters. In your case, it needs to add Position and Origin as parameter, and then apply it as a value.
Like this:
public Trash(Texture2D texture, Vector2 position, Vector2 origin)
{
_texture = texture;
Position = position;
Origin = origin;
}
And change the way you call it in the game1.cs as well, they need to work similair like texture:
var texture = Content.Load<Texture2D>("Prototype");
var position = new Vector2(100, 100),
var origin = new Vector2(texture.Width / 2, texture.Height - 25),
Trash = new Objects.Trash(texture, position, origin);
And as a tip: keep consistency in your field names, mixing in underscore and lowercase in one field, and uppercase in an other field will get confusing to understand. especially when the parameters needs a name different from the fields as well. I prefer to keep them all with the first letter uppercase.
The player box is continuing through walls in an undesired fashion, I have tried making it so that the player moves in 0.1f(u) increments at a time, but this severely drops the performance of the game. Is there any way I can detect if the player is hitting a wall, what side they hit it on and how can I prevent them from clipping into the wall?
Here is the code that I am running (this is minimalistic of course)
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 Platformer
{
public class Player
{
double terminalVelocity;
//AnimatedTexture texture;
public Texture2D texture;
public Vector2 Position, Velocity;
public Rectangle boundingBox;
public Player(Texture2D tex, Vector2 pos, Vector2 vel, Rectangle bb)
{
texture = tex;
Position = pos;
Velocity = vel;
boundingBox = bb;
terminalVelocity = Math.Sqrt((2*bb.Width*bb.Height*Game1.gravity)/-9.8*2);
}
public void updateBoundingBoxes()
{
boundingBox.X = (int)Position.X;
boundingBox.Y = (int)Position.Y;
}
public void onUpdate()
{
updateBoundingBoxes();
Position.X += Velocity.X;
Position.Y += Velocity.Y;
//Velocity = Vector2.Zero;
Velocity.Y += Game1.gravity / 60;
Velocity.X /= 1.2f;
}
public void Draw(SpriteBatch sb)
{
updateBoundingBoxes();
sb.Begin();
sb.Draw(texture,boundingBox,GameLighting.currentColour());
sb.End();
}
}
public enum GameLightingState
{
Red, Dark, Orange, Blue, White
}
public class Platform : Object
{
Texture2D text;
public Rectangle rect;
public Platform(Texture2D t, Vector2 p, int sizeX, int sizeY)
{
text = t;
rect = new Rectangle((int)p.X, (int)p.Y, sizeX, sizeY);
}
public void onPlayerCollision(Player p)
{
p.Velocity.X = -p.Velocity.X / 2;
p.Velocity.Y = -p.Velocity.Y / 2;
}
public void Draw(SpriteBatch sb)
{
sb.Begin();
sb.Draw(text, rect, GameLighting.currentColour());
sb.End();
}
public void onUpdate()
{
}
}
public class GameLighting
{
public static Color currentColour()
{
return eToColour(Game1.currentLightingState);
}
public static Color eToColour(GameLightingState gls)
{
switch (gls)
{
case(GameLightingState.Red):
return Color.Red;
case (GameLightingState.Blue):
return Color.Blue;
case (GameLightingState.Orange):
return Color.Orange;
case (GameLightingState.Dark):
return Color.DarkGray;
case (GameLightingState.White):
return Color.White;
}
return Color.White;
}
}
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
public static float gravity = 9.80665f;
public static GameLightingState currentLightingState;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Platform> platforms;
List<Player> players;
int controlledPlayerIndex = 0;
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
currentLightingState = GameLightingState.White;
platforms = new List<Platform>();
players = new List<Player>();
players.Add(new Player(this.Content.Load<Texture2D>("Images/dirt"), new Vector2(300,0), new Vector2(0,0), new Rectangle(300,0,20,20)));
platforms.Add(new Platform(this.Content.Load<Texture2D>("Images/dirt"),new Vector2(300,450),200,20));
platforms.Add(new Platform(this.Content.Load<Texture2D>("Images/dirt"), new Vector2(20,20), 20, 200));
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
}
/// <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();
foreach (Player p in players)
{
Boolean intersects = false;
Rectangle tempRectangle = new Rectangle((int)(p.Position.X + p.Velocity.X),(int) (p.Position.Y + p.Velocity.Y), p.boundingBox.Width, p.boundingBox.Height);
foreach (Platform pl in platforms)
{
intersects = intersects || tempRectangle.Intersects(pl.rect);
}
if (!intersects)
{
p.onUpdate();
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
players[controlledPlayerIndex].Velocity.Y -= 0.75f;
}
if (Keyboard.GetState().IsKeyDown(Keys.A))
{
players[controlledPlayerIndex].Velocity.X -= 0.75f;
}
if (Keyboard.GetState().IsKeyDown(Keys.D))
{
players[controlledPlayerIndex].Velocity.X += 0.75f;
}
// 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
foreach (Platform p in platforms)
{
p.Draw(spriteBatch);
}
foreach (Player p in players)
{
p.Draw(spriteBatch);
}
base.Draw(gameTime);
}
}
}
*Updated Source Code based on first comments
One note about this code, you need to run it in XNA and use an icon called dirt.png in a folder called Images, it doesn't matter what the picture looks like, you just need it to fully understand what is happening
Had a similar problem recently myself. Here is what I did.
//variables needed
public bool follow = true;
public Vector2D startpoint;
//puts the startpoint value equal
//to the inital location of the player
public Player()
{
startpoint.X = rectangle.X;
startpoint.Y = rectangle.Y;
}
//if any of the collision tests fail
if(collision occurs)
{
collision();
}
//else update startpoint to new valid location
else
{
startpoint.X = rectangle.X;
startpoint.Y = rectangle.Y;
follow = true;
}
if(follow == true)
{
//movement commands occur
}
else
{
follow = true;
}
//if a condition fails set player
//too last valid location
public void collision()
{
rectangle.X = startpoint.X;
rectangle.Y = startpoint.Y;
follow = false;
}
This worked well enough for me hope it helps.
I changed my code but it still doesn't work. I get this error message in the Intro class:
'GameStates': cannot reference a type through an expression; try 'menuinterface.Game1.GameStates' instead
What is wrong? I want to set the gamestate to MenuState if the player presses the Space Key.
Game1 class:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private IState currentState;
public enum GameStates
{
IntroState = 0,
MenuState = 1,
MaingameState = 2,
}
public GameStates CurrentState
{
get { return currentGameState; }
set { currentGameState = value; }
}
private GameStates currentGameState = GameStates.IntroState;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
currentState = new Intro(this);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
currentState.Load(Content);
}
protected override void Update(GameTime gameTime)
{
currentState.Update(gameTime);
KeyboardState kbState = Keyboard.GetState();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
currentState.Render(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
Interface:
public interface IState
{
void Load(ContentManager content);
void Update(GameTime gametime);
void Render(SpriteBatch batch);
}
Intro class:
public class Intro : IState
{
private IState currentState;
Texture2D Menuscreen;
private Game1 game1;
public Intro(Game1 game)
{
game1 = game;
}
public void Load(ContentManager content)
{
Menuscreen = content.Load<Texture2D>("menu");
}
public void Update(GameTime gametime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.Space))
game1.CurrentState = game1.GameStates.IntroState;
currentState = new Menu(game1);
}
public void Render(SpriteBatch batch)
{
batch.Draw(Menuscreen, new Rectangle(0, 0, 1280, 720), Color.White);
}
}
Your problem is not understanding how enumerative types work. Specifically, this line:
game1.GameStates = IntroState;
First, let's discuss a little of what an enum actually is. It's a structure that simply assigns names to integer values, and can then refer to each value by name, and thus make code more readable (as it's far easier to understand direction = Dir.Up than direction = 1).
Notice how I use those two example statements, though. In the code, you treat the enum as a type not as a variable, and this is the problem you're encountering. In fact, your problem is twofold. The first issue id that you're trying to assign a value to a structure, which is similar to writing int = 4 - i.e. it doesn't make sense. Your second issue is that enums are not global, so IntroState has no meaning outside game1.
Interestingly enough, you've set up the system correctly, as you have the currentGameState variable, which is what you actually intend to change. However, it is a private variable, disallowing access to it from outside the game1 class. You can either make the variable public, or create a property to access it. The latter is good practice, as it allows you to control how the variable is set. To create this, you can use something like this:
public GameStates CurrentState
{
get { return currentGameState; }
set { currentGameState = value; }
}
Once you have this in your game1 class, you can set the game state like so:
game1.CurrentState = Game1.GameStates.IntroState;
Notice how this code tells the program where to look for what you want. IntroState is part of a structure (GameStates) within game1, and so needs to be accessed explicitly.
Hopefully, this has helped you to understand how enumerative types work, and why the code you wrote doesn't make sense, and thus why it breaks.
Do what the error message says:
game1.GameStates = Game1.GameStates.IntroState;
You need to fully qualify that enum value.
I am trying to make Pong in XNA/C# using a class for the Paddle and Ball
Game1.cs:
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 Pong
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Paddle Paddle1 = new Paddle();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
Paddle1.Draw();
base.Draw(gameTime);
}
}
}
Paddle.cs:
namespace Pong
{
class Paddle
{
SpriteBatch spriteBatch;
ContentManager Content;
Texture2D paddle1;
Texture2D paddle2;
Vector2 Paddle1;
Vector2 Paddle2;
public void LoadContent()
{
paddle1 = Content.Load<Texture2D>("pongpaddle1");
Paddle1 = new Vector2();
Paddle1.X = 50;
Paddle1.Y = 50;
}
public void Draw()
{
spriteBatch.Begin(); //Causes NullReferenceException was unhandled, Object reference not set to an instance of an object.
spriteBatch.Draw(paddle1, Paddle1, Color.White);
spriteBatch.End();
}
}
}
I don't have anything in the Ball class yet, but it will use similar methods to Paddle.cs
Every time I've ran the code, I keep getting a System.StackOverFlow exception whenever it hits this line of code in Game1.cs:
Paddle Paddle1 = new Paddle();
How do I fix this? I don't see how it's run out of memory already.
EDIT: Updated code.
What's happening here is that Paddle inherits Game1. Game1 creates new Paddles:
Paddle Paddle1 = new Paddle();
Paddle Paddle2 = new Paddle();
Those Paddles are Games that need to initialize their own set of Paddles. Infinite recursion! I'm not sure how XNA works, but if that's how the inheritance should be, just move your initializations to Initialize():
// TODO: Add your initialization logic here
base.Initialize();
this.Paddle1 = new Paddle();
this.Paddle2 = new Paddle();
I kind of doubt that a game object should inherit from the game itself, though. That would seem like a rather poor design decision.
public class Game1 : Microsoft.Xna.Framework.Game
{
Paddle Paddle1 = new Paddle();
Paddle Paddle2 = new Paddle();
...
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
Paddle1.LoadContent();
}
...
}
class Paddle : Game1
{
...
protected override void LoadContent()
{
Paddle1 = new Vector2();
Paddle1.X = 50;
Paddle1.Y = 50;
base.LoadContent();
}
...
}
Two big problems here, there is a recursive LoadContent call. Not to mention your paddles have paddles which have paddles... Why is your paddle inheriting from Game1? It almost definitely shouldn't be.
Also your paddle instances instantiate other paddle instances, so you're in a loop of instantiating other paddle classes.
It seems like you might want to take a step back and just get used to some basic code first? For what it's worth, I wrote pong in xna for fun a few years back, it's a bit messy, but it might give you some starting help.
Here is an example of a paddle class based off the DrawableGameComponent class (drawn in primatives so it's a bit verbose):
public class Paddle : DrawableGameComponent
{
private readonly VertexPositionColor[] _vertices = new VertexPositionColor[6];
private readonly float _width;
private readonly float _height;
private IndexBuffer _indexbuffer;
private VertexBuffer _vertexbuffer;
public Vector3 Position { get; set; }
public Vector3 Direction { get; set; }
public float Speed { get; set; }
public Paddle(Game game, float width, float height)
: base(game)
{
_width = width;
_height = height;
}
protected override void LoadContent()
{
base.LoadContent();
_vertices[0].Position = new Vector3(0, 0, 0);
_vertices[0].Color = Color.Red;
_vertices[1].Position = new Vector3(_width, _height, 0);
_vertices[1].Color = Color.Green;
_vertices[2].Position = new Vector3(0, _height, 0);
_vertices[2].Color = Color.Blue;
_vertices[3].Position = new Vector3(_width, 0, 0);
_vertices[3].Color = Color.Green;
_vertexbuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), _vertices.Length, BufferUsage.WriteOnly);
_vertexbuffer.SetData(_vertices);
var indices = new short[6];
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 0;
indices[4] = 3;
indices[5] = 1;
_indexbuffer = new IndexBuffer(GraphicsDevice, typeof(short), 6, BufferUsage.WriteOnly);
_indexbuffer.SetData(indices);
}
public BoundingBox GetBoundingBox()
{
return new BoundingBox(Position, Position + new Vector3(_width, _height, 0));
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
GraphicsDevice.SetVertexBuffer(_vertexbuffer);
GraphicsDevice.Indices = _indexbuffer;
GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
}
}
this is my code so far:
Game1.cs Class:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player MyPlayer;
Texture2D Ball;
int GraphicsWidth,GraphicsHeight;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
GraphicsWidth = graphics.PreferredBackBufferWidth;
GraphicsHeight= graphics.PreferredBackBufferHeight;
MyPlayer = new Player(Ball, new Vector2(100, 100), Vector2.Zero);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Ball = Content.Load<Texture2D>("Images/ball");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
MyPlayer.Draw(spriteBatch);
base.Draw(gameTime);
}
}
Player class(The ball):
class Player
{
Texture2D Texture;
Vector2 Positon,Velocity;
public int Height
{
get { return this.Texture.Height; }
}
public int Width
{
get { return this.Texture.Width; }
}
public Player(Texture2D tex, Vector2 position,Vector2 velocity)
{
this.Texture = tex;
this.Positon = position;
this.Velocity = velocity;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(Texture, Positon, Color.White);
spriteBatch.End();
}
}
When I try to debug the game I have the following error:
This method does not accept null for this parameter.
Parameter name: texture
In that part:
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(Texture, Positon, Color.White);
spriteBatch.End();
}
Btw, I'd like to ask if I can make this code better or something like that.
Thanks alot!
Looks like you create the Player object before you've loaded the Ball content, and thus, the player holds null instead of a texture, but the Ball field in the Game is the real texture.
I would move the creation of Player into LoadContent, after you've assigned the Ball.
Ball = Content.Load<Texture2D>("Images/ball");
MyPlayer = new Player(Ball, new Vector2(100, 100), Vector2.Zero);
I'm going to preface my answer by saying you should call spriteBatch.begin() and spriteBatch.end() in your Game1.cs Draw function instead of your Player.cs Draw function. It's expensive and you shouldn't do it more than once per draw frame, unless it's absolutely necessary (it's not in this case).
With regards to your actual question, you need to load your player in the LoadContent method rather than your Initialize method.
Initialize is happening before your texture is loaded.
try moving MyPlayer = new Player(Ball, new Vector2(100, 100), Vector2.Zero);
into your LoadContent method after you load the texture into Ball.
It looks like you're loading the ball texture after you've already initialized myPlayer with the "NULL" Ball texture
This is because Initialize is called before LoadContent, and at the point you create your Player the Ball texture is still null.
Either create the Player object in LoadContent, after you load the ball, or allow Player to load its own content.