c# XNA -尝试随机化对象列表的移动.除了一个人以外,所有人的动作都一样

本文关键字:一个人 所有人 都一样 移动 XNA 随机化 列表 对象 | 更新日期: 2023-09-27 18:12:07

我试图获得一个精灵对象列表,以便在屏幕上以短线性移动(上、下、左、右)随机移动。这些精灵是随机移动的,但它们的移动都是相同的(游戏邦注:例如所有精灵都向左移动,所有精灵都向右移动等等),除了一个精灵是单独移动的。我希望它们都能独立地相互移动。代码如下-

 namespace game2
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    /// <summary>
    /// Sprite
    /// </summary>
    List<Sprite> spriteList;
    Sprite tempSprite;
    private int spriteNum;

    /// <summary>
    /// General
    /// </summary>
    Random random;
    int randomNum;
    Rectangle viewPort;
    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        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()
    {
        // TODO: Add your initialization logic here
        //Initialize Sprites
        spriteList = new List<Sprite>();
        spriteNum = 4;
        for (int i = 0; i < spriteNum; i++)  //Load in as many sprites as spriteNum specifies
        {
            tempSprite = new Sprite();
            spriteList.Add(tempSprite);      //add in sprites to list       
        }
        //initialise random
        random = new Random();
        //initialise viewport
        viewPort = new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
        base.Initialize();
    }
    /// <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);
        foreach (Sprite s in spriteList)                    //for each sprite in spriteList, load content by passing in Game1's content
        {
            s.LoadContent(this.Content, viewPort, "square");
            s.Position = new Vector2(random.Next(0, viewPort.Width), random.Next(0, viewPort.Height));
        }
        // TODO: use this.Content to load your game content here
    }
    /// <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();

        //update sprites
        foreach (Sprite s in spriteList)
        {
            s.Update(gameTime);
        }
        // TODO: Add your update logic here
        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();

        foreach (Sprite s in spriteList)
        {
            s.Draw(this.spriteBatch);
        }

        spriteBatch.End();
        // TODO: Add your drawing code here
        base.Draw(gameTime);
    }
}
}

这里是精灵类-

namespace game2
 {
class Sprite
{
    //Movement
    public Vector2 Position = new Vector2(0,0);
    private float counter = 0f;
    private float range = 100f;
    private Random random;
    public int randomNum;
    //Properties
    private Texture2D mSpriteTexture;
    //General
    private Rectangle viewPort;
    public void LoadContent(ContentManager theContentManager, Rectangle tempViewport, string asset)
    {
        random = new Random();
        viewPort = tempViewport;
        mSpriteTexture = theContentManager.Load<Texture2D>(asset);
    }
    public void Update(GameTime gameTime)
    {
        if (randomNum == 0)
        {
            if (Position.X + mSpriteTexture.Width < viewPort.Width && counter <= range)
            {
                    Position.X++;
                    counter++;
            }
            else
            {
                randomNum = random.Next(0, 4);
                counter = 0;
            }
        }
        if (randomNum == 1)
        {
            if (Position.X > viewPort.X && counter <= range)
            {
                Position.X--;
                counter++;
            }
            else
            {
                randomNum = random.Next(0, 4);
                counter = 0;
            }
        }
        if (randomNum == 2)
        {
            if (counter <= range)
            {
                Position.Y++;
                counter++;
            }
            else
            {
                randomNum = random.Next(0, 4);
                counter = 0;
            }
        }
        if (randomNum == 3)
        {
            if (counter <= range)
            {
                Position.Y--;
                counter++;
            }
            else
            {
                randomNum = random.Next(0, 4);
                counter = 0;
            }
        }
    }
    public void Draw(SpriteBatch theSpriteBatch)
    {
        theSpriteBatch.Draw(mSpriteTexture, Position, Color.White);
    }
}
}

c# XNA -尝试随机化对象列表的移动.除了一个人以外,所有人的动作都一样

你在LoadContent中加载所有精灵的速度非常快,这不是问题,但是每个精灵都有自己的Random类

因此,许多人得到相同的种子(类似于在forwhile循环中实例化Random时看到的问题)。具有相同种子的rng将产生相同的值序列,从而导致您所看到的行为。

将单个Random实例传递给使用它的所有对象应该会导致您的问题消失。