精灵和产卵

时间:2012-03-07 06:15:58

标签: c# xna sprite

我有一艘正在产生精灵的船。有两种类型:轨道炮弹和导弹。导弹正常发射,但轨道炮弹总是在船前产生大约一百个像素(或者至少看起来如此)。我不确定为什么会这样。此外,有两个炮塔,当它从一个炮弹中射出时,它应该设置一个布尔值为真,使其从另一个炮弹中射出;当它从那个触发时,它将布尔值设置为false,依此类推。它总是从第一个发射出来。再一次,不知道为什么。我整天都在反对这个问题。这是我的代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
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.Media; 
using ShipBattle.Classes.Ships; 
using ShipBattle.Classes.Ships.Fighters; 
using ShipBattle.Classes.Ships.Projectiles; 
using ShipBattle.Classes.Ships.Projectiles.Tauri; 

namespace ShipBattle.Classes.Ships.Fighters 
{ 
    public class F302 : Ship 
    { 
        const double missileMinimumFiringArc = Utilities.NINETY_DEGREES / 2; 
        const double missileMaximumFiringArc = Utilities.NINETY_DEGREES + (Utilities.NINETY_DEGREES / 2); 
        const double railgunMinimumFiringArc = 1.5; 
        const double railgunMaximumFiringArc = 1.6; 
        const double MISSILES_ROF = 30.0; 

        protected List<double> CooldownLeft = new List<double>(); 
        private ContentManager content; 

        public event ShipFired WeaponFired; 
        public List<NaquadahEnhancedMissile> missiles; 
        public List<RailgunRound> railgunRounds; 
        public int[] MissileAmmo { get; set; } 
        public int[] RailgunAmmo { get; set; } 
        //Determines which missile/railgun to fire 
        bool leftMissile = true; 
        bool leftRailgun = true; 

        public F302(Vector2 position, ContentManager Content) 
        { 
            content = Content; 
            Texture = content.Load<Texture2D>(@"Textures\Ships\Tauri\Fighters\F302"); 
            Position = position; 
            Rotation = 0; 
            #region Physics Stuff 
            mass = 19200; 
            force = 76.3f; 

            acceleration = (force * 1000) / mass; 
            maxSpeed = Utilities.GetVelocity(acceleration); 
            #endregion 
            #region Hull & Shielding 
            HullIntegrity = 10; 
            ShieldStrength = 0; 
            #endregion 
            #region Weapons!!! 
            /*
             * [0] = Port Missile
             * [1] = Starboard Missile
             * [2] = Port Railgun
             * [3] = Starboard Railgun
             */ 

            //Setup 
            missiles = new List<NaquadahEnhancedMissile>(); 
            railgunRounds = new List<RailgunRound>(); 
            MissileAmmo = new int[2]; 
            RailgunAmmo = new int[2]; 

            //Port Missile 
            WeaponRatesOfFire.Add(MISSILES_ROF); 
            CooldownLeft.Add(0); 
            WeaponsEnplacements.Add(new Vector2(14, 5)); 
            WeaponEmplacementOffsets.Add(new Vector2(14, 5)); 
            MissileAmmo[0] = 2; 

            //Starboard Missile 
            WeaponRatesOfFire.Add(MISSILES_ROF); 
            CooldownLeft.Add(0); 
            WeaponsEnplacements.Add(new Vector2(35, 5)); 
            WeaponEmplacementOffsets.Add(new Vector2(35, 5)); 
            MissileAmmo[1] = 2; 

            //Port Railgun 
            WeaponRatesOfFire.Add(7.2); 
            CooldownLeft.Add(0); 
            WeaponsEnplacements.Add(new Vector2(24, 0)); 
            WeaponEmplacementOffsets.Add(new Vector2(24, 0)); 
            RailgunAmmo[0] = 10000; 

            //Starboard Railgun 
            WeaponRatesOfFire.Add(7.2); 
            CooldownLeft.Add(0); 
            WeaponsEnplacements.Add(new Vector2(26, 0)); 
            WeaponEmplacementOffsets.Add(new Vector2(26, 0)); 
            RailgunAmmo[1] = 10000; 
            #endregion 
        } 

        protected override void UpdateProjectiles(Vector2 pos) 
        { 
            for (int i = 0; i < missiles.Count; i++) 
                if (missiles[i].Remove) 
                    missiles.RemoveAt(i); 

            for (int i = 0; i < railgunRounds.Count; i++) 
                if (railgunRounds[i].Remove) 
                    railgunRounds.RemoveAt(i); 

            foreach (NaquadahEnhancedMissile nem in missiles) 
                nem.Update(enemyPos); 

            foreach (RailgunRound rr in railgunRounds) 
                rr.Update(enemyPos); 
        } 

        protected override void DrawProjectiles(SpriteBatch spriteBatch) 
        { 
            foreach (NaquadahEnhancedMissile nem in missiles) 
                nem.Draw(spriteBatch); 

            foreach (RailgunRound rr in railgunRounds) 
                rr.Draw(spriteBatch); 
        } 

        protected override void CheckTarget(Ship target) 
        { 
            enemyPos = target.Position; 
            double distance = Vector2.Distance(Position, target.Position); 

            Vector2 vector1 = Vector2.Normalize(Position - target.Position); 
            Vector2 vector2 = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation)); 

            double angle = Math.Acos(Vector2.Dot(vector1, vector2)); 

            if (angle > missileMinimumFiringArc && angle < missileMaximumFiringArc) 
                if (distance < 500) 
                    if (((target.HullIntegrity + target.ShieldStrength) - 10) <= 0) 
                        FireMissiles(); 

            if (angle > railgunMinimumFiringArc && angle < railgunMaximumFiringArc) 
                FireRailguns(); 
        } 

        protected void FireMissiles() 
        { 
            if (leftMissile) 
            { 
                if (CooldownLeft[0] <= 0) 
                { 
                    if (MissileAmmo[0] > 0) 
                    { 
                        NaquadahEnhancedMissile nem = new NaquadahEnhancedMissile(WeaponsEnplacements[0], Rotation, content); 
                        nem.hit += new ProjectileHit(nem_hit); 
                        missiles.Add(nem); 
                        CooldownLeft[0] = WeaponRatesOfFire[0]; 
                        CooldownLeft[1] = WeaponRatesOfFire[1]; 
                        MissileAmmo[0]--; 
                        leftMissile = false; 
                    } 
                } 
            } 
            else 
                if (CooldownLeft[1] <= 0) 
                { 
                    if (MissileAmmo[1] > 0) 
                    { 
                        NaquadahEnhancedMissile nem = new NaquadahEnhancedMissile(WeaponsEnplacements[1], Rotation, content); 
                        nem.hit += new ProjectileHit(nem_hit); 
                        missiles.Add(nem); 
                        CooldownLeft[0] = WeaponRatesOfFire[0]; 
                        CooldownLeft[1] = WeaponRatesOfFire[1]; 
                        MissileAmmo[1]--; 
                        leftMissile = true; 
                    } 
                } 
        } 

        private void FireRailguns() 
        { 
            if (leftRailgun) 
            { 
                if (CooldownLeft[2] <= 0) 
                { 
                    if (RailgunAmmo[0] > 0) 
                    { 
                        RailgunRound rgr = new RailgunRound(WeaponsEnplacements[2], Rotation, content); 
                        rgr.hit += new ProjectileHit(nem_hit); 
                        railgunRounds.Add(rgr); 
                        CooldownLeft[2] = WeaponRatesOfFire[2]; 
                        CooldownLeft[3] = WeaponRatesOfFire[3]; 
                        RailgunAmmo[0]--; 
                        leftRailgun = false; 
                    } 
                } 
            } 
            else 
                if (CooldownLeft[3] <= 0) 
                { 
                    if (RailgunAmmo[1] > 0) 
                    { 
                        RailgunRound rgr = new RailgunRound(WeaponsEnplacements[3], Rotation, content); 
                        rgr.hit += new ProjectileHit(nem_hit); 
                        railgunRounds.Add(rgr); 
                        CooldownLeft[2] = WeaponRatesOfFire[2]; 
                        CooldownLeft[3] = WeaponRatesOfFire[3]; 
                        MissileAmmo[1]--; 
                        leftRailgun = true; 
                    } 
                } 

        } 

        protected override void Cooldown() 
        { 
            for (int f = 0; f < CooldownLeft.Count; f++) 
                CooldownLeft[f]--; 
        } 

        private void nem_hit(Projectile p, EventArgs e) 
        { 
            if (p is NaquadahEnhancedMissile) 
            { 
                p.Remove = true; 

                if (targetShip.ShieldStrength > 0) 
                    targetShip.ShieldStrength -= p.Damage; 
                else 
                    targetShip.HullIntegrity -= p.Damage; 

            } 
            else if (p is RailgunRound) 
            { 
                p.Remove = true; 

                if (targetShip.ShieldStrength > 0) 
                    targetShip.ShieldStrength -= p.Damage / 4; 
                else 
                    targetShip.HullIntegrity -= p.Damage; 

            } 
        } 

        protected override void CleanupProjectiles() 
        { 
            missiles.Clear(); 
            railgunRounds.Clear(); 
        } 
    } 
} 

以下是这个全部继承自的船类的代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using ShipBattle.Classes.Ships.Projectiles; 
using ShipBattle.Classes.Ships.Projectiles.Tauri; 

namespace ShipBattle.Classes.Ships 
{ 
    public abstract class Ship 
    { 
        public Texture2D Texture { get; set; } 
        public Vector2 Position 
        { 
            get 
            { 
                return _position; 
            } 
            set 
            { 
                _position = value; 
            } 
        } 
        public float Rotation { get; set; } 

        private Vector2 _position; 

        protected Ship targetShip; 
        protected Vector2 enemyPos; 
        #region Health & Shielding 
        public float HullIntegrity { get; set; } 
        public float ShieldStrength { get; set; } 
        public bool Remove { get; set; } 
        #endregion 
        #region Guns 
        protected List<Vector2> WeaponsEnplacements = new List<Vector2>(); 
        protected List<Vector2> WeaponEmplacementOffsets = new List<Vector2>(); 
        protected List<double> WeaponRatesOfFire = new List<double>(); 
        /// <summary> 
        /// The rates of fire for all weapons, represented in terms of the delay between frames 
        /// </summary> 
        #endregion 
        #region Targeting Logic 
        bool hasTarget = false; 
        protected int targetHashCode; 
        Vector2 targetShipPosition; 
        Ship target; 
        bool evasive = false; 
        bool hasRandomTrajectory = false; 
        bool reachedBounds = false; 
        bool followingRandom = false; 
        int timeToFaffAbout = 360; 
        double randomRotation; 
        #endregion 
        #region Physics Stuff 
        float angleA, b, a, speed = 0; 
        double turningRadius = 10 * (Math.PI / 180); 

        //Acceleration 
        protected int mass; // kg 
        protected float force; // kN, thruster power 
        protected float acceleration; // m/s^2 

        //Velocity 
        protected float maxSpeed; // m/s, calculated using 30-second burn 
        protected float initialSpeed = 0; 
        protected float finalSpeed = 0; 
        protected float time = 0.016666f; 
        #endregion 

        public void Update(List<Ship> ships) 
        { 
            if (timeToFaffAbout >= 0) 
            { 
                timeToFaffAbout = 360; 
                followingRandom = false; 
            } 

            if (!hasTarget) 
            { 
                targetShip = GetTarget(ships); 
                hasTarget = true; 
            } 
            else 
            { 
                if (targetShip != null) 
                { 
                    if (Vector2.Distance(Position, targetShip.Position) < 75) 
                        evasive = true; 
                    else 
                        evasive = false; 

                    if (evasive) 
                    { 
                        if (!hasRandomTrajectory) 
                        { 
                            Random random = new Random(); 

                            randomRotation = random.Next((int)(Math.PI * 100)); 
                            double negative = random.Next(2); 
                            if (negative == 1) 
                                randomRotation *= -1; 

                            Rotation = (float)randomRotation; 
                            hasRandomTrajectory = true; 
                        } 
                    } 
                    else 
                    { 
                        if (!followingRandom) 
                        { 
                            //Rotate the sprite using the turning radius 
                            Rotation = Utilities.TurnToFace(Position, new Vector2(targetShip.Position.X, targetShip.Position.Y), (float)Rotation, (float)turningRadius); 
                        } 
                    } 

                    KeepOnTheScreen(); 

                    //Move the sprite, using KINEMATIC PHYSICS, ***!!! -->goes in the direction set by the rotation algorithm 
                    Move(); 

                    CheckTarget(targetShip); 
                    UpdateProjectiles(targetShip.Position); 

                    //Stop targeting a dead enemy 
                    if (targetShip.HullIntegrity <= 0) 
                        hasTarget = false; 

                } 
            } 

            //Recalculate the List<Vector2> weapons enplacements based on the current rotation angle 
            RecalculateWeaponsPositions(); 

            //Cooldown the guns 
            Cooldown(); 
        } 

        public void Draw(SpriteBatch spriteBatch) 
        { 
            spriteBatch.Draw(Texture, Position, null, Color.White, Rotation, new Vector2(Texture.Width / 2, Texture.Height / 2), 0.5f, 
                SpriteEffects.None, 0.0f); 

            if (hasTarget) 
                DrawProjectiles(spriteBatch); 
        } 

        /// <summary> 
        /// Uses trig and the thruster power to move the ship. b is the y distance to move, a is the x distance to move 
        /// </summary> 
        private void Move() 
        { 
            if (finalSpeed < maxSpeed) 
                finalSpeed = speed + (acceleration * time); 

            angleA = Rotation; 

            b = (float)Math.Cos(angleA) * finalSpeed; 
            a = (float)Math.Sin(angleA) * finalSpeed; 

            _position.Y -= b; 
            _position.X += a; 

            speed = finalSpeed; 
        } 

        /// <summary> 
        /// Acquires the closes enemy ship 
        /// </summary> 
        /// <param name="ships">The ships to search through</param> 
        /// <returns></returns> 
        private Ship GetTarget(List<Ship> ships) 
        { 
            CleanupProjectiles(); 
            Ship rVal = null; 
            int distance = int.MaxValue; 
            float c; 

            foreach (Ship ship in ships) 
            { 
                c = Vector2.Distance(Position, ship.Position); 

                if (c < distance) 
                    rVal = ship; 
            } 

            return rVal; 
        } 

        /// <summary> 
        /// Reorients the positions of all the weapon positions on this ship 
        /// </summary> 
        private void RecalculateWeaponsPositions() 
        { 
            for (int i = 0; i < WeaponsEnplacements.Count; i++) 
            { 
                WeaponsEnplacements[i] = RotateWeapons(WeaponEmplacementOffsets[i]); 
            } 
        } 

        /// <summary> 
        /// Recalculates the positions of the weapons on this ship based off their default offset and the current angle 
        /// </summary> 
        /// <param name="weapon">The weapon position to recalculate</param> 
        /// <param name="offset">The default offset of that weapon</param> 
        private Vector2 RotateWeapons(Vector2 offset) 
        { 
            Quaternion rotation = Quaternion.CreateFromAxisAngle(Vector3.Backward, (float)Rotation); 
            return Vector2.Transform(offset, rotation) + Position; 
        } 

        /// <summary> 
        /// Keeps the ship on the screen 
        /// </summary> 
        private void KeepOnTheScreen() 
        { 
            if (Position.X > 1019 || Position.X < 5 || Position.Y > 761 || Position.Y < 5) 
                reachedBounds = true; 
            else 
                reachedBounds = false; 

            if (reachedBounds) 
            { 
                followingRandom = true; 

                if (!followingRandom) 
                    Rotation = Utilities.TurnToFace(Position, new Vector2(1024 / 2, 768 / 2), Rotation, (float)turningRadius); 
                else 
                    timeToFaffAbout--; 

            } 
        } 

        /// <summary> 
        /// Checks to see if the target ship is within weapons range 
        /// </summary> 
        /// <param name="target"></param> 
        protected abstract void CheckTarget(Ship target); 

        /// <summary> 
        /// Decrements the cooldown of all weapons 
        /// </summary> 
        protected abstract void Cooldown(); 
        protected abstract void UpdateProjectiles(Vector2 pos); 
        protected abstract void DrawProjectiles(SpriteBatch spriteBatch); 
        protected abstract void CleanupProjectiles(); 
    } 
} 

如果有人能帮助我,我会非常感激。谢谢!

1 个答案:

答案 0 :(得分:0)

为什么FireRailguns()执行MissileAmmo [1] - ; ?