MonoGame精灵渲染异常求助:纹理显示异常
MonoGame精灵渲染异常问题排查与解决
问题描述
MonoGame开发中遇到精灵渲染异常:PNG纹理已通过Content.mgcb正确部署到Content文件夹,加载无报错,但渲染时仅显示Color参数对应的色块,仅当鼠标hover时纹理才会出现在屏幕左上角。
相关代码
Entity类代码
public class Entity { public Vector2 Position { get; set; } public Vector2 Diameters { get; set; } public float Angle { get; set; } public Texture2D EntityTexture { get; set; } public int EntityLayer { get; set; } public Entity(Vector2 position, Vector2 diameters, float angle, string spriteName, int entityTexture) { Position = position; Diameters = diameters; Angle = angle; EntityTexture = Holder.content.Load<Texture2D>(spriteName); EntityLayer = entityTexture; } public void DrawEntity() { if(EntityTexture != null) { Holder.spriteBatch.Draw(EntityTexture, Position, new Rectangle((int)(Position.X), (int)(Position.Y), (int)(Diameters.X), (int)(Diameters.Y)), Color.White, Angle, new Vector2(EntityTexture.Bounds.Width/2, EntityTexture.Bounds.Height/2), Holder.scale, SpriteEffects.None, EntityLayer); } } }
主类LoadContent()代码
Holder.content = this.Content; Holder.spriteBatch = new SpriteBatch(GraphicsDevice); _player = new Player(new Vector2(300, 300), new Vector2(64, 64), 0.0f, "player", 1);
主类Draw()方法代码
Holder.spriteBatch.Begin(); _player.DrawEntity(); Holder.spriteBatch.End(); base.Draw(gameTime);
Holder类代码
namespace SpaceInvaderPlusPlus { class Holder { public static SpriteBatch spriteBatch; public static ContentManager content; public static float scale = 1.0f; } }
已尝试的无效操作
- 给
spriteBatch.Begin()传入SpriteSortMode.Deferred、BlendState.AlphaBlend参数 - 将
SpriteEffects.None改为new SpriteEffects() - 给纹理添加透明背景并将
Color.White改为Color.Transparent(仅使色块变为透明,问题未解决)
问题根源与修复
核心问题
- 源矩形参数错误:
Draw方法的第三个参数是从纹理上截取的区域,你传入的new Rectangle((int)Position.X, (int)Position.Y, ...)把世界坐标当成了纹理UV坐标,导致截取的区域超出纹理范围,最终只显示纯色块。 - 层级参数超出范围:
layerDepth参数要求取值在**0(最上层)到1(最下层)**之间,你直接传入整数1会导致渲染排序异常,和hover时的异常显示相关。
修改后的DrawEntity方法
public void DrawEntity() { if(EntityTexture != null) { // 使用整个纹理作为渲染源 var sourceRect = EntityTexture.Bounds; // 将层级转换为0-1范围内的浮点数,可根据实际层级数量调整除数 float layerDepth = EntityLayer / 10f; Holder.spriteBatch.Draw( texture: EntityTexture, position: Position, sourceRectangle: sourceRect, color: Color.White, rotation: Angle, origin: new Vector2(EntityTexture.Width / 2f, EntityTexture.Height / 2f), scale: Holder.scale, effects: SpriteEffects.None, layerDepth: layerDepth ); } }
额外说明
- 如果需要将精灵缩放到指定的
Diameters尺寸,不要修改源矩形,而是通过计算缩放比例实现:scale = new Vector2(Diameters.X / EntityTexture.Width, Diameters.Y / EntityTexture.Height) - 若使用
SpriteSortMode.FrontToBack或BackToFront,必须保证layerDepth在0-1范围内,否则渲染顺序会混乱
内容的提问来源于stack exchange,提问作者brd
相关产品推荐
相关产品推荐

