【问题标题】:XNA How to create randomly generated (differing) turn rates for duplicated objects?XNA 如何为重复对象创建随机生成(不同)的转率?
【发布时间】:2014-01-03 06:40:13
【问题描述】:

我正在制作小行星,我需要它们以不同的速度和方向旋转以达到我想要的效果。我没有为每个创建 10 多个不同的东西,而是尝试做

for (int i = 0; i < 25; i++)
{
   AsteroidPositions[i] = new Vector2(1 * random.Next(800), 1 * random.Next(600));
}

这似乎很适合随机生成的位置。我可以一次在不同的地方在屏幕上显示 25 颗随机生成的小行星。它不适用于旋转,因为它是float 而不是Vector2。我试图做这样的事情:

AsteroidRotation = MathHelper.Lerp(-0.5f, +0.5f, (float)random.NextDouble());

但这给了我所有屏幕上的岩石随机朝向一个方向的错误。和同样的一个。我无法将[i] 添加到其中,因为它说它无法将float 转换为float[]。我也有这个spriteBatch

for (int i = 0; i < 25; i++)
{
     spriteBatch.Draw(AsteroidTexture,
                AsteroidPositions[i],
                AsteroidSourceLocation,
                Color.White,
                AsteroidRotation,
                AsteroidSourceOrigin,
                1.0f,
                SpriteEffects.None,
                AsteroidLocation.Y / 720.0f);
 }

所以我有什么办法吗?我不应该使用[i] 方法并使用array 吗?如果有,怎么做?

【问题讨论】:

    标签: c# random xna rotation


    【解决方案1】:

    直截了当地说,使用变量而不是类来表示您的小行星可能不是一个好主意。您在标题中提到您在这里拥有的是一个重复的对象-甚至不是这种情况,因为您没有使用任何对象!由于在您的脑海中,您将这颗小行星可视化为一个物体,因此您应该使用一个类来包含它。

    所有小行星都朝向同一个方向的原因是因为AsteroidRotation = MathHelper.Lerp(-0.5f, +0.5f, (float)random.NextDouble()); 是一个单一的值,与每个小行星的自转使用的值相同。

    同样,您不能简单地使用AsteroidRotation[i],因为这意味着AsteroidRotation 是一个轮换集合,您可以在其中使用[i] 访问集合中的i 个 值.它不是一个集合,它是一个浮点值。

    解决这个问题的两种方法:

    1) 快速简单。不建议。不是未来的证明。会导致坏习惯。

    将旋转值设为数组。

    float[] asteroidRotation = new float[25];
    
    for (int i = 0; i < 25; i++)
    {
        asteroidRotation[i] = MathHelper.ToRadians(random.Next(360)); 
        // ToRadians() important, XNA does not work in degrees.
    }
    

    然后在你的绘图代码中你需要使用:

     spriteBatch.Draw(AsteroidTexture,
                AsteroidPositions[i],
                AsteroidSourceLocation,
                Color.White,
                AsteroidRotation[i],
                AsteroidSourceOrigin,
                1.0f,
                SpriteEffects.None,
                AsteroidLocation.Y / 720.0f);
    

    2) 创建一个Asteroid 类。好习惯。使用 C# / .Net 的面向对象的特性。

    创建一个包含所有数据和相关方法的小行星类。这与您的“而不是为每个人创建 10 多种不同的东西”作斗争。

    一个非常快速的课程设置,但它会完成工作:

    public class Asteroid
    {
        public Texture2D Texture { get; set; }
        public Vector2 Position { get; set; }
        public Color Color { get; set; }
        public float Rotation { get; set; }
    
        public Rectangle SourceLocation { get; set; }
        public Vector2 SourceOrigin { get; set; }
    
        public Asteroid()
        {
        }
    
        public void Draw(SpriteBatch sb)
        {
            sb.Draw(
                Texture,
                Position,
                SourceLocation,
                Color,
                Rotation,
                SourceOrigin,
                1.0f,
                SpriteEffects.None,
                0f);
        }
    }
    

    创建小行星列表并填写列表:

    List<Asteroid> asteroids = new List<Asteroid>();
    int numAsteroids = 25;
    
    for (int i = 0; i < numAsteroids; i++)
    {
        Asteroid asteroid = new Asteroid();
    
        asteroid.Texture = asteroidTexture;
        asteroid.Position = new Vector2(1 * random.Next(800), 1 * random.Next(600));
        asteroid.Color = Color.White;
        asteroid.Rotation = MathHelper.ToRadians(random.Next(360));
        asteroid.SourceLocation = new Rectangle(0, 0, 0, 0); // Fill me in
        asteroid.SourceOrigin = new Vector2(0, 0); // Fill me in
    
        asteroids.Add(asteroid);
    }
    

    确保您只执行一次,最好是在您游戏的其他 LoadContent()Initialize() 方法中!

    然后绘制:

    foreach (Asteroid asteroid in asteroids)
    {
        asteroid.Draw(spriteBatch);
    }
    

    应该就是这样。我不认为我错过了什么!

    将来,这使您可以扩展小行星可以非常轻松地完成的任务。您可以创建一个控制旋转速度的Update() 方法;通过给它们自己的速度让小行星移动。

    【讨论】:

    • 非常感谢您的意见,我知道我做错了什么,我只是不知道如何解决它。稍后我会看看你的建议是否有效。
    猜你喜欢
    • 2021-12-01
    • 2017-04-10
    • 2020-11-29
    • 2017-10-01
    • 1970-01-01
    • 2015-12-02
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多