Weird bullet issue...

Aug 28, 2009 at 5:55 PM

this probably isn't the best place to post this, seeing as it's probably a logic issue and not a farseer one, but creator's club seems to be down. so here goes.

right now i have a shotgun. it shoots 3 bullets at a time, in a random fashion, inside a 20 degree cone. so i have the following shoot method.

      public void Shoot(ContentManager Content, PhysicsSimulator physicsSimulator)
        {

            for (int i = 1; i <= PrimaryWeapon.BulletsPerShot; i++)
            {
                Random Spread = new Random();
             
                Bullet bullet = null;
                float Angle = ArmBody.Rotation;
                Angle += MathHelper.ToRadians(Spread.Next(-PrimaryWeapon.BulletSpread, PrimaryWeapon.BulletSpread));

                bool FoundDeadBullet = false;

                foreach (Bullet b in Bullets)
                {
                    if (FoundDeadBullet == false)
                    {
                        if (b.Alive == false)
                        {
                            FoundDeadBullet = true;

                            b.Body.ResetDynamics();

                            b.Body.Position = PrimaryWeapon.Body.GetWorldPosition(new Vector2(PrimaryWeapon.Sprite.Width, 0));
                            b.Tag = PlayerIndex;
                            b.Alive = true;
                            b.Body.Enabled = true;

                            b.Force = PrimaryWeapon.Force;

                            b.Body.Rotation = Angle;
                            b.Velocity = new Vector2((float)Math.Cos(b.Body.Rotation) * PrimaryWeapon.BulletSpeed, (float)Math.Sin(b.Body.Rotation) * PrimaryWeapon.BulletSpeed);
                            b.Body.LinearVelocity = b.Velocity;
                            b.Body.IgnoreGravity = true;
                            b.Geom.CollisionGroup = ArmGeom.CollisionGroup;

                            b.Geom.OnCollision += b.OnCollision;
                        }
                    }
                }
                if (FoundDeadBullet == false)
                {
                    bullet = new Bullet();

                    bullet.Load(Content, physicsSimulator);

                    bullet.Body.Position = PrimaryWeapon.Body.GetWorldPosition(new Vector2(PrimaryWeapon.Sprite.Width, 0));
                    bullet.Tag = PlayerIndex;
                    bullet.Alive = true;
                    bullet.Body.Enabled = true;

                    bullet.Force = PrimaryWeapon.Force;

                    bullet.Body.Rotation = Angle;
                    bullet.Velocity = new Vector2((float)Math.Cos(bullet.Body.Rotation) * PrimaryWeapon.BulletSpeed, (float)Math.Sin(bullet.Body.Rotation) * PrimaryWeapon.BulletSpeed);
                    bullet.Body.LinearVelocity = bullet.Velocity;
                    bullet.Body.IgnoreGravity = true;
                    bullet.Geom.CollisionGroup = ArmGeom.CollisionGroup;

                    bullet.Geom.OnCollision += bullet.OnCollision;

                    Bullets.Add(bullet);
                }
            }
        }

i know it's not exactly the cleanest code, but it's what i've got. basically, it just looks for a dead bullet. if it finds one, it recycles it. if it doesn't, it creates a new one.

the problem is that if the game recycles the bullets, it only shoots one. but if i put breakpoints in there, and i watch every step and every variable of the method, it shoots correctly.

could anybody maybe enlighten me to what might be occurring here? i know it's not quite farseer related, but it'd be a lot of help. thanks.

Aug 29, 2009 at 8:12 AM
Edited Aug 29, 2009 at 8:16 AM

 

So if you step through the code and it finds a dead bullet, it keeps getting through to make more?
Anyway, best i can figure is that somehow the "FoundDeadBullet" variable's value is leaking between loop runs, so maybe try this:

        public void Shoot(ContentManager Content, PhysicsSimulator physicsSimulator)
        {

            for (int i = 1; i <= PrimaryWeapon.BulletsPerShot; i++)
            {
                Random Spread = new Random();
             
                Bullet bullet = null;
                float Angle = ArmBody.Rotation;
                Angle += MathHelper.ToRadians(Spread.Next(-PrimaryWeapon.BulletSpread, PrimaryWeapon.BulletSpread));

                foreach (Bullet b in Bullets)
                {
                    if (bullet == null && b.Alive == false)
                    {
                        bullet = b;

                        b.Body.ResetDynamics();
                        
                        MakeBullet(b);
                    }
                }
                if (bullet == null)
                {
                    bullet = new Bullet();

                    bullet.Load(Content, physicsSimulator);
                    
                    MakeBullet(b);

                    Bullets.Add(bullet);
                }
            }
        }
        private static void MakeBullet(Bullet b)
        {
            b.Body.Position = PrimaryWeapon.Body.GetWorldPosition(new Vector2(PrimaryWeapon.Sprite.Width, 0));
            b.Tag = PlayerIndex;
            b.Alive = true;
            b.Body.Enabled = true;

            b.Force = PrimaryWeapon.Force;

            b.Body.Rotation = Angle;
            b.Velocity = new Vector2((float)Math.Cos(b.Body.Rotation) * PrimaryWeapon.BulletSpeed, (float)Math.Sin(b.Body.Rotation) * PrimaryWeapon.BulletSpeed);
            b.Body.LinearVelocity = b.Velocity;
            b.Body.IgnoreGravity = true;
            b.Geom.CollisionGroup = ArmGeom.CollisionGroup;

            b.Geom.OnCollision += b.OnCollision;
        }

(Plus, some free refactoring to clean up your code a tad)