'particleEngine' being drawn against a vector - c#

I'm using XNA and C#.
I have a problem with calling a vector variable from my particleEmitter. I can draw the particle just fine if it is static or not moving. And when I have a vector variable that is set to a fixed position of (x,y) it's okay and draws on the screen. But if I have a vector variable that has been set to move in the x or y axis it does not draw at all.
Declared variables:
Vector2 shipPos;
float shipMovement;
ParticleEngine particleEngine;
And a method that loads stuff about what should happen with the vectors and the way it should behave:
public void loadEmitter(GameTime gameTime)
{
shipMovement = 2f;
shipPos.Y -= shipMovement;
particleEngine.EmitterLocation = new Vector2(shipPos.X,shipPos.Y);
}
I'm trying to get particleEngine to trail the movement of a ship. What I can't seem to do is get it to draw when I set this up to happen.
Other info: ParticleEngine is a class in itself and basically sets some parameters about how the particles I will be drawing should behave. I have other screens with the spritebatch Begin and End calls. Other than that, here's the code for my main class:
namespace PlanetDrill2
{
class LaunchScreen : Screen
{
Texture2D LaunchScreenTexture;
Texture2D shipLaunch;
Vector2 shipPos;
float shipMovement;
ParticleEngine particleEngine;
Vector2 smokePos;
public LaunchScreen(Game game, SpriteBatch batch, ChangeScreen changeScreen)
: base(game, batch, changeScreen)
{
}
protected override void SetupInputs()
{
base.SetupInputs();
}
public override void Activate()
{
base.Activate();
}
public void LaunchShip()
{
}
public void loadEmitter(GameTime gameTime)
{
shipMovement = 2f;
shipPos.Y -= shipMovement;
particleEngine.EmitterLocation = new Vector2(shipPos.X,shipPos.Y);
}
protected override void LoadScreenContent(ContentManager content)
{
LaunchScreenTexture = content.Load<Texture2D>("launchTest");
shipLaunch = content.Load<Texture2D>("shipLaunch");
List<Texture2D> textures = new List<Texture2D>();
textures.Add(content.Load<Texture2D>("smoketexture"));
particleEngine = new ParticleEngine(textures, new Vector2(0, 0));
base.LoadScreenContent(content);
}
protected override void UpdateScreen(GameTime gameTime, DisplayOrientation screenOrientation)
{
//if (gameTime.TotalGameTime.Seconds>10)
//{
// changeScreenDelegate(ScreenState.UMA);
//}
loadEmitter(gameTime);
particleEngine.Update();
base.UpdateScreen(gameTime, screenOrientation);
}
protected override void DrawScreen(SpriteBatch batch, DisplayOrientation screenOrientation)
{
batch.Draw(LaunchScreenTexture, Vector2.Zero, Color.White);
batch.Draw(shipLaunch, new Vector2(80, 450) +shipPos, Color.White);
particleEngine.Draw(batch);
base.DrawScreen(batch, screenOrientation);
}
protected override void SaveScreenState()
{
base.SaveScreenState();
}
} // end class LaunchScreen
} // end namespace PlanetDrill2

From here
batch.Draw(shipLaunch, new Vector2(80, 450) +shipPos, Color.White);
particleEngine.Draw(batch);
It looks like you are drawing the ship relative to [80, 450], but you are not applying this offset to the particleEngine.

Related

XNA 4.0 2D Camera With Cursor Active

