Наложение спрайтов

Последнее обновление: 14.11.2015

Если у нас в приложении используется несколько текстур, то может возникнуть вопрос их наложения, если их границы пересекаются.

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

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Game1
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D texture;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            base.Initialize();
        }
		
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            texture = Content.Load<Texture2D>("monokot_tr");
        }
		
        protected override void UnloadContent()
        {
		
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            //рисуем первый объект
            spriteBatch.Draw(texture, 
                new Vector2(
                    (Window.ClientBounds.Width / 2) - (texture.Width / 2),
                    (Window.ClientBounds.Height/4) - (texture.Height/2)), 
                null,
                Color.White,
                0,
                Vector2.Zero,
                1.1f,
                SpriteEffects.None,
                0);
				
            // рисуем второй объект
            spriteBatch.Draw(texture,
                new Vector2(
                    (Window.ClientBounds.Width / 2),
                    (Window.ClientBounds.Height / 4)),
                null,
                Color.Blue,
                0,
                Vector2.Zero,
                1.1f,
                SpriteEffects.None,
                0);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

Да последовательных метода spriteBatch.Draw() выведут два объекта. Второй объект в синим цвете будет перекрывать границы первого:

Наложение объектов в MonoGame

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

За z-порядок или порядок отрисовки спрайтов отвечает последний параметр метода spriteBatch.Draw(), который называется layerDepth и который принимает значение типа float от 0 до 1. 0 и 1 - это как бы крайние точки, между которыми располагаются объекты. 0 представляет передний план, а 1 - задний.

Чтобы изменить порядок спрайтов, также надо использовать перегруженные версии метода spriteBatch.Begin(). Данный метод может принимать параметр типа SpriteSortMode - перечисление, в котором определены следующие значения:

  • Deferred: спрайты не отображаются до вызова SpriteBatch.End. Затем все вызовы метода spriteBatch.Draw() направляются на графическое устройство в том порядке, в каком они были сделаны. Данный режим применяется по умолчанию.

  • Immediate: метод spriteBatch.Begin сразу после вызова устанавливает настройки для графического устройства, а новые вызовы spriteBatch.Draw() сразу же выводят спрайты на экран также в том же порядке, в каком вызываются для них методы spriteBatch.Draw().

  • Texture: то же самое, что и режим Deferred за тем исключением, что производит сортировку спрайтов перед их отображением на экране.

  • BackToFront: то же самое, что и режим Deferred, при этом спрайты располагаются по порядку в соответствии с указанным значением параметра layer depth в методе Draw.

  • FrontToBack: то же самое, но теперь спрайты располагаются в обратном порядке по сравнению со значениями, указанными в параметре layer depth метода spriteBatch.Draw().

Теперь изменим метод Draw():

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin(SpriteSortMode.BackToFront);

    //рисуем первый объект
    spriteBatch.Draw(texture, 
                new Vector2(
                    (Window.ClientBounds.Width / 2) - (texture.Width / 2),
                    (Window.ClientBounds.Height/4) - (texture.Height/2)), 
                null,
                Color.White,
                0,
                Vector2.Zero,
                1.1f,
                SpriteEffects.None,
                1);
     // рисуем второй объект
    spriteBatch.Draw(texture,
                new Vector2(
                    (Window.ClientBounds.Width / 2),
                    (Window.ClientBounds.Height / 4)),
                null,
                Color.Blue,
                0,
                Vector2.Zero,
                1.1f,
                SpriteEffects.None,
                0);
    spriteBatch.End();
    base.Draw(gameTime);
}

Поскольку у первого объекта layerDepth равно 0, то он помещается на передний план. У второго объекта данное значение равно 1, поэтому он уходит на задний план.

Наложение спрайтов в MonoGame
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850