0

我在寻找解决问题的方法时发现了这个网站,我想知道是否有人可以帮助我尝试解决我的困境。

我正在使用 XNA 和 C# 来创建用户能够从他们随机选择的零件组装汽车的东西。这辆车不必有 4 个轮子和挡风玻璃。它只需要由用户选择的至少 7 个部分组成。我创建了一个名为“Car”的类,它将创建用户选择的部件的所有 7 个实例。这些部件属于“CarPart”类。我还创建了两个独立的“CarPart”子类,称为“Wheel”和“Windshield”。我打算稍后扩展这些部分,例如添加“门”和“树干”等。

所以我所做的是在我的 Car 类中,声明 7 个“CarPart”类型的对象,然后将它们声明为 new Windshield()。或新的轮子()。

但是当我尝试访问 Windshield 或 Wheel 类的初始化函数时,它只允许我访问父“CarPart”类的初始化函数。

我是在尝试以正确的方式做到这一点,还是应该找到另一种解决问题的方法?

我也尝试过使用 Virtual 和 Override 来尝试重载函数,但我似乎也无法让它正常工作,它只是说,“找不到合适的重载方法”。

我已经包含了我的课程代码。

任何帮助都会令人惊叹,我已经被困了好几天,如果没有用户能够按照自己的意愿组装汽车的功能,我就无法继续我的项目。

我发现了与我在此链接上尝试做的类似的事情,但我似乎无法让它工作。 http://csharp-station.com/Tutorial/CSharp/Lesson09

我确定我在做一些我看不到的愚蠢的事情,因为我已经盯着同一个问题太久了。

车类:

namespace TestGame4
{
    class Car
    {
        //Car consists of 7 CarParts chosen by the user//
        //e.g.: 

        CarPart Part1, Part2, Part3, Part4, Part5, Part6, Part7; 

        public void Initialize(CarPart part1, CarPart part2, CarPart part3, CarPart part4, CarPart part5, CarPart part6, CarPart part7)
        {
            Part1 = part1;
            Part2 = part2;
            Part3 = part3;
            Part4 = part4;
            Part5 = part5;
            Part6 = part6;
            Part7 = part7;       

            ***//This is the part that doesn't work how I want it to. I want it to initialize 
            //as a Windshield class, but it's only initializing as a CarPart class//***
            part1.Initialize(

        }
    }
}

CarPart class:

namespace TestGame4
{
    public class CarPart
    {
        public void Initialize(string assetName, Vector2 Position)
        {

        }
    }
}

挡风玻璃类:

namespace TestGame4
{
    public class Windshield : CarPart
    {
        public void Initialize(Vector2 Position)
        {

        }
    }
}

轮组:

namespace TestGame4
{
    public class Wheel : CarPart
    {
        public void Initialize(Vector2 Position)
        {

        }
    }
}

我在其中初始化 Car 类并尝试使用 Windshield 和 Wheel 类作为参数设置它的主要 Game1 类:

namespace TestGame4
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Car myCar;

        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

            myCar = new Car();
            myCar.Initialize(new Windshield(), new Wheel(), new Windshield(), new Wheel(), new Windshield(), new Wheel(), new Windshield());           

            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
        }

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

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

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}

我将非常感谢我得到的任何帮助!提前致谢!

4

1 回答 1

1

WindshieldWheel都是CarPart. 对于Car类,它们只是CarPart(如定义的那样),所以Car不知道它们中的任何一个是Wheel还是Windshield。至少在编译时不是。

要解决此问题,您需要为这些类添加一个接口。CarPart或者添加一个更容易的抽象函数。

abstract class CarPart
{
   public abstract void Initialize(Vector2 position);
   public void Initialize(string assetName, Vector2 position)
   {
   }
}

之后,两个子类都需要重写这个函数,否则它们也将是抽象的(抽象类不能用于创建对象)。

接口非常简单:接口是您需要从类中获得的行为。例如

interface IInitializable
{
   void Initialize (Vector2 position);
}
class WindShield: IIinitializable
{
   void Initialize (Vector2 position)
   {
      ...
   }
}

然后你可以写CarPart

IInitializable [] parts = new IInitializable [7];
parts[0] = new WindShield();
...
parts[6] = new Wheel();

parts[3].Initialize(new Vector2(0, 0));

所以这些部分都符合接口IInitializable,你可以调用通用方法Initialize (Vector2)。当不同的不相关的类实现相同的行为时,接口是最有用的,比如IQueryableorIDisposable等​​等。

于 2013-03-14T09:29:42.907 回答