I am pretty new to XNA framework For now I can do drawing, animations and so, But I have encountered a problem with Camera displaying cursor.
I want to achieve a 2D game where you use cursor as main controller (selecting, moving on map and so). I want the camera to be controlled by cursor Right-click and drag.
I have created very simple logic for moving it, but it's not working.
Anytime I press RButton and drag it, camera is working well.
The problem pop up when do it again. Whole View resets to initial position. I guess the problem is with mouse position relative to world.
I am adding my camera Class
class TCCamera : IDrawable
{
public Matrix transformation;
Viewport viewport;
Vector2 centre;
public TCCamera(Viewport vport)
{
viewport = vport;
this.centre = new Vector2();
}
public void LoadContent(Microsoft.Xna.Framework.Content.ContentManager Content)
{
}
public void Draw(SpriteBatch spriteBatch)
{
throw new NotImplementedException();
}
public Matrix Translate
{
get
{
return this.transformation;
}
}
public void Update(GameTime gameTime)
{
MouseState mstat = Mouse.GetState();
if (mstat.RightButton == ButtonState.Pressed)
{
this.centre.X = mstat.X;
this.centre.Y = mstat.Y;
transformation = Matrix.CreateTranslation(new Vector3(-centre.X, -centre.Y, 0));
}
}
}
}
And also the Cursor Class
class TCCursor : IDrawable
{
Texture2D tex;
public Vector2 pos;
Rectangle bBox;
public TCCursor()
{
this.pos = new Vector2();
this.bBox = new Rectangle(0, 0, 50, 50);
}
public void LoadContent(ContentManager Content)
{
tex = Content.Load<Texture2D>("cursor");
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(tex, bBox, Color.White);
}
public void Update(GameTime gameTime)
{
MouseState value = Mouse.GetState();
this.pos.X = value.X;
this.pos.Y = value.Y;
this.bBox.X = value.X;
this.bBox.Y = value.Y;
}
}
And also I am drawing as
spriteBatch.Begin(SpriteSortMode.Immediate,
BlendState.AlphaBlend,
null, null, null, null, camera.Translate);
I still cannot completely understand the concept of World and View Matrices and their Math.
After a while I have found the solution using inverse matrices.
I have found this extremly useful: Tutorial XNA Camera

Reset Texture2Ds in XNA

I'm Having a problem with an experiment of mine. I'm trying to make a method that fuses one Texture2D into another Texture2D, then reloads the Texture2D, this time moving the pasted texture in a new spot. I plan to perfect upon this method in later projects where I paste in a spotlight onto a dark background to "illuminate" the scenery behind it. While I managed to make the paste-to method work perfectly, I am having some major problems with the second part of my plan. I have the pasted texture set to a Vector2, where the X member increases by 1 every frame, thus dragging the pasted texture along the background. However, the background doesn't reset after each frame, leaving a drag mark on the background where the previous image was. For the last half hour I've been working to cure this problem by resetting the background texture to make it clean again for when it has the other image pasted onto it.
Here is my code.
namespace CopyTest
{
public class Image
{
public Texture2D Bitmap;
public Vector2 Position;
public String BitmapName;
public Rectangle Viewport;
public Color Tint = Color.White;
public void ResetViewportDimensions()
{
this.Viewport = new Rectangle(this.Viewport.X, this.Viewport.Y, Bitmap.Width, Bitmap.Height);
}
public void Draw(SpriteBatch Target)
{
}
public void FinalizeBitmap(ContentManager Target)
{
this.Bitmap = null;
this.Bitmap = Target.Load<Texture2D>(this.BitmapName);
}
public Image(Vector2 Position, String BitmapName)
{
this.BitmapName = BitmapName;
this.Position = Position;
}
}
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Image Rainbow = new Image(new Vector2(0, 0), "Rainbow");
public Image Eye = new Image(new Vector2(0, 0), "Glow");
public Image PrintOut = new Image(new Vector2(0, 0), "Rainbow");
public Vector2 Destination = new Vector2(100, 50);
public void PrintTo(Image Source, Image Target, Vector2 Location)
{
Color[] A = new Color[Source.Bitmap.Width * Source.Bitmap.Width];
Color[] B = new Color[Target.Bitmap.Width * Target.Bitmap.Width];
int Y = 0;
int X = 0;
Source.Bitmap.GetData(A);
Target.Bitmap.GetData(B);
for (int i = 0; i < A.Length; i++)
{
B[(int)Location.X + X + (((int)Location.Y + Y) * Target.Bitmap.Width)] = A[i];
X++;
if (X == Source.Bitmap.Width)
{
X = 0;
Y++;
}
}
Target.Bitmap.SetData<Color>(B);
}
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Eye.FinalizeBitmap(Content);
Rainbow.FinalizeBitmap(Content);
PrintOut.FinalizeBitmap(Content);
Eye.ResetViewportDimensions();
Rainbow.ResetViewportDimensions();
PrintOut.ResetViewportDimensions();
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
GraphicsDevice.Textures[0] = null;
PrintOut.FinalizeBitmap(Content);
PrintTo(Eye, PrintOut, Destination);
Destination.Y++;
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(PrintOut.Bitmap, PrintOut.Position, PrintOut.Viewport, PrintOut.Tint);
spriteBatch.End();
base.Draw(gameTime);
}
}
Any help at all would be greatly appreciated.

