C# 无法从 'float' 转换为 'Microsoft.Xna.Framework.Point'

C# cannot convert from 'float' to 'Microsoft.Xna.Framework.Point'

我正在尝试使用 Monogame 和 RogueSharp 在 C# 中制作 rougelike。

这是我在 Draw() 中的一些代码

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

            _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

            int sizeOfSprites = 64;
            float scale = .25f;
            foreach (Cell cell in _map.GetAllCells())
            {
            // error in the line below    
            Microsoft.Xna.Framework.Rectangle position = new Microsoft.Xna.Framework.Rectangle(cell.X * sizeOfSprites * scale, cell.Y * sizeOfSprites * scale);
                if (cell.IsWalkable)
                {
                    _spriteBatch.Draw(floorSprite, position, null, Color.White, 0f, new Vector2(scale, scale), 0.0f, 0f);
                }
                else
                {
                    _spriteBatch.Draw(wallSprite, position, null, Color.White, 0f, new Vector2(scale, scale), 0.0f, 0f);
                }
            }

            _spriteBatch.End();

            base.Draw(gameTime);
        }

Returns:

参数 2:无法从 'float' 转换为 'Microsoft.Xna.Framework.Point'

参数 1:无法从 'float' 转换为 'Microsoft.Xna.Framework.Point'

Rectangle 构造函数采用 (Point location, Point size)(Int32 x, Int32 y, Int32 width, Int32 height) 但不采用 (Float, Float) (这甚至意味着什么?) - 请参阅 docs.

所以,这里有两个问题:

  • 您需要四个值才能在二维空间中唯一指定一个矩形 space,而不是两个。 Rectangle 使用左上角的 X 和 Y 以及宽度和高度。
  • Rectangle 构造函数期望这些值是整数而不是浮点数。

看你的代码,我猜测你想创建一个长方形,两边的长度都是sizeOfSprites * scale,在这种情况下你会需要指定尺寸如下:

int scaledSize = (int)(sizeOfSprites * scale);
Microsoft.Xna.Framework.Rectangle position = new Microsoft.Xna.Framework.Rectangle(
  cell.X * scaledSize,
  cell.Y * scaledSize,
  scaledSize,
  scaledSize
);

我注意到 Cell 也有整数坐标,你只对 0.25 部分使用浮点数,所以你也可以简单地将大小存储为整数。如果您以后不打算使这些变量动态化,最快的方法是首先使用 const int scaledSize = 16;

您想尽量减少在 Draw() 中执行的操作。 Draw() 是一个阻塞调用,意味着进程将等待(即挂起)完成。

我建议预乘 sizeOfSprites * scale 作为常数,如果它不改变的话:

const int SIZE = 16; // 64 * .25

Microsoft.Xna.Framework.Rectangle position = new Microsoft.Xna.Framework.Rectangle(
  (int)(cell.X * SIZE),  (int)(cell.Y * SIZE),  SIZE, SIZE);
);

对于简单的游戏,每帧 16.6666667 毫秒(60 FPS)的时间限制不是问题,但随着游戏的增长,它们可能会达到极限。

我不是提倡过度优化。在这种情况下,很可能在 X86/X64 处理器上,内存查找可能被缓存,但是缓存 structure/layout 可能不同的移动或控制台应用程序呢?

进行不必要的函数调用只会增加时间预算。(Floor()Round()

每个函数调用都必须添加当前状态上下文推送,复制任何传递的变量,并弹出上下文状态+结果。大量不必要的内存访问。