在我的游戏中使用图形模块的更好方法是什么

时间:2015-09-24 11:49:25

标签: c# .net monogame

我在游戏中重构了很多东西,
通过CodeReview我的理解是,我正在使图形模块完全错误。而且,我的意思是让所有模块都知道UI而不是让UI知道所有模块。

GitHub to the game code

顺便说一句:这个课程显然没有完成,它有一些我检查过的旧东西(比如Texture2D PlayerHealthTexture等等)

目前,我的UI是一个静态类,如下所示:

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

namespace ModuloFramework.UI
{
    public delegate void UIDrawEventHandler(SpriteBatch spriteBatch);

    public static class UI
    {
        private static Dictionary<Color, Texture2D> ColorTextureRepository { get; set; }

        public static Texture2D GetColorTexture(Color color, GraphicsDevice graphicsDevice)
        {
            if (ColorTextureRepository.ContainsKey(color))
                return ColorTextureRepository[color];
            Texture2D tex = new Texture2D(graphicsDevice, 1, 1);
            tex.SetData<Color>(new Color[] { color });
            ColorTextureRepository[color] = tex;
            return tex;
        }

        public static SpriteFont Font { get; set; }

        public static Texture2D PlayerHealthTexture { get; set; }

        public static event UIDrawEventHandler DrawingEvent;

        public static void SubscribeToUIDraw(UIDrawEventHandler handler)
        {
            DrawingEvent += handler;
        }

        public static void UnsubscribeFromUIDraw(UIDrawEventHandler handler)
        {
            DrawingEvent -= handler;
        }

        public static void Initialize(GraphicsDevice graphicsDevice)
        {
            ColorTextureRepository = new Dictionary<Color, Texture2D>();
        }

        public static void LoadContent(ContentManager manager)
        {
            Font = manager.Load<SpriteFont>("UI/MainFont");
        }

        public static void Draw(SpriteBatch spriteBatch)
        {
            if (spriteBatch != null)
                DrawingEvent?.Invoke(spriteBatch);
        }
    }
}

而且,每当我想要在UI上绘制内容时,我都会这样做:

public ItemBehavior()
{
    UI.SubscribeToUIDraw(PrintUi);
    isDrawn = false;
}

protected override void BehaviorImplementation(IUnit destinationPlayer)
{
    Debug.Print("Behavior test print");
    isDrawn = !isDrawn;
}

private void PrintUi(SpriteBatch spriteBatch)
{
    if (!isDrawn) return;
    spriteBatch.DrawString(UI.Font, string.Format("Test"), new Vector2(20, 50),
        Color.Black);
}

我想知道做这个UI模块的更好方法是什么 例如,如果我有一个应该在UI上具有可视化表示的Inventory类,我是在Inventory类中创建Draw()方法,还是在UI类中创建DrawInventory(库存清单)方法?

另外,我应该创建一个IDrawingEngine接口并让UI成为实现该接口的单例,如CodeReview帖子中所推荐的那样吗? 如果我这样做,并说我遵循第二种方法(让UI知道其他模块),那么在UI类本身之外,该界面对我有用吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

这是一个非常开放的问题,我的第一个建议是去看看家里的WPF和Winforms做他们的渲染。我还建议选择虚幻引擎SDK的副本并查看它们如何构建UI。那里有一些有趣的想法。

基本要点

这不是一个新问题。人们已经花了很多时间来解决它。从他们的结果中获得灵感!是否有可以集成的开源库?

手头的问题

屏幕上的每个项目都应该能够单独运行,并且具有不同的图形表示。将不同的UI元素分成几类。您可能需要基本UI支持的基类 - Render()等。您的库存应该是它自己的类。

您可以使用界面的原因是,如果您想,可以稍后更改用户界面。也许你有两个版本的UI,你想要交换它们进行性能测试!静态的东西阻止你这样做。