(моноигра) Несколько экземпляров объекта, унаследованного спрайтом

Я видел вопросы, похожие на то, что я задаю, но они не совсем дают мне ответ, который я ищу. Я хочу, чтобы 5 экземпляров моих спрайтов отображались на экране и появлялись в разных местах. Однако по какой-то причине вместо 5 экземпляров каждый «экземпляр» спрайта увеличивает значения одного спрайта, который появляется на экране.

Sprite.cs

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

namespace Lab05
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;

namespace Lab05_2__Aaron_Benjamin_
{
    class Enemy : Sprite
{
    const string ENEMY_ASSETNAME = "gear";
    Random Rand = new Random();
    int startPos_X;
    int startPos_Y;

    public void LoadContent(ContentManager theContentManager)
    {
        Position = new Vector2(startPos_X = Rand.Next(0 , 1000), startPos_Y = Rand.Next(0, 1000)); //= Rand.Next(0, 100),Position.Y = Rand.Next(0,100));

        base.LoadContent(theContentManager, ENEMY_ASSETNAME);
    }

    public void Update(GameTime gameTime)
    {
        MouseState cState = Mouse.GetState();


        if (Position.X > cState.X)
        {
            Position.X += 1;
        }
        if (Position.X < cState.X)
        {
            Position.X -= 1;
        }
        if (Position.Y < cState.Y)
        {
            Position.Y -= 1;
        }
        if (Position.Y > cState.Y)
        {
            Position.Y += 1;
        }

        base.Update(gameTime);
       }        
     }
   }
_Aaron_Benjamin_ { class Sprite { Texture2D mSpriteTexture; public Vector2 Position; Color mSpriteColor; public Rectangle Size; public string AssetName; private float mScale = 1.0f; public float Scale { get { return mScale; } set { mScale = value; //Recalculate the Size of the Sprite with the new scale Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale)); } } public void LoadContent(ContentManager theContentManager, string theAssetName) { mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName); AssetName = theAssetName; Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale)); } public void Update(GameTime gameTime) { } public void Draw(SpriteBatch theSpriteBatch) { theSpriteBatch.Draw(mSpriteTexture, Position, new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height), Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0); //theSpriteBatch.Draw(mSpriteTexture, Position); } } }

Enemy.cs

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;

namespace Lab05_2__Aaron_Benjamin_
{
    class Enemy : Sprite
{
    const string ENEMY_ASSETNAME = "gear";
    Random Rand = new Random();
    int startPos_X;
    int startPos_Y;

    public void LoadContent(ContentManager theContentManager)
    {
        Position = new Vector2(startPos_X = Rand.Next(0 , 1000), startPos_Y = Rand.Next(0, 1000)); //= Rand.Next(0, 100),Position.Y = Rand.Next(0,100));

        base.LoadContent(theContentManager, ENEMY_ASSETNAME);
    }

    public void Update(GameTime gameTime)
    {
        MouseState cState = Mouse.GetState();


        if (Position.X > cState.X)
        {
            Position.X += 1;
        }
        if (Position.X < cState.X)
        {
            Position.X -= 1;
        }
        if (Position.Y < cState.Y)
        {
            Position.Y -= 1;
        }
        if (Position.Y > cState.Y)
        {
            Position.Y += 1;
        }

        base.Update(gameTime);
       }        
     }
   }

Game1.cs

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Lab05_2__Aaron_Benjamin_
{
/// <summary>
/// This is the main type for your game.
/// </summary>

public class Game1 : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    List<Enemy> enemies = new List<Enemy>();




    private void CreateEnemy()
    {
        Enemy gear = new Enemy();
        Random rand = new Random();
        //gear = new Enemy();
        //gear.Position.X = rand.Next(0, 1000);
        //gear.Position.Y = rand.Next(0, 1000);
        Console.WriteLine(gear.Position.Y);
        enemies.Add(gear);

    }

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
    }

    /// <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


        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);

        // TODO: use this.Content to load your game content here
        for (int i = 0; i < 5; i++)
        {
            CreateEnemy();
        }

        foreach (var cog in enemies)
        {
            cog.LoadContent(this.Content);
        }
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// game-specific 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)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        // TODO: Add your update logic here
        foreach (var cog in enemies)
        {
            if (cog.Position.X > Window.ClientBounds.Width - 50)
                cog.Position.X = Window.ClientBounds.Width - 50;
            if (cog.Position.Y > Window.ClientBounds.Height - 50)
                cog.Position.Y = Window.ClientBounds.Height - 50;

            if (cog.Position.X < 0)
                cog.Position.X = 0;
            if (cog.Position.Y < 0)
                cog.Position.Y = 0;
        }

        foreach (var cog in enemies)
        {
            cog.Update(gameTime);
        }

        if (Keyboard.GetState().IsKeyDown(Keys.M))
        {
            // If 'm' is down, we create a new meteor. Note that once this is working
            // this is going to make a lot of meteors. That's another issue, though.
            CreateEnemy();
        }
        //Console.WriteLine(enemies.Count);
        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.Black);

        // TODO: Add your drawing code here
        spriteBatch.Begin();
        foreach (var cog in enemies)
        {
           cog.Draw(spriteBatch);
        }
        spriteBatch.End();
        base.Draw(gameTime);
      }
   }
}

person Starkium    schedule 19.03.2016    source источник


Ответы (2)


Разве вы не должны использовать gear в этой части вместо this.gear ?

 foreach (var gear in enemies)
 {
       this.gear.LoadContent(this.Content);
 }
person L. Centeleghe    schedule 19.03.2016
comment
мой друг только что заметил это. Я заменил все это на зубчатое колесо вместо механизма и переместил туда, где создается экземпляр. Показался только один спрайт, но с правильной скоростью. Что-то мне подсказывает, что случайная позиция не является новой случайной для каждого спрайта. Я обновлю код. - person Starkium; 19.03.2016

хорошо, я получил его на работу. Таким образом, мои случайные числа были назначены, а затем переназначены в другом разделе кода, так что все они складывались друг над другом. Вот решение.

Sprite.cs

class Sprite
{
    Texture2D mSpriteTexture;
    public Vector2 Position;
    Color mSpriteColor;
    public Rectangle Size;
    public string AssetName;
    private float mScale = 1.0f;

    public float Scale 
    {
        get { return mScale; }
        set
        {
            mScale = value;
            //Recalculate the Size of the Sprite with the new scale
            Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
        }
    }

    public void LoadContent(ContentManager theContentManager, string theAssetName)
    {
        mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
        AssetName = theAssetName;
        Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
    }

    public  void Update(GameTime gameTime)
    {


    }

    public void Draw(SpriteBatch theSpriteBatch)
    {
         theSpriteBatch.Draw(mSpriteTexture, Position,
            new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height),
             Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);

        //theSpriteBatch.Draw(mSpriteTexture, Position);
    }

   }
}

Enemy.cs

class Enemy : Sprite
{
    const string ENEMY_ASSETNAME = "gear";
    Random Rand = new Random();
    //int startPos_X;
    //int startPos_Y;

    public void LoadContent(ContentManager theContentManager)
    {
        Position = new Vector2(Position.X ,Position.Y);

        base.LoadContent(theContentManager, ENEMY_ASSETNAME);
    }

    public void Update(GameTime gameTime)
    {
        MouseState cState = Mouse.GetState();


        if (Position.X > cState.X)
        {
            Position.X += 1;
        }
        if (Position.X < cState.X)
        {
            Position.X -= 1;
        }
        if (Position.Y < cState.Y)
        {
            Position.Y -= 1;
        }
        if (Position.Y > cState.Y)
        {
            Position.Y += 1;
        }

        base.Update(gameTime);
    }        
  }
}

Game1.cs

public class Game1 : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    List<Enemy> enemies = new List<Enemy>();
    Random rand = new Random();



    private void CreateEnemy()
    {
        Enemy gear = new Enemy();

        //gear = new Enemy();
        gear.Position.X = rand.Next(0, 1000);
        gear.Position.Y = rand.Next(0, 1000);
        Console.WriteLine(gear.Position.Y);
        enemies.Add(gear);
        enemies[0].Position.X += 10;

    }

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
    }

    /// <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


        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);

        // TODO: use this.Content to load your game content here
        for (int i = 0; i < 5; i++)
        {
            CreateEnemy();
        }

        foreach (var cog in enemies)
        {
            cog.LoadContent(this.Content);
        }
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// game-specific 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)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        // TODO: Add your update logic here
        foreach (var cog in enemies)
        {
            if (cog.Position.X > Window.ClientBounds.Width - 50)
                cog.Position.X = Window.ClientBounds.Width - 50;
            if (cog.Position.Y > Window.ClientBounds.Height - 50)
                cog.Position.Y = Window.ClientBounds.Height - 50;

            if (cog.Position.X < 0)
                cog.Position.X = 0;
            if (cog.Position.Y < 0)
                cog.Position.Y = 0;
        }

        foreach (var cog in enemies)
        {
            cog.Update(gameTime);
        }

        if (Keyboard.GetState().IsKeyDown(Keys.M))
        {
            // If 'm' is down, we create a new meteor. Note that once this is working
            // this is going to make a lot of meteors. That's another issue, though.
            CreateEnemy();
        }
        //Console.WriteLine(enemies.Count);
        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.Black);

        // TODO: Add your drawing code here
        spriteBatch.Begin();
        foreach (var cog in enemies)
        {
           cog.Draw(spriteBatch);
        }
        spriteBatch.End();
        base.Draw(gameTime);
    }
  }
}
person Starkium    schedule 19.03.2016