iOS MonoGame应用启动屏后黑屏 如何添加可手动移除的全屏过渡图
问题1解答
可以直接使用Assets.xcassets下的图片资源,iOS会自动根据当前设备的屏幕倍率、设备类型选择对应适配版本的资源,你只需要把不同尺寸的图片放到对应Image Set的1x/2x/3x、iPhone/iPad插槽即可,加载时使用UIImage.FromImageNamed("你的Image Set名称")方法,不需要手动指定后缀。
比你当前用的UIImage.FromFile更适配原生iOS资源管理规则,不需要自行处理路径和适配逻辑。
问题2解答
报错是因为UIApplicationDelegate(你继承的Program父类)本身没有View属性,你需要先获取应用的根窗口、以及MonoGame运行后挂载的根视图控制器的视图,修复步骤:
- 给Program类添加UIWindow的重写属性
- 替换所有直接调用
View的代码为Window.RootViewController.View
问题3解答
你现有的事件通知逻辑是可行的,只需要补全事件绑定、确保UI操作在主线程执行即可,完整修改后的代码如下:
修正后的Program.cs
using System; using Foundation; using UIKit; namespace MyProject { [Register("AppDelegate")] class Program : UIApplicationDelegate { private static Game1 game; private UIImageView LogoImage; // 新增Window属性,MonoGame会自动赋值 public override UIWindow Window { get; set; } public override void FinishedLaunching(UIApplication app) { global::Xamarin.Forms.Forms.Init(); RunGame(); // 先运行游戏,初始化根视图控制器 // 初始化Logo图片,用Assets资源就替换为UIImage.FromImageNamed("Launchscreenlogo") LogoImage = new UIImageView(UIImage.FromFile("Launchscreenlogo.png")); LogoImage.Tag = 1234; // 适配全屏,设置填充模式避免变形 LogoImage.ContentMode = UIViewContentMode.ScaleAspectFill; LogoImage.Frame = Window.RootViewController.View.Bounds; // 加到根视图最上层 Window.RootViewController.View.AddSubview(LogoImage); Window.RootViewController.View.BringSubviewToFront(LogoImage); // 绑定移除Logo的事件 game.RemoveLogo += G_RemoveLogo; } private void RunGame() { if (game == null) { game = new Game1(); } // 启动MonoGame游戏循环 game.Run(); } private void G_RemoveLogo(object sender, System.EventArgs e) { // UI操作必须放在主线程执行 InvokeOnMainThread(() => { var LogoView = Window.RootViewController.View.ViewWithTag(1234); if (LogoView != null) { LogoView.RemoveFromSuperview(); // 可选:加淡入淡出动画过渡更自然 // UIView.Animate(0.3, () => { LogoView.Alpha = 0; }, () => { LogoView.RemoveFromSuperview(); }); } }); } } }
修正后的Game1.cs
你现有的Game1代码逻辑已经可以满足需求,只需要在你想要移除Logo的时机触发RemoveLogo事件即可,建议把触发时机放在第一次Draw执行完成之后,避免移除后还有短时间黑屏:
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; namespace MyProject { public class Game1 : Game { private GraphicsDeviceManager _graphics; private SpriteBatch _spriteBatch; public event EventHandler RemoveLogo; // 标记是否已经移除过Logo,避免重复触发 private bool _isLogoRemoved = false; public Game1() { _graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { base.Initialize(); } protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: 加载你的游戏资源 } protected override void Update(GameTime gameTime) { base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: 你的绘制逻辑 base.Draw(gameTime); // 第一次绘制完成后再移除Logo,完全避免黑屏 if (!_isLogoRemoved) { RemoveLogo?.Invoke(this, EventArgs.Empty); _isLogoRemoved = true; } } } }
内容的提问来源于stack exchange,提问作者harry_mitch
相关产品推荐
相关产品推荐

