C#使用Monogame开发构造Rectangle时报错无法将float转为Point如何解决
报错原因
你触发报错的代码是实例化Microsoft.Xna.Framework.Rectangle的那一行,问题出在两点:
Rectangle类没有接收两个float参数的构造函数:你传入的cell.X * sizeOfSprites * scale和cell.Y * sizeOfSprites * scale因为乘了float类型的scale,计算结果都是float类型,编译器找不到匹配的构造函数,误以为你要传入两个Point类型的参数,因此抛出类型转换错误。- 即使解决了类型问题,你也缺了构造
Rectangle必须的宽度、高度参数:Rectangle的合法构造方式只有两种,要么传入四个int参数(x坐标、y坐标、宽度、高度),要么传入两个Point参数(位置、尺寸),你只传了两个坐标参数,本身就不符合构造要求。
另外你后续的_spriteBatch.Draw调用也存在参数不匹配的问题:如果你第二个参数传入的是目标Rectangle,对应的重载不存在单独的缩放参数,你传的new Vector2(scale, scale)实际占用了origin参数的位置,会导致绘制偏移。
修复方案
这里提供两种可行的修复方式,按需选择即可:
方案1:继续使用目标Rectangle控制绘制(更推荐像素对齐,适合2D网格类游戏)
先计算好每个单元格的绘制尺寸,再构造完整的Rectangle,同时调整Draw调用的参数:
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); int sizeOfSprites = 64; float scale = .25f; // 提前计算每个单元格绘制的像素尺寸,转成int保证像素对齐 int cellDrawSize = (int)(sizeOfSprites * scale); foreach (Cell cell in _map.GetAllCells()) { // 构造完整的Rectangle,四个参数都为int类型 Microsoft.Xna.Framework.Rectangle position = new Microsoft.Xna.Framework.Rectangle( (int)(cell.X * cellDrawSize), (int)(cell.Y * cellDrawSize), cellDrawSize, cellDrawSize ); if (cell.IsWalkable) { // 调整Draw参数,origin传Vector2.Zero,删掉多余的缩放参数 _spriteBatch.Draw(floorSprite, position, null, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); } else { _spriteBatch.Draw(wallSprite, position, null, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); } } _spriteBatch.End(); base.Draw(gameTime); }
方案2:改用Vector2位置+scale参数控制绘制
不需要构造Rectangle,直接用接收位置向量的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()) { // 直接计算绘制位置的Vector2,不需要转int Vector2 position = new Vector2(cell.X * sizeOfSprites * scale, cell.Y * sizeOfSprites * scale); if (cell.IsWalkable) { // 用第二个参数为Vector2的Draw重载,scale参数正常生效 _spriteBatch.Draw(floorSprite, position, null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); } else { _spriteBatch.Draw(wallSprite, position, null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); } } _spriteBatch.End(); base.Draw(gameTime); }
内容的提问来源于stack exchange,提问作者gogy255
相关产品推荐
相关产品推荐