Object reference not set to an instance of an object. What is wrong? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have two classes: Game1 and Animation.
I always get that "Object reference not set to an instance of an object." error message in this line of the Game1 class: animation.Draw(spriteBatch);
What is wrong? I don't know what to change.
Animation class code:
public class Animation
{
private int _animIndex;
public TimeSpan PassedTime { get; private set; }
public Rectangle[] SourceRects { get; private set; }
public Texture2D Texture {get; private set; }
public TimeSpan Duration { get; private set; }
public Animation(Rectangle[] sourceRects, Texture2D texture, TimeSpan duration)
{
for (int i = 0; i < sourceRects.Length; i++)
{
sourceRects[i] = new Rectangle((sourceRects.Length - 1 - i) * (Texture.Width / sourceRects.Length), 0, Texture.Width / sourceRects.Length, Texture.Height);
}
SourceRects = sourceRects;
Texture = texture;
Duration = duration;
}
public void Update(GameTime dt)
{
PassedTime += dt.ElapsedGameTime;
if (PassedTime > Duration)
{
PassedTime -= Duration; // zurücksetzen
}
var percent = PassedTime.TotalSeconds / Duration.TotalSeconds;
_animIndex = (int)Math.Round(percent * (SourceRects.Length - 1));
}
public void Draw(SpriteBatch batch)
{
batch.Draw(Texture, new Rectangle(0, 0, Texture.Width / SourceRects.Length, Texture.Height), SourceRects[_animIndex], Color.White);
}
}
Game1 class code:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Animation animation;
Texture2D gegner;
Rectangle[] gegnerbilder = new Rectangle[10];
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
gegner = Content.Load<Texture2D>("kurzeanim");
}
protected override void Update(GameTime gameTime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.A))
{
animation = new Animation(gegnerbilder, gegner, TimeSpan.FromSeconds(3));
animation.Update(gameTime);
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
animation.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
Your field animation is not initialized and you are calling its instance method Draw that is why you are getting this exception. At that particular line it is null. It is being initialized in update method, you may initialize it in the constructor to avoid that exception
Ensure that the Update-method of the Game1-class is called before the Draw-method of that class or ensure that animation is not null before calling its members:
protected override void Draw(GameTime gameTime)
{
if (animation != null)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
animation.Draw(spriteBatch);
spriteBatch.End();
}
base.Draw(gameTime);
}
You only ever instantiate the animation property if the A key is depressed when Update is called.
protected override void Update(GameTime gameTime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.A))
{
animation = new Animation(gegnerbilder, gegner, TimeSpan.FromSeconds(3));
animation.Update(gameTime);
}
base.Update(gameTime);
}
You need to initialise it earlier (e.g. in the constructor) or add some logic to the Draw method to check for null values.
animation = new Animation(gegnerbilder, gegner, TimeSpan.FromSeconds(3));
Are you really creating a new animation and updating it every Update() That could be 60 Times per second.
You are going to need to add it to your Initialize() Method (Or whenever you need to change the animation)
Then in update you can still do animation.Update() but without the constructor.

