基于组件的设计(C# 游戏引擎)

Component Based Design (C# Game Engine)

我目前正在使用 GDI+ 在 c# 中设计一个 2D 游戏引擎,我在我的代码中遇到了一个可怕的设计缺陷。

我的想法是我的游戏引擎由多个屏幕组成,每个屏幕包含多个游戏对象,每个游戏对象包含多个组件(就像 unity 一样)。与前一个游戏对象相比,每个游戏对象可以包含不同的组件。

例如,假设我有一个会弹跳的球。我需要一个物理组件和一个变换组件。

但是,我意识到某些组件依赖于其他组件来工作。

在我上面提到的物理组件的情况下,需要访问变换组件来更新和了解球的位置、旋转等。

所以目前,我的基础组件 class 也包含对当前附加的 GameObject 的引用,因此任何组件都可以访问游戏对象中的任何其他组件。

我只是想知道这是否是我基于组件的引擎的最佳方法。

下面是Sprite组件的脚本,需要获取游戏对象的位置。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameEngine.Components
{
    /// <summary>
    /// 
    /// </summary>
    /// <seealso cref="GameEngine.Components.Component" />
    /// <seealso cref="System.IDisposable" />
    public class Sprite : Component, IDisposable
    {
        /// <summary>
        /// The bitmap the graphics engine renders
        /// </summary>
        private Bitmap bitmap;

        /// <summary>
        /// Initializes a new instance of the <see cref="Sprite"/> class.
        /// </summary>
        /// <param name="bitmap">The bitmap.</param>
        public Sprite(Bitmap bitmap)
        {
            this.bitmap = bitmap;

            this.Events.OnRenderFrame += Events_OnRenderFrame;
        }

        /// <summary>
        /// Handles the OnRenderFrame event of the Events control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RenderEventArgs"/> instance containing the event data.</param>
        private void Events_OnRenderFrame(object sender, RenderEventArgs e)
        {
            // Uses the game objects transform component, to get the position of the object
            e.GraphicsEngine.DrawSprite(this, GameObject.GetComponentOfType<Transform>().Position);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            bitmap.Dispose();
        }
    }
}

However, I've realised that some components, rely on other components to work.

In the case I mentioned above the physics component, needs to access the transform component to update and know the balls position, rotation, etc.

没错,但这不是问题所在。这是一个无法消除的要求,因为有时两个或多个组件一起工作以实现 objective。但是您可以通过从代码中添加依赖组件来使其更明智,因为 Require Component attribute 通常在 Unity 中使用。

您需要记住,除了此基于组件的模型的几个优点之外,无法实现完全独立。

The components should be appropriate for deployment into any suitable environments, thus they should possess minimal dependencies related to other components[They should be, but cannot possible in every circumstances like in your case or unity game-engin]. This ensures that the deployment of a particular component do not affect the whole system in any way.(more)

注意:您有权不同意答案或提供更温和的答案以确保decoupling.