2D Particle Explosion

Posted by TheBroodian on Game Development See other posts from Game Development or by TheBroodian
Published on 2012-04-11T21:46:40Z Indexed on 2012/04/11 23:46 UTC
Read the original article Hit count: 261

Filed under:
|
|

I'm developing a 2D action game, and in said game I've given my primary character an ability he can use to throw a fireball. I'm trying to design an effect so that when said fireball collides (be it with terrain or with an enemy) that the fireball will explode. For the explosion effect I've created a particle that once placed into game space will follow random, yet autonomic behavior based on random variables.

Here is my question: When I generate my explosion (essentially 90 of these particles) I get one of two behaviors,

1) They are all generated with the same random variables, and don't resemble an explosion at all, more like a large mass of clumped sprites that all follow the same randomly generated path.

2) If I assign each particle a unique seed to its random number generator, they are a little bit -more- spread out, yet clumping is still visible (they seem to fork out into 3 different directions)

Does anybody have any tips for producing particle-based 2D explosions? I'll include the code for my particle and the event I'm generating them in.

Fire particle class:

    public FireParticle(xTile.Dimensions.Location StartLocation, ContentManager content)
    {
        worldLocation = StartLocation;
        fireParticleAnimation = new FireParticleAnimation(content);
        random = new Random();

        int rightorleft = random.Next(0, 3);
        int upordown = random.Next(1, 3);
        int xVelocity = random.Next(0, 101);
        int yVelocity = random.Next(0, 101);
        Vector2 tempVector2 = new Vector2(0,0);

        if (rightorleft == 1)
        {
            tempVector2 = new Vector2(xVelocity, tempVector2.Y);
        }

        else if (rightorleft == 2)
        {
            tempVector2 = new Vector2(-xVelocity, tempVector2.Y);
        }

        if (upordown == 1)
        {
            tempVector2 = new Vector2(tempVector2.X, -yVelocity);
        }

        else if (upordown == 2)
        {
            tempVector2 = new Vector2(tempVector2.X, yVelocity);
        }

        velocity = tempVector2;
        scale = random.Next(1, 11);
        upwardForce = -10;
        dead = false;
    }

    public FireParticle(xTile.Dimensions.Location StartLocation, ContentManager content, int seed)
    {
        worldLocation = StartLocation;
        fireParticleAnimation = new FireParticleAnimation(content);
        random = new Random(seed);

        int rightorleft = random.Next(0, 3);
        int upordown = random.Next(1, 3);
        int xVelocity = random.Next(0, 101);
        int yVelocity = random.Next(0, 101);
        Vector2 tempVector2 = new Vector2(0, 0);

        if (rightorleft == 1)
        {
            tempVector2 = new Vector2(xVelocity, tempVector2.Y);
        }

        else if (rightorleft == 2)
        {
            tempVector2 = new Vector2(-xVelocity, tempVector2.Y);
        }

        if (upordown == 1)
        {
            tempVector2 = new Vector2(tempVector2.X, -yVelocity);
        }

        else if (upordown == 2)
        {
            tempVector2 = new Vector2(tempVector2.X, yVelocity);
        }

        velocity = tempVector2;
        scale = random.Next(1, 11);
        upwardForce = -10;
        dead = false;
    }

    #endregion

    #region Update and Draw

    public void Update(GameTime gameTime)
    {
        elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

        fireParticleAnimation.Update(gameTime);

        Vector2 moveAmount = velocity * elapsed;

        xTile.Dimensions.Location newPosition = new xTile.Dimensions.Location(worldLocation.X + (int)moveAmount.X, worldLocation.Y + (int)moveAmount.Y);

        worldLocation = newPosition;

        velocity.Y += upwardForce;

        if (fireParticleAnimation.finishedPlaying)
        {
            dead = true;
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(
            fireParticleAnimation.image.Image,
            new Rectangle((int)drawLocation.X, (int)drawLocation.Y, scale, scale),
            fireParticleAnimation.image.SizeAndsource,
            Color.White * fireParticleAnimation.image.Alpha);
    }

Fireball explosion event:

    public override void Update(GameTime gameTime)
    {
        if (enabled)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            foreach (Heart_of_Fire.World_Objects.Particles.FireParticle particle in explosionParticles.ToList())
            {
                particle.Update(gameTime);

                if (particle.Dead)
                {
                    explosionParticles.Remove(particle);
                }
            }

            collisionRectangle = new Microsoft.Xna.Framework.Rectangle((int)wrldPstn.X, (int)wrldPstn.Y, 5, 5);

            explosionCheck = exploded;

            if (!exploded)
            {
                coreGraphic.Update(gameTime);
                tailGraphic.Update(gameTime);

                Vector2 moveAmount = velocity * elapsed;

                moveAmount = horizontalCollision(moveAmount, layer);
                moveAmount = verticalCollision(moveAmount, layer);

                Vector2 newPosition = new Vector2(wrldPstn.X + moveAmount.X, wrldPstn.Y + moveAmount.Y);

                if (hasCollidedHorizontally || hasCollidedVertically)
                {
                    exploded = true;
                }

                wrldPstn = newPosition;
                worldLocation = new xTile.Dimensions.Location((int)wrldPstn.X, (int)wrldPstn.Y);
            }

            if (explosionCheck != exploded)
            {
                for (int i = 0; i < 90; i++)
                {
                    explosionParticles.Add(new World_Objects.Particles.FireParticle(
                        new Location(
                            collisionRectangle.X + random.Next(0, 6),
                            collisionRectangle.Y + random.Next(0, 6)),
                            contentMgr));
                }
            }

            if (exploded && explosionParticles.Count() == 0)
            {
                //enabled = false;
            }
        }
    }

enter image description here

© Game Development or respective owner

Related posts about XNA

Related posts about 2d