Error on xna "is inaccessible due to its protection level"

I am getting an error when I try to get the mouse position.
This is my player class. I am trying to make the player sprite move by mouse cursor
class Player : Actor
{
public MouseState mState;
EnemyManager enemyManager;
public Player(Texture2D texture, Vector2 origin, SpriteBatch spriteBatch, EnemyManager enemyManager)
: base(texture, origin, spriteBatch, new Vector2(250.0f, 516.0f))
{
this.enemyManager = enemyManager;
}
public override void Update(GameTime gameTime)
{
//KeyboardState keyboardState = Keyboard.GetState();
//if (keyboardState.IsKeyDown(Keys.Left))
//{
// if (this.Position.X > 32.0f)
// {
// this.Position -= 10.0f * Vector2.UnitX;
// }
//}
//if (keyboardState.IsKeyDown(Keys.Right))
//{
// if (this.Position.X < 748.0f)
// {
// this.Position += 10.0f * Vector2.UnitX;
// }
//}
MouseState mState = Mouse.GetState();
this.Position = new Vector2(mState.x, mState.y);
// Collisions...
foreach (Enemy e in this.enemyManager.Enemies)
{
if (this.BoundingRectangle.Intersects(e.BoundingRectangle))
{
e.OnHit();
break;
}
}
base.Update(gameTime);
}
}
and this is my Actor class which has position variables
namespace Shmup
{
public class Actor
{
public Texture2D texture;
public Vector2 origin;
public SpriteBatch spriteBatch;
public Vector2 position;
public Rectangle boundingRectangle;
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public Rectangle BoundingRectangle
{
get { return boundingRectangle; }
}
public Actor(Texture2D texture, Vector2 origin, SpriteBatch spriteBatch, Vector2 initialPosition)
{
this.texture = texture;
this.origin = origin;
this.spriteBatch = spriteBatch;
this.position = initialPosition;
boundingRectangle = new Rectangle((Int32)(initialPosition.X - origin.X), (Int32)(initialPosition.Y - origin.Y), texture.Width, texture.Height);
}
public virtual void Update(GameTime gameTime)
{
}
public virtual void Draw(GameTime gameTime)
{
this.spriteBatch.Draw(texture, position - origin, Color.White);
}
}
}
my main class
public class MyGame : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player player;
EnemyManager enemyManager;
Actor actor;
public MyGame()
{
graphics = new GraphicsDeviceManager(this);
IsMouseVisible = true;
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
Actor actor = new Actor();
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
startTheGame();
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
{
this.Exit();
}
this.player.Update(gameTime);
this.enemyManager.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Maroon);
this.spriteBatch.Begin();
this.player.Draw(gameTime);
this.enemyManager.Draw(gameTime);
this.spriteBatch.End();
base.Draw(gameTime);
}
void startTheGame()
{
enemyManager = new EnemyManager(this.Content.Load<Texture2D>("Enemy"), new Vector2(16), this.spriteBatch);
player = new Player(this.Content.Load<Texture2D>("Player"),actor.position, this.spriteBatch, enemyManager);
enemyManager.StartTheGame(10);
}
}
This line is the problem I think:
this.Position = new Vector2(mState.x, mState.y);
x and y are not publicly exposed on MouseState. You need to capitalize them (C# is case-sensitive). Use this instead:
this.Position = new Vector2(mState.X, mState.Y);
"making these changes gives me a different error Object reference not set to an instance of an object in the line player = new Player(this.Content.Load("Player"),actor.position, this.spriteBatch, enemyManager); on my main class it says Error 'Shmup.Actor' does not contain a constructor that takes 0 arguments –"
The constructor for Actor requires - Texture2D texture, Vector2 origin, SpriteBatch spriteBatch, Vector2 initialPosition .
So you would need to change the "Actor actor = new Actor();" into LoadContent() or a separate method after you have supplied all the information required to declare a new Actor.
It should read something along these lines(replace each argument with the proper item from your game class):
Actor actor = new Actor( texture, origin, spriteBatch, initialPosition);
If you do that it will fix the error, If you don't you will continue to get the error unless you define a constructor in Actor that takes 0 arguments. Hope this helps somewhat.

Why is my Texture origin is incorrect at runtime?

Alright, so this is the code:
Game1.cs Class:
public class Game1 : Microsoft.Xna.Framework.Game
{
KeyboardState keyboard;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player MyPlayer;
Texture2D Ball;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
IsMouseVisible = true;
graphics.IsFullScreen = true;
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Ball = Content.Load<Texture2D>("Images/Ball");
MyPlayer = new Player(new Vector2(700, 700), Ball);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Escape))
this.Exit();
MyPlayer.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
MyPlayer.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
Game object class:
abstract class GameObject
{
protected Vector2 position;
protected Texture2D texture;
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Vector2.Zero;
this.texture = Texture;
}
protected Vector2 Position { set; get; }
protected Texture2D Texture { set; get; }
protected float X
{
set { position.X = value; }
get { return position.X; }
}
protected float Y
{
set
{
position.Y = value;
}
get
{
return position.Y;
}
}
public int GraphicsWidth { set; get; }
public int GraphicsHeight { set; get; }
}
Player class:
class Player : GameObject
{
KeyboardState keyboard;
bool IsJump = false;
int SpeedX = 5;
int SpeedY = 5;
public Player(Vector2 position, Texture2D tex):base(position,tex)
{
}
public int Height
{
get { return this.texture.Height; }
}
public int Width
{
get { return this.texture.Width; }
}
public void intialize()
{
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, Position, Color.White);
}
public void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.D))
{
X += SpeedX;
}
else if (keyboard.IsKeyDown(Keys.A))
{
X-= SpeedX;
}
if (X > GraphicsWidth)
{
X = GraphicsWidth;
}
}
}
When I'm debugging it, My ball texture is in (0,0) (TOP LEFT). Instead of (700,700).
BTW, If anyone can give me some advices if I made anything wrong, or anything I should change, it Would be great!!
Thanks alot for helpers.
EDIT: Anyone.. please? I suppose it's not so hard to figure it out ><.
In your GameObject constructor you are setting the position to Vector2.Zero and not to your param Position.
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Vector2.Zero;
this.texture = Texture;
}
should be
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Position;
this.texture = Texture;
}
There are two issues I see. The first one, answered by CraigW, you've already fixed:
protected Vector2 position;
public GameObject(Vector2 Position, Texture2D Texture)
{
position = Vector2.Zero; // <---- this needs to be position = Position
this.texture = Texture;
}
protected Vector2 Position { set; get; }
The second issue is your Position property. When you declare a property using the { get; set; } syntax the compiler is implicitly giving you a backing field to store the value of the property. But you're creating your own position field as well. Your position field is getting set to the value passed in the constructor (assuming you've fixed issue #1 in your constructor that is), but the getter for your Position property is returning the compiler generated field, which you haven't set to anything.
There are two ways you can fix this. Either remove your position field and reference the Position property everywhere, or modify your property to use your position field.
Fix Option #1: just use the Position property
// protected Vector2 position; // <----- remove this
public GameObject(Vector2 Position, Texture2D Texture)
{
this.Position = Position;
this.texture = Texture;
}
Fix Option #2: Change your Position property to use your field
protected Vector2 Position { get { return position; } set { position = value; } }
-7? What did you do deserve this!?
I think there's a logic error somewhere in your code, change this:
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, Position, Color.White);
}
To this:
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, new Vector2(700,700), Color.White);
}
And see how it works for you (it should work fine) :)
From there you're going to have to work backwards to find where Position is not being set to the value you want.
Personally I've never been a fan of gameobject, much better to create your own base types since you have total control over how they work and can more easily solve issues that pop up.

Categories