Sign in to follow this  

XNA 4.0 Particle class for 2D game

This topic is 2098 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am working on a 2D game in XNA 4.0, and I'm trying to get a particle class to work. All of the particles are created and rendered, but they do not update their positions. Here is the code I am using, If anyone could help me figure out why this isn't working it would be a great help.


[CODE]
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.Input.Touch;
using Microsoft.Xna.Framework.Media;
namespace Game1
{
public enum ParticleDetail { LOW, MEDIUM, HIGH };
public enum ParticleType { DIRECTED, RANDOM };
class ParticleEmitter
{
private struct particle
{
public bool alive;
public int duration;
public Vector2 pos;
public Vector2 vel;
public float scale;
public void Update(ref GameTime gameTime)
{
if (this.alive)
{
this.pos += this.vel;
this.duration = this.duration - gameTime.ElapsedGameTime.Milliseconds;
if (this.duration <= 0)
{
this.alive = false;
}
}
}
public void Render(ref Texture2D texture, ref SpriteBatch spriteBatch)
{
if (this.alive)
{
int height = texture.Height / 2;
int width = texture.Width / 2;
Vector2 origin = new Vector2(width, height);
spriteBatch.Draw(texture, this.pos, null, Color.White, 0, origin, this.scale, SpriteEffects.None, 0);
}
}
};
protected Random rnd { get; private set; }
public Texture2D texture;
private List<particle> ParticleList;
public void Init()
{
rnd = new Random();
ParticleList = new List<particle>();
}
public void CreateParticles(ParticleDetail detailLevel, ParticleType type,
Vector2 Position, Vector2 Direction, int MaxAngleDeg)
{
switch (detailLevel)
{
case ParticleDetail.LOW:
{
for (short i = 0; i < 10; i++)
{
int tAngle = rnd.Next((int)MaxAngleDeg * 2);
tAngle = MaxAngleDeg - tAngle;
float Angle = (float)tAngle * (3.14f / 180.0f);
float x = (float)(Direction.X * Math.Cos(Angle) - Direction.Y * Math.Sin(Angle));
float y = (float)(Direction.X * Math.Sin(Angle) + Direction.Y * Math.Cos(Angle));
particle p = new particle();
p.alive = true;
p.duration = 1000;
p.pos = Position;
p.vel = new Vector2(x, y);
p.vel.Normalize();
p.vel *= 10.0f;
p.scale = 0.5f;
ParticleList.Add(p);
}
} break;
case ParticleDetail.MEDIUM:
{
for (short i = 0; i < 20; i++)
{
int tAngle = rnd.Next((int)MaxAngleDeg * 2);
tAngle = MaxAngleDeg - tAngle;
float Angle = (float)tAngle * (3.14f / 180.0f);
int x = (int)(Direction.X * Math.Cos(Angle) - Direction.Y * Math.Sin(Angle));
int y = (int)(Direction.X * Math.Sin(Angle) + Direction.Y * Math.Cos(Angle));
particle p = new particle();
p.alive = true;
p.duration = 1000;
p.pos = Position;
p.vel = new Vector2(x, y);
p.vel.Normalize();
p.vel *= 10.0f;
p.scale = 1.0f;
ParticleList.Add(p);
}
}break;
case ParticleDetail.HIGH:
{
for (short i = 0; i < 30; i++)
{
int tAngle = rnd.Next((int)MaxAngleDeg * 2);
tAngle = MaxAngleDeg - tAngle;
float Angle = (float)tAngle * (3.14f / 180.0f);
int x = (int)(Direction.X * Math.Cos(Angle) - Direction.Y * Math.Sin(Angle));
int y = (int)(Direction.X * Math.Sin(Angle) + Direction.Y * Math.Cos(Angle));
particle p = new particle();
p.alive = true;
p.duration = 1000;
p.pos = Position;
p.vel = new Vector2(x, y);
p.vel.Normalize();
p.vel *= 10.0f;
p.scale = 1.0f;
ParticleList.Add(p);
}
}break;
default:
{}break;
};
}
public void UpdateParticles(ref GameTime gameTime)
{
foreach (particle p in ParticleList)
{
p.Update(ref gameTime);
}
}
public void RenderParticles(ref SpriteBatch spriteBatch)
{
foreach (particle p in ParticleList)
{
p.Render(ref texture, ref spriteBatch);
}
}
}
}
[/CODE]

Share this post


Link to post
Share on other sites
Please, use the code command. The code is difficult to follow without indentation.

Are you sure that p.vel is different than 0? What happen if you put an arbitrary number, let say (0.1, 0.1).

Share this post


Link to post
Share on other sites
I used the break points in this to step through the code, and it says that the p.vel has a value, but it doesn't seem to want to update anyway.

Share this post


Link to post
Share on other sites
public int duration; should be float or double. EDIT: Sorry, I didn't see that you use milliseconds.

Do you try a velocity like (0.1, 0.1)? We need to be sure where you have the problem. Use something like this.pos += new Vector2(0.1f, 0.1f);

Share this post


Link to post
Share on other sites
Then show me your spritebatch begin and end.

One question: Why do you use a origin value different than 0,0?

Share this post


Link to post
Share on other sites
[quote name='jischneider' timestamp='1334865292' post='4932927']
He is not doing any modification to the gameTime variable, the problem should not be there.
[/quote]

You seem to have misinterpreted the [i]?[/i] character. I was curious to what it would actually achieve, I wasn't stating that it was the problem. It's true that alot of people do answer questions with questions, so I can't grill you for replying like you did. [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]

Share this post


Link to post
Share on other sites
[quote name='dAND3h' timestamp='1334867879' post='4932942']
[quote name='jischneider' timestamp='1334865292' post='4932927']
He is not doing any modification to the gameTime variable, the problem should not be there.
[/quote]

You seem to have misinterpreted the [i]?[/i] character. I was curious to what it would actually achieve, I wasn't stating that it was the problem. It's true that alot of people do answer questions with questions, so I can't grill you for replying like you did. [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img]
[/quote]

Yes, I misinterpreted you. [img]http://public.gamedev.net//public/style_emoticons/default/ph34r.png[/img]

He seems not understand well the real use of ref. TimeSpan is a structured, he can use ref to do modifications to a value type and/or to access/use less memory in a method call (i.e. optimization). But he also use ref with a texture (a reference type), there a really few uses in which use the pointer of the pointer.

Share this post


Link to post
Share on other sites
Hello, just to let you guys know, I switched the particle struct to a class, and it worked. thanks for the help anyway.

Share this post


Link to post
Share on other sites
Of course. When you do foreach (particle p in ParticleList) you are making a copy of the particle because particle is a value type. So when you update position this value is lost because is not done in the original particle, instead is done in the temporal copy.

Share this post


Link to post
Share on other sites
Sign in to follow this