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'的主要内容,如果未能解决你的问题,请参考以下文章