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

Posted

技术标签:

【中文标题】C# 无法从 \'float\' 转换为 \'Microsoft.Xna.Framework.Point\'【英文标题】: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'

【问题讨论】:

【参考方案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()

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

【讨论】:

以上是关于C# 无法从 'float' 转换为 'Microsoft.Xna.Framework.Point'的主要内容,如果未能解决你的问题,请参考以下文章

C#如何将OBJECT转换成数组

在 C# 中“转换”浮点数为双精度值

C#如何把INT类型转换为方法参数对应的枚举类型?怎么强制转换?

C#中怎么将string转换成int型

c#中int向float型转换。

C# 隐式运算符 MyType(int value) 自动“支持”从浮点数转换