Search code examples
c#physicsmonogameparticle-system

Trying to make a simple Euler Formula


https://gamedev.stackexchange.com/questions/13178/why-is-my-velocity-decaying

I was using the suggested answer in that thread to try a basic physics formula for my particle system. For some reason though it doesn't even move my particles at all anymore. Can someone better with math then me take a look and make sure I'm doing the formula right? This stuff goes over my head but I wanted to apply some gravity to my particles.

Particle.cs

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Game1
{
    public class Particle
    {
        public Texture2D Texture { get; set; }
        public Vector2 Position { get; set; }
        public Vector2 Velocity { get; set; }
        public float Mass = 1.0f;
        public Vector2 Acceleration { get; set; }
        public float Angle { get; set; }
        public float AngularVelocity { get; set; }
        public Color Color { get; set; }
        public float Size { get; set; }
        public int TTL { get; set; } //Time to live

        public Particle(Texture2D texture, Vector2 position, Vector2 velocity, Vector2 acceleration, float angle, float angularVelocity, Color color, float size, int ttl)
        {
            Texture = texture;
            Position = position;
            Velocity = velocity;
            Acceleration = acceleration;
            Angle = angle;
            AngularVelocity = angularVelocity;
            Color = color;
            Size = size;
            TTL = ttl;
        }

        public void Update(GameTime gameTime)
        {
            var dt = gameTime.ElapsedGameTime.TotalSeconds;

            TTL--;
            var t = Vector2.Multiply(Velocity, (float)dt);
            var r = Vector2.Multiply(Acceleration, 0.5f);
            var q = Vector2.Multiply(t + r, (float)dt);
            var f = Vector2.Multiply(q, (float)dt);

            Position += f;
            Velocity += Vector2.Multiply(Acceleration, (float)dt);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            Rectangle sourceRectangle = new Rectangle(0, 0, Texture.Width, Texture.Height);
            Vector2 origin = new Vector2(Texture.Width / 2, Texture.Height / 2);
            spriteBatch.Draw(Texture, Position, sourceRectangle, Color, Angle, origin, Size, SpriteEffects.None, 0f);
        }
    }
}

Creation of particles

private Particle GenerateNewParticle(GameTime gameTime)
        {
            Texture2D texture = textures[random.Next(textures.Count)];
            Vector2 position = EmitterLocation;

            Vector2 velocity = new Vector2(1f * (float)(random.NextDouble() * 2 - 1), (1f * (float)(random.NextDouble() * 2 - 1)));
            Vector2 acceleration = new Vector2(20f, 20f);
            float angle = 0;
            float angularVelocity = 0.1f * (float)(random.NextDouble() * 2 - 1);
            Color color = new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
            float size = (float)random.NextDouble();
            int ttl = 20 + random.Next(40);

            return new Particle(texture, position, velocity, acceleration, angle, angularVelocity, color, size, ttl);
        }

Solution

  • It looks like you got the q term incorrect. Operator precedence will do the multiplies first, then the additions. To implement the equations you referenced,

    q should be Vector2.Multiply(r, (float)dt);

    Then your update to Position needs to become Position += (t+f);