当敌人进攻时他不能死

时间:2016-05-27 08:44:05

标签: c# monogame

我在Monogame中制作了一个平台游戏,在那里我有敌人可以制造攻击框架但是如果我试图杀死它,它会卡在框架中而不能死亡。

这是我的Game1代码:

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.Graphics;
using Microsoft.Xna.Framework.Input;

namespace TreasureHunt
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {

        int enemyLives = 2;
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SoundEffect aj;
        SoundEffect collect;
        Texture2D coinCount;

        int screenWidth = 1024;
        int screenHeight = 768;

        //int enemyLives = 2;
        //Vector2 temp = new Vector2 (1000, 600);

        Pirate player;

        List<EnemyPirate> argh = new List<EnemyPirate>();
        List<Coin> coin = new List<Coin>();
        bool firstPirateArmy = true;

        Level map;
        Vector2 dist;
        Vector2 coindist;
        Background backGround;
        int collectedCoins;
        SpriteFont inGameFont;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = screenWidth;
            graphics.PreferredBackBufferHeight = screenHeight;
            graphics.IsFullScreen = false;
            Window.Title = "TreasureHunt";
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            map = new Level (screenWidth, screenHeight);
            map.LoadMap (Content, 1);
            backGround = new Background(screenWidth, (int)(Level.GetWorldSize().X * Level.GetTileSize()), 1, Content);

            player = new Pirate(screenWidth, screenHeight, Content, graphics.GraphicsDevice);

            argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(400, 400), enemyLives));
            argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(1600, 420), enemyLives));
            argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(3800, 600), enemyLives));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (505, 278)));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (1100, 25)));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (890, 660)));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (1720, 660)));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (2348, 410)));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (2850, 150)));
            coin.Add (new Coin (screenWidth, screenHeight, Content, new Vector2 (2950, 660)));

            base.Initialize();
        }


        private void ResetPirates()
        {
            if(firstPirateArmy)
            {
                argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(1000, 500), enemyLives));
                argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(1500, 50), enemyLives));
                argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(3700, 200), enemyLives));
                firstPirateArmy = false;
            }
            else
            {
                argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(400, 400), enemyLives));
                argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(1600, 420), enemyLives));
                argh.Add(new EnemyPirate(screenWidth, screenHeight, Content, new Vector2(3800, 600), enemyLives));
                firstPirateArmy = true;
            }
        }


        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            inGameFont = Content.Load<SpriteFont>("inGameFont");
            aj = Content.Load<SoundEffect> ("AjLjud");
            collect = Content.Load<SoundEffect> ("Collecting1");
            coinCount = Content.Load<Texture2D> ("Coin");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            player.Update (gameTime);
            for (int i = 0; i < coin.Count (); i++) {

                coin [i].Update (gameTime);
                coindist = (coin [i].GetPosition () - player.GetPosition ());

                if (coindist.Length () < 60) {
                    collect.Play ();
                    coin.RemoveAt (i);
                    collectedCoins++;
                }
            }  

            for (int i = 0; i < argh.Count (); i++) {
                dist = (argh [i].GetPosition () - player.GetPosition ());

                if (dist.Length () < 100) {
                    argh [i].Attack ();//.currentState = EnemyPirate.figureState.hitting;
                    player.playerLives--;    
                }      
            }

            for (int i = 0; i < argh.Count(); i++)
            {
                argh[i].Update(gameTime);
                if (player.HasHitEnemy(argh[i].GetBoundingBox()))
                {
                    argh [i].enemyLives--;
                    aj.Play ();
                    argh [i].hurt = true;
                    if (argh [i].enemyLives <= 0) {
                        argh [i].currentState = EnemyPirate.figureState.predie;
                        argh [i].EnemyIsDead ();
                        //if(argh[i].dead)

                        //argh.RemoveAt (i);
                    }

                    if (argh.Count() == 0)
                        ResetPirates();
                }
                if (argh [i].currentState == EnemyPirate.figureState.died)
                    argh.RemoveAt (i);                  

            }

            map.UpdateCamera(player.GetPosition());
            backGround.Update ();

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin (SpriteSortMode.Deferred,
                null,
                SamplerState.PointClamp,
                null,
                null);

            backGround.Draw (spriteBatch);
            map.Draw (spriteBatch);

            foreach (EnemyPirate c in argh)
                c.Draw (spriteBatch);    

            foreach (Coin c in coin)
                c.Draw (spriteBatch);    

            player.Draw (spriteBatch);

            //spriteBatch.DrawString(inGameFont, "speed.Y:" + player.position.Y, new Vector2(20, 20), Color.White);
            spriteBatch.DrawString(inGameFont, "R = Reset", new Vector2(20, 20), Color.White);
            spriteBatch.DrawString(inGameFont, "dist: "+dist.Length()+" "+player.playerLives, new Vector2(20, 40), Color.White);
            spriteBatch.DrawString(inGameFont, ": " + collectedCoins, new Vector2(55, 70), Color.White);
            spriteBatch.Draw (coinCount, new Vector2 (20, 60), Color.White);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

这是我的敌人代码:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace TreasureHunt
{
    public class EnemyPirate : PlatformerFigure
    {

        public int enemyLives = 2;
        int animWalk = 0;
        int animHit = 6;
        int animPreDie = 9;
    //  int animDie = 10;
        public figureState currentState;
        public bool dead;
        public bool hurt;
        public const float _delay = 3; // seconds
        public float _remainingDelay = _delay;

        public enum figureState            // Alla olika stadier figuren kan befinna sig i
        {
            standing,
            walking,
            jumping,
            predie,
            die,
            died,
            hitting
        }

        public EnemyPirate (int screenWidth, int screenHeight, ContentManager contMan, Vector2 position, int Lives)
        {
            this.screenWidth = screenWidth;
            this.screenHeight = screenHeight;
            LoadMedia(contMan);
            enemyLives = Lives;

            animSequence = new int[]{ 1, 2, 3, 4, 5, 0, 7, 8, 0, 10, 11, 11 };

            SetBoundingBox (new Rectangle (10, 15, 63, 81));    

            Reset ();
            this.position = position;    
        }

        public void Reset()
        {
            Facing = AnimatedObject.direction.left;
            SetFrame(animWalk);
            currentState = figureState.standing;
            maxSpeed = new Vector2(1f, 6);
            //position = new Vector2(1600, 400);   // Behövs inte när man skickar in en position till konstruktorn.
            speed = Vector2.Zero;
            slipperyK = 1;
            acc = Vector2.Zero;                   // Från början står figuren still.
            walkAcc = 1f;
            primaryColor = Color.White;
            alpha = 1;
        }


        private void LoadMedia(ContentManager content)
        {
            gfx = content.Load<Texture2D>("EnemyPirate2");

            AnimationSettings(96, 96, 110, direction.right, 12);
        }

        public override bool Update(GameTime gameTime)
        {
            var timer = (float) gameTime.ElapsedGameTime.TotalSeconds;
            Think();
            Move(gameTime);
            UpdateAnimation(gameTime);
            GroundCollision();
            if (currentState == figureState.hitting && currentFrame == 0)
                currentState = figureState.standing;
        //  else if (enemyLives <= 0)
            //  currentState = figureState.predie;

            if (currentState == figureState.predie) {
                _remainingDelay -= timer;
                if (_remainingDelay < 2) {
                    alpha -= 0.04f;
                    if (alpha < 0)
                        alpha = 0;
                }
            }

            if (_remainingDelay <= 0)
                currentState = figureState.died;

            return true;
        }

        private void Think()
        {
            if (Facing == direction.left)
            {
                acc.X = -walkAcc;
                if (WallCollision(new Vector2(-10,0)) || !GroundAhead())
                {
                    Facing = direction.right;
                    acc.X = walkAcc;
                }
            }
            else
            {
                acc.X = walkAcc;
                if (WallCollision(new Vector2(10,0)) || !GroundAhead())
                {
                    Facing = direction.left;
                    acc.X = -walkAcc;
                }
            }
        }

        private bool GroundAhead()
        {
            Vector2 ahead = position + pos_feet;        // Vart finns figurens fötter?
            if (Facing == direction.left)
                ahead += new Vector2(-10, 0);           // Tittar lite till vänster om figuren
            else
                ahead += new Vector2(10, 0);            // Tittar lite till höger om figuren

            int tile = Level.GetTile(ahead);

            if (tile > 44 && tile < 77 || tile > 84 && tile < 104)
                return true;

            return false;
        }

        public void EnemyIsDead ()
        {               
            if (currentState == figureState.predie)
                SetFrame (animPreDie);
                acc = Vector2.Zero;
                walkAcc = 0;
                dead = true;   
        }

        public void Hurted()
        {
            if (hurt) {
                var pos = position.X;
                while(position.X < pos-5){
                    position = new Vector2 (position.X, 0);
                }       
            }    
        }

        public void Attack()
        {
            if (currentState != figureState.hitting) {
                SetFrame (animHit);
                currentState = figureState.hitting;
            }   
        }    
    }
}

1 个答案:

答案 0 :(得分:1)

代码太多了。您没有AssertsExceptions。使你的代码变得非常脆弱,这样如果出现错误,它将停止并提醒你修复它。

例如。在Argh.Attack()内部,断言currentState尚未死亡。