Методы CanvasSpriteBatch, Begin/End для рисования множества спрайтов одним и тем же SpriteBatch

Я написал простой класс для управления рисованием растрового изображения.

Является ли это хорошим способом реализации методов Begin() - End() для рисования нескольких спрайтов из разных объектов (как в методах omonime XNA)?

public class Caravaggio : IDrawingService
{
    private CanvasDrawingSession _ds = null;
    private CanvasSpriteBatch _sb = null;

    private CanvasImageInterpolation _interpolation = CanvasImageInterpolation.Linear;
    private CanvasSpriteOptions _options = CanvasSpriteOptions.ClampToSourceRect;
    private CanvasSpriteSortMode _sortMode = CanvasSpriteSortMode.None;

    public bool EnableDebugDrawing { get; set; } = false;

    // This is being set from outside each CanvasAnimatedControl Draw event.
    // I made this because I'd like to pass only a "Caravaggio" parameter to my draw functions.
    public void SetDrawingEntity(CanvasDrawingSession DrawingEntity)
    {
        _ds = DrawingEntity;
    }

    public void Begin()
    {
        _sb = _ds.CreateSpriteBatch(_sortMode, _interpolation, _options);
    }

    public void End()
    {
        _sb.Dispose();
        _sb = null;
    }

    public void DrawBitmap(
        CanvasBitmap Bitmap,
        Rect SourceRect,
        Vector2 Position,
        Color OverlayColor,
        Vector2 Origin,
        float Rotation,
        Vector2 Scale,
        bool FlipHorizontally)
    {
        if (_ds == null)
        {
            throw new System.Exception("CanvasDrawingSession not set");
        }

        if (_sb == null)
        {
            throw new System.Exception("CanvasSpriteBatch not set. Did you forget to call Begin()?");
        }

        _sb.DrawFromSpriteSheet(
            Bitmap,
            Position, SourceRect,
            ColorToVector4(OverlayColor),
            Origin, Rotation, Scale,
            FlipHorizontally ? CanvasSpriteFlip.Horizontal : CanvasSpriteFlip.None);

        if (EnableDebugDrawing)
        {
            _ds.DrawRectangle(Position.X, Position.Y, (float)SourceRect.Width, (float)SourceRect.Height, Colors.Red);
        }
    }

Я знаю, что это очень просто, но это просто для "хобби".

Я думаю, что эти методы являются улучшением, если вы не хотите создавать новый объект SpriteBatch для каждого нарисованного объекта, например, когда вы рисуете свои объекты таким образом:

// GameManager
public void Draw(IDrawingService MyDrawingService)
{
    MyDrawingService.Begin();

    _background.Draw(MyDrawingService);    

    foreach (Player p in _players)
       p.Draw(MyDrawingService);

    _score.Draw(MyDrawingService);

    MyDrawingService.End();
}

person Francesco Bonizzi    schedule 27.12.2015    source источник
comment
@Downvoter: Хотите прокомментировать?   -  person Francesco Bonizzi    schedule 03.01.2016
comment
Я не против, но в любом случае: мне не ясно, какое значение это добавляет поверх обычного API CanvasSpriteBatch. Возможно, демонстрация того, как это улучшает код вызова, даст достаточно контекста, чтобы помочь ответить на вопрос, хороший ли это способ....   -  person Damyan    schedule 06.01.2016


Ответы (2)


Похоже на разумный способ начать строить абстракции поверх Win2D.

Там, где у вас есть пары Begin/End, я обычно хотел бы видеть что-то IDisposable, чтобы вы могли использовать его с помощью «using». Что-то типа:

public void Draw(IDrawingService MyDrawingService)
{
    using (var session = MyDrawingService.Begin())
    {

        _background.Draw(session);    

        ...
    }
}

Такого рода вещи позволяют вам легко возвращать или генерировать исключение из пары Begin/End, не беспокоясь о том, что вы пропустите End.

person Damyan    schedule 08.01.2016

Я думаю, что это хорошая отправная точка.

Я вижу больше преимуществ, если вы обернете больше материалов Win2D, скажем, вместо использования CanvasBitmap вы используете свой собственный объект Sprite. Еще одна вещь, которую вы также можете добавить, — это возможность создавать несколько пакетов спрайтов вместо использования одного.

Я собираюсь сделать что-то подобное для небольшого проекта, я обновлю свою версию, когда это будет сделано.

person xesf    schedule 17.01.2016