Компонентный дизайн (C# Game Engine)

В настоящее время я разрабатываю 2D Game Engine на C#, используя GDI+, и я столкнулся с ужасным недостатком дизайна в моем коде.

Идея состоит в том, что мой игровой движок состоит из нескольких экранов, каждый экран содержит несколько игровых объектов, а каждый игровой объект состоит из нескольких компонентов (как и в случае с Unity). Каждый игровой объект может содержать разные компоненты по сравнению с предыдущим игровым объектом.

Например, допустим, у меня есть мяч, который подпрыгивает. Мне понадобится физический компонент и компонент преобразования.

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

В случае, о котором я упоминал выше, физический компонент должен получить доступ к компоненту преобразования, чтобы обновить и узнать положение шариков, вращение и т. Д.

Таким образом, в данный момент мой базовый класс компонентов содержит ссылку на 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();
        }
    }
}

1 ответ

Решение

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

В случае, о котором я упоминал выше, физический компонент должен получить доступ к компоненту преобразования, чтобы обновить и узнать положение шариков, вращение и т. Д.

Да, это правда, но это не проблема. Это требование, которое не может быть отменено, так как некоторое время два или более компонента работают вместе для достижения цели. Но вы можете сделать это более разумным путем добавления зависимого компонента из вашего кода, поскольку атрибут Require Component обычно используется в Unity.

Необходимо помнить, что помимо нескольких преимуществ этой модели на основе компонентов полная независимость не может быть достигнута.

Компоненты должны быть подходящими для развертывания в любых подходящих средах, поэтому они должны обладать минимальными зависимостями, связанными с другими компонентами [они должны быть, но не могут быть возможными при любых обстоятельствах, как в вашем случае или Unity Game-Engine]. Это гарантирует, что развертывание определенного компонента никак не повлияет на всю систему.( Подробнее)

Примечание. Вы имеете право не согласиться с ответом или предоставить более точный ответ, обеспечивающий разделение.

Другие вопросы по тегам