【问题标题】:C# cannot convert from 'float' to 'Microsoft.Xna.Framework.Point'C# 无法从 'float' 转换为 'Microsoft.Xna.Framework.Point'
【发布时间】:2021-12-26 05:57:25
【问题描述】:

我正在尝试使用 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);
        }

返回:

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

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

【问题讨论】:

    标签: c# monogame


    【解决方案1】:

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

    所以,这里有两个问题:

    • 您需要四个值来唯一指定二维空间中的矩形,而不是两个。 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;

    【讨论】:

    • 现在可以了!太棒了!
    • (int)Math.Floor() 调用是多余的。仅使用演员表(int)。负面位置在屏幕外并且不相关。在游戏中,小于 16 毫秒的执行速度至关重要。仅抗锯齿需要亚像素精度,一般绘图不需要。
    【解决方案2】:

    您希望最小化在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 处理器上,内存查找可能会被缓存,但是缓存结构/布局可能不同的移动或控制台应用程序呢?

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多