Спрайты и Нерест - PullRequest
       25

Спрайты и Нерест

0 голосов
/ 07 марта 2012

У меня есть корабль, который порождает спрайтов.Есть два типа: рельсовые снаряды и ракеты.Ракеты запускаются правильно, но снаряды из рельсовых орудий всегда появляются на расстоянии около ста пикселей перед кораблем (или, по крайней мере, кажется).Я не уверен, почему это происходит.Кроме того, есть две башни, когда она запускается из одной, она должна установить логическое значение в true, чтобы она запускалась из другой;когда он срабатывает, он устанавливает логическое значение обратно в 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 голосов
/ 29 марта 2012

Почему FireRailguns () выполняет MissileAmmo [1] -;

...