XNA 4.0敌人产卵,弹掉墙壁

时间:2014-02-15 18:18:19

标签: c# xna bounce spawning

对所有代码感到抱歉,但我对Visual C#和XNA完全不熟悉。

该程序不属于Aaron Reed的学习XNA 4.0。我的教授修改了它应该做的一些东西(这本书涵盖了一些但不是全部)。大多数代码都是从书中复制的。

这些是成品的最低要求:

  1. 您可以使用任意2个图像代替3个戒指和骷髅球(或者如果您愿意,您仍然可以使用相同的) - 一个是玩家(3个戒指)而另一个是参与者(也称为敌人)
  2. 玩家精灵只能使用箭头键(鼠标未激活)
  3. 移动
  4. 参与者的精灵是自动化的,他们可以自由移动(如果你愿意的话随机移动)并且他们会跳出界限(以你选择的任何方式)
  5. 游戏开始时有1位玩家和5位参与者精灵
  6. 游戏持续正好120秒,在游戏结束时,如果玩家精灵已经摧毁了屏幕上的所有参与者(敌人精灵),则会打印一条消息,指示玩家获胜;否则打印播放器丢失的消息
  7. 每10秒就有一个敌人精灵的新化身出现在任何地方
  8. 玩家精灵只有在碰撞时才会摧毁敌人精灵并且同时按下“A”键。如果在没有碰撞的情况下按下“A”键,则会发生2个敌人的化身
  9. 敌人的精灵必须以合理的速度移动(我的意思不是很慢)才能让游戏变得有意义
  10. 你需要在你的程序中有一些声音 - 一个总是播放的背景声音,一个在敌人被摧毁时播放的声音,当玩家发射时不同的声音但是敌人因为没有碰撞而没有被摧毁,新敌人出现时的声音(每10秒钟)
  11. 我试图让敌人(骷髅球)躲避玩家(骚扰),但敌人要么四面都没有反应(玩家在右边或左边,敌人不会逃避直到玩家当敌人躲避时,它们会在屏幕外抖动消失(它们突然直接向上或向下移动,并且它们会迅速摇晃。

    当新敌人从左上角开始10秒后产生时,它从底部墙壁反弹,然后在它重新上升时从屏幕上消失。

    10秒钟后,颅骨也不会在屏幕周围随机产生。

    此外,我不知道如何在没有碰撞的情况下按下A按钮时再产生2个敌人。

    SpriteManager.cs

    namespace Assignment_2
    {
        public class SpriteManager : Microsoft.Xna.Framework.DrawableGameComponent
        {
            //SpriteBatch for drawing
            SpriteBatch spriteBatch;
    
            //A sprite for the player and a list of automated sprites
            UserControlledSprite player;
            List<Sprite> spriteList = new List<Sprite>();
    
            int enemySpawnMinMilliseconds = 10000;
            int enemySpawnMaxMilliseconds = 10000;
            int enemyMinSpeed = 10;
            int enemyMaxSpeed = 10;
            int nextSpawnTime = 0;
    
            public SpriteManager(Game game)
                : base(game)
            {
                // TODO: Construct any child components here
            }
    
            public override void Initialize()
            {
                // TODO: Add your initialization code here
                ResetSpawnTime();
                base.Initialize();
            }
    
            protected override void LoadContent()
            {
                spriteBatch = new SpriteBatch(Game.GraphicsDevice);
    
                //Load the player sprite
                player = new UserControlledSprite(
                    Game.Content.Load<Texture2D>(@"Images/threerings"),
                    Vector2.Zero, new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(6, 6));
    
                //Load several different automated sprites into the list to test
                //spriteList.Add(new AutomatedSprite(
                //    Game.Content.Load<Texture2D>(@"Images/skullball"),
                //    new Vector2(150, 150), new Point(75, 75), 10, new Point(0, 0),
                //    new Point(6, 8), new Vector2(3, 0), "skullcollision"));
                //spriteList.Add(new AutomatedSprite(
                //    Game.Content.Load<Texture2D>(@"Images/skullball"),
                //    new Vector2(300, 150), new Point(75, 75), 10, new Point(0, 0),
                //    new Point(6, 8), new Vector2(-2, 0), "skullcollision"));
                ////spriteList.Add(new AutomatedSprite(
                ////    Game.Content.Load<Texture2D>(@"Images/skullball"),
                ////    new Vector2(150, 300), new Point(75, 75), 10, new Point(0, 0),
                ////    new Point(6, 8), new Vector2(3, 4), "skullcollision"));
                ////spriteList.Add(new AutomatedSprite(
                ////    Game.Content.Load<Texture2D>(@"Images/skullball"),
                ////    new Vector2(300, 400), new Point(75, 75), 10, new Point(0, 0),
                ////    new Point(6, 8), new Vector2(0, -3), "skullcollision"));
                ////spriteList.Add(new AutomatedSprite(
                ////    Game.Content.Load<Texture2D>(@"Images/skullball"),
                ////    new Vector2(200, 300), new Point(75, 75), 10, new Point(0, 0),
                ////    new Point(6, 8), new Vector2(-3, 7), "skullcollision"));
                spriteList.Add(new EvadingSprite(
                    Game.Content.Load<Texture2D>(@"Images/skullball"),
                    new Vector2(150, 150), new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(3, 0), "skullcollision", this, .75f, 150));
                spriteList.Add(new EvadingSprite(
                    Game.Content.Load<Texture2D>(@"Images/skullball"),
                    new Vector2(300, 150), new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(-2, 0), "skullcollision", this, .75f, 150));
                spriteList.Add(new EvadingSprite(
                    Game.Content.Load<Texture2D>(@"Images/skullball"),
                    new Vector2(150, 300), new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(3, 4), "skullcollision", this, .75f, 150));
                spriteList.Add(new EvadingSprite(
                    Game.Content.Load<Texture2D>(@"Images/skullball"),
                    new Vector2(300, 400), new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(0, -3), "skullcollision", this, .75f, 150));
                spriteList.Add(new EvadingSprite(
                    Game.Content.Load<Texture2D>(@"Images/skullball"),
                    new Vector2(200, 300), new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(-3, 7), "skullcollision", this, .75f, 150));
                base.LoadContent();
            }
    
            public override void Update(GameTime gameTime)
            {
                nextSpawnTime -= gameTime.ElapsedGameTime.Milliseconds;
                if (nextSpawnTime < 0)
                {
                    SpawnEnemy();
    
                    //reset spawn timer
                    ResetSpawnTime();
                }
                // Update player
                player.Update(gameTime, Game.Window.ClientBounds);
    
                // Update all sprites
                for (int i = 0; i < spriteList.Count; ++i)
                {
                    Sprite s = spriteList[i];
    
                    s.Update(gameTime, Game.Window.ClientBounds);
    
                    // Check for collisions
                    if (s.collisionRect.Intersects(player.collisionRect) && (Keyboard.GetState().IsKeyDown(Keys.A)))
                    {
                        // Play collision sound
                        if (s.collisionCueName != null)
                            ((Game1)Game).PlayCue(s.collisionCueName);
    
                        // Remove collided sprite from the game
                        spriteList.RemoveAt(i);
                        --i;
                    }
                }
    
                base.Update(gameTime);
            }
    
            public override void Draw(GameTime gameTime)
            {
                spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
    
                // Draw the player
                player.Draw(gameTime, spriteBatch);
    
                // Draw all sprites
                foreach (Sprite s in spriteList)
                    s.Draw(gameTime, spriteBatch);
    
                spriteBatch.End();
                base.Draw(gameTime);
            }
            // Return current position of the player sprite
            public Vector2 GetPlayerPosition()
            {
                return player.GetPosition;
            }
    
            private void SpawnEnemy()
            {
                Vector2 speed = Vector2.Zero;
                Vector2 position = Vector2.Zero;
    
                // Default frame size
                Point frameSize = new Point(75, 75);
                // Create the sprite. NOTE: This sprite bounces off the bottom wall then goes back and disappears offscreen
                spriteList.Add(
                    new EvadingSprite(Game.Content.Load<Texture2D>(@"images\skullball"),
                    position, new Point(75, 75), 10, new Point(0, 0),
                    new Point(6, 8), new Vector2(3, 4), "skullcollision", this, .75f, 150)); 
    
            }
    
             private void ResetSpawnTime()
             {
                 nextSpawnTime = ((Game1)Game).rnd.Next(
                 enemySpawnMinMilliseconds,
                 enemySpawnMaxMilliseconds);
             }
        }
    }
    

    EvadingSprite

    class EvadingSprite : Sprite
    {
        // Save a reference to the sprite manager to
        // use to get the player position
        SpriteManager spriteManager;
    
        // Variables to delay evasion until player is close 
        float evasionSpeedModifier;
        int evasionRange;
        bool evade = false;
    
        public EvadingSprite(Texture2D textureImage, Vector2 position,
            Point frameSize, int collisionOffset, Point currentFrame,
            Point sheetSize, Vector2 speed, string collisionCueName,
            SpriteManager spriteManager, float evasionSpeedModifier,
            int evasionRange)
            : base(textureImage, position, frameSize, collisionOffset,
            currentFrame, sheetSize, speed, collisionCueName)
        {
            this.spriteManager = spriteManager;
            this.evasionSpeedModifier = evasionSpeedModifier;
            this.evasionRange = evasionRange;
        }
    
        public EvadingSprite(Texture2D textureImage, Vector2 position,
            Point frameSize, int collisionOffset, Point currentFrame,
            Point sheetSize, Vector2 speed, int millisecondsPerFrame,
            string collisionCueName, SpriteManager spriteManager,
            float evasionSpeedModifier, int evasionRange)
            : base(textureImage, position, frameSize, collisionOffset,
            currentFrame, sheetSize, speed, millisecondsPerFrame,
            collisionCueName)
        {
            this.spriteManager = spriteManager;
            this.evasionSpeedModifier = evasionSpeedModifier;
            this.evasionRange = evasionRange;
        }
    
        public override Vector2 direction
        {
            get { return speed; }
        }
    
        public override void Update(GameTime gameTime, Rectangle clientBounds)
        {
            // First, move the sprite along its direction vector
            position += speed;
    
            // Use the player position to move the sprite closer in
            // the X and/or Y directions
            Vector2 player = spriteManager.GetPlayerPosition();
    
            if (evade)
            {
                // Move away from the player horizontally
                if (player.X < position.Y)
                    position.X += Math.Abs(speed.Y);
                else if (player.X > position.X)
                    position.X -= Math.Abs(speed.Y);
    
                // Move away from the player vertically
                if (player.Y < position.Y)
                    position.Y += Math.Abs(speed.X);
                else if (player.Y > position.Y)
                    position.Y -= Math.Abs(speed.X);
    
            }
            else
            {
                if (Vector2.Distance(position, player) < evasionRange)
                {
                    // Player is within evasion range,
                    // reverse direction and modify speed
                    speed *= -evasionSpeedModifier;
                    evade = true;
                }
            }
    
            //make them bounce off walls
            if (position.X > clientBounds.Width - frameSize.X ||
                position.X < 0)
                speed *= -1;
    
            if (position.Y > clientBounds.Height - frameSize.Y ||
                position.Y < 0)
                speed *= -1;
            base.Update(gameTime, clientBounds);
        }
    }
    

1 个答案:

答案 0 :(得分:1)

对于您的碰撞代码:

    if (position.Y > clientBounds.Height - frameSize.Y ||
        position.Y < 0)
        speed *= -1;

你告诉精灵只去上去。基本上当它在y上击中-1时,它向正方向移动,直到它变为正向,在这种情况下它移动为负。因此,您可以在正面和负面屏幕之间切换。我的建议是将这些陈述分成两部分,这样当你不回避你的时候就会准确地从墙上蹦蹦跳跳。

    if (position.X > clientBounds.Width - frameSize.X)
        speed *= -1;
    else if (position.X<=0)
        speed*=1;
    if (position.Y > ClientBounds.Height - frameSize.Y)
          speed *= -1;
    else if(position.Y > 0)
          speed *= 1;