【问题标题】:XNA: Need help spawning enemies on any side, on a timer tick, then maving them move randomlyXNA:需要帮助在任何一侧生成敌人,在计时器滴答时,然后让他们随机移动
【发布时间】:2014-03-28 19:45:05
【问题描述】:

好吧,我正在 XNA 中制作一个 2D 射击游戏,但遇到了一些问题。我正在尝试制作一个敌人类,它允许我每 10 秒在屏幕外生成一个敌人,然后让它随机向上、向右或向下移动。在花了 4 个小时的大部分时间在互联网上搜索之后,我发现的只是让敌人向一个方向移动、从一个点生成等等的例子。

任何帮助将不胜感激,我的敌人班级现在有点混乱,因为我将这么多代码拖到一起尝试使其工作。就是这样:

using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Shark_Wars_2
{
    class Enemy
    {
        List<Vector2> sharkPosition = new List<Vector2>(); //is there a better way for having more than one of the same enemy?
        public Vector2 sharkDirection;

        public int sharkWidth;
        public int sharkHeight;

        public int sharkSpeed;

        float sharkSpawnProbability;

        public Random randomSharkPosition;
        public Random direction;

        double timer = 0;
        float interval = 1000;
        int speed = 1;

        public Enemy()
        {
            sharkPosition = new Vector2(0, 0); //brings up error - see above

            sharkWidth = 64;
            sharkHeight = 44;

            sharkSpeed = 3;

            sharkSpawnProbability = 1 / 10000f;

            randomSharkPosition = new Random(3); //left, right, up, down
            direction = new Random(3);

        }

        public void update(GameTime gameTime)
        {
            //enemy movement
            for (int i = 0; i < sharkPosition.Count; i++)
            {
                //enemy position increases by speed
                sharkPosition[i] = new Vector2(sharkPosition[i].X + sharkDirection.X, sharkPosition[i].Y + sharkDirection.Y);
            }

            timer += gameTime.ElapsedGameTime.TotalMilliseconds;

            //aniamtion
            if (timer >= interval / speed)
            {
                timer = 0;
            }

            //spawn new enemy
            if (randomSharkPosition.NextDouble() < sharkSpawnProbability)
            {
                float spawn = (float)randomSharkPosition.NextDouble() * (1280 - sharkHeight); sharkPosition.Add(new Vector2(sharkDirection.X, sharkDirection.Y));
            }
        }

        // ill worry about drawing after spawning and movement, should be no problem
        public void draw()//(SpriteBatch spritebatch, Texture2D wave)
        {
            for (int i = 0; i < sharkPosition.Count; i++)
            {
                //spritebatch.Draw(shark, new Rectangle((int)sharkPosition[i].X, (int)sharkPosition[i].Y, sharkWidth, sharkHeight);
            }
        }
    }
}

我的脑袋真的被堵住了,我花了很多时间研究如何制作移动的背景对象和一个子弹列表。

我真的很想把它简化一下,所以如果你知道一种更简单的做事方式,我会全力以赴!

提前致谢!

【问题讨论】:

  • 你的 SharkPosition = new Vector2(0, 0);应该显示错误。这是一个列表,所以你需要这样做。 SharkPosition.Add(new Vector2(0, 0));至于你的产卵。选择一个随机的 x 和 y 值。检查它们是否超出范围。放置单元。检查单位是否小于0。如果是则向右移动。否则检查它是否小于0。向下移动。否则检查它是否大于地图边界宽度。向左移动。否则检查它是否大于地图边界高度。提升。检查会导致单位从界外变为界内。

标签: c# random xna game-physics


【解决方案1】:

您的基本问题是您没有将管理/逻辑类与实例对象分开。你想要更多的分离,像这样:

public class EnemyManager
{
   List<Shark> activeSharks = new List<Shark>();
   Timer spawnTimer;

   //Just one random instance per class, this is considered best practice to improve
   //the randomness of the generated numbers
   Random rng = new Random(); //Don't use a specific seed, that reduces randomness!

   public EnemyManager()
   {
      //Min/max time for the next enemy to appear, in milliseconds
      spawnTimer = new Timer(rng.Next(500, 2000));
      spawnTimer.Elapsed += SpawnShark;
      spawnTimer.Start();
   }

   public void SpawnShark(object sender, ElapasedEventArgs e)
   {
       Vector2 newSharkPosition = Vector2.Zero;
       newSharkPosition.X = rng.Next(0, 1280); //Whatever parameters you want    
       newSharkPosition.Y = rng.Next(0, 1280); //Whatever parameters you want    

       Vector2 newSharkDirection.... //Repeat above for direction

       Shark spawnedShark = new Shark(newSharkPosition, newSharkDirection);
       activeSharks.Add(spawnedShark);

       //Min/max time for the next enemy to appear, in milliseconds
      spawnTimer = new Timer(rng.Next(500, 2000));
   }

   public void update(GameTime gameTime)
   {
      foreach(Shark s in activeSharks)
        s.Update(gameTime);
   }

   public void draw(SpriteBatch spritebatch, Texture2D wave)
   {
      foreach(Shark s in activeSharks)
        s.Draw(spritebatch, wave)
   }
}

public class Shark
{
    Vector2 position;
    Vector2 direction;
    const float speed = 3;
    const int height = 44;
    const int width = 64;

    public Shark(Vector3 initPosition, Vector3 direction)
    {
        position = initPosition;
        this.direction = direction;
    }

    //Draw/Update using the local variables.
}

显然我没有编写所有代码,但这应该可以帮助您入门。首先,我将所有“实例”特定数据放入自己的对象中,然后“管理器”只是持有和管理这些对象的集合。我还将 RNG 重构为只有一个实例(最佳实践)并使用默认的基于时间的种子。自己播种会导致每次运行程序时出现的数字都相同(可能不是你想要的:))。

如果您有不明白的地方请告诉我,或者我可以提供任何进一步的帮助!

【讨论】:

  • 哇,非常感谢你,这真的把事情弄清楚了,进展也更加顺利。我希望我能从这里处理事情,但我一定会问我是否还有其他麻烦!非常感谢:)
  • 很高兴我能帮上忙!当您觉得您的问题已得到解答时,请记住“检查”您认为最好的答案。支持有用的答案(当你有代表时)也是说“谢谢!”的好方法。给帮助过的人。不这样做会使回答者非常难过:(;)。欢迎来到 StackOveflow,您的第一个问题非常好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多