单人游戏。各种绘图功能的水平深度?

Monogame. Level depth in various draw functions?

在animatedSprite.cs我有:

public void Draw(SpriteBatch spriteBatch, Vector2 location)
    {
        int width = Texture.Width / Columns;
        int height = Texture.Height / Rows;
        int row = (int)((float)currentFrame / (float)Columns);
        int column = currentFrame % Columns;
         Rectangle sourceRectangle = new Rectangle(width * column, height * row, width, height);
     Rectangle  destinationRectangle = new Rectangle((int)location.X, (int)location.Y, 120, 140);
        if (Game1.przelacznik_w_bezruchu == true) { sourceRectangle = new Rectangle(0, 0, width, height); }
        spriteBatch.Begin();
        spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White);
        spriteBatch.End();}

在GameScene.cs

 private void DrawGame(){
    spriteBatch.Begin();
    spriteBatch.Draw(floor1, rec_floor1, color1);
    spriteBatch.Draw(floor2, rec_floor2, color1);
    spriteBatch.Draw(house1, rec_house1,color1);
    spriteBatch.End();}

我希望地板和房子的高度低于精灵,这样它们就不会遮挡精灵。但是我不知道如何为纹理分配深度级别。

SpriteBatch Draw 函数有一个重载,允许您指定 layerDepth。

您将在 animatedSprite.cs 的 Draw 调用中使用以下内容:

spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, layerDepth);

layerDepth 将是一个浮点值,它允许您控制精灵的排序顺序。这可以从您的 GameScene.cs 作为浮点参数传入,或者您可以将位置参数更改为 Vector3 并使用其 Z 变量。

至于其他参数:

  • 0.0f 是精灵的旋转值(在 Z 轴上)
  • Vector2.Zero 是 "origin" 参数,它允许您控制精灵的旋转点。这对于围绕左上角以外的点(通常是中心)旋转很有用
  • SpriteEffects.None 这使您的绘制调用与原始 post 中的相同。不同的 SpriteEffect 值允许您执行水平或垂直翻转纹理等操作。

问题是您有多个批次,定义为 spriteBatch.Begin()spriteBatch.End() 之间的代码。

默认情况下,spriteBatch.Begin() 调用时不带参数,所有精灵均按调用顺序绘制:第一个绘制调用是背景。第二个绘图调用将在第一个之上...

正如@ProfessionalKent 在他的回答中所述,使用 layerDepth 参数:

spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, layerDepth);

layerDepth 接受任何 float 值(默认值为 0),较低的值呈现在较高的值之上。任何相同的值都按照输入的顺序完成。

此参数同样适用于spriteBatch.DrawString()

但是,layerDepth 仅在同一批次中有效。 一旦调用 End(),批次就会被排序、展平并渲染到帧缓冲区.

解决方案

写下所有绘制对象所需的深度。替换以下代码中的 layerDepth 数字以反映您的分析。

删除整个项目中的所有 spriteBatch.Begin()spriteBatch.End() 行。除非 spriteBatch.Begin() 没有 default(第 81 和 91-100 行)参数。

Game1.csGraphicsDevice.Clear之后尽早打开spriteBatch:

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

   spriteBatch.Begin();

   // Your existing code here.

   spriteBatch.End();

   //oprozniony, nothing should be here
}

在GameScene.cs中:

private void DrawGame()
{
// The ,, is for the null source rectangle, 
    spriteBatch.Draw(floor1, rec_floor1,, color1, 0.0f, Vector2.Zero, SpriteEffects.None, 2);
    spriteBatch.Draw(floor2, rec_floor2,, color1, 0.0f, Vector2.Zero, SpriteEffects.None, 3);
    spriteBatch.Draw(house1, rec_house1,,color1, 0.0f, Vector2.Zero, SpriteEffects.None, 1);

// example of a table the animatedSprite(at a depth of 0) will walk or move behind(note the negative depth):
//    spriteBatch.Draw(stol, rec_stol, , color1, 0.0f , Vector2.Zero, SpriteEffects.None, -1);

}

在AnimatedSprite.cs

public void Draw(SpriteBatch spriteBatch, Vector2 location)
    {
        // unless the width and height can change when the game is running, they should be class variables set in the constructor
        int width = Texture.Width / Columns;
        int height = Texture.Height / Rows;

        // removed unnecessary casts:(unless currentFrame is not an int)
        int row = currentFrame / Columns;
        int column = currentFrame % Columns;
        Rectangle sourceRectangle = new Rectangle(width * column, height * row, width, height);
        Rectangle destinationRectangle = new Rectangle((int)location.X, (int)location.Y, 120, 140);
        if (Game1.przelacznik_w_bezruchu == true) sourceRectangle = new Rectangle(0, 0, width, height);

// Place the sprite at Depth of 0.
        spriteBatch.Draw(Texture, destinationRectangle, sourceRectangle, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, 0);        
}

有些情况需要多批处理。如果是这种情况,请手动按深度顺序拆分批次。