c# - LoadContent 在 AndroidGameActivity 中运行时的启动/加载屏幕

标签 c# android mono monogame

首先,我想说的是,总体而言,我对 C# 和 Monogame 真的很陌生。

我的问题是显示屏幕。 我有一个名为 loadingsplash.xml 的布局资源,我想在游戏 Activity 运行 LoadContent() 时显示它;

流程图为: Main.xml:在 LoadContent > GameActivity 期间按下按钮 > ProgressDialog

我要的流程图: Main.xml:按下按钮 > 在 LoadContent > GameActivity 期间显示 loadingsplash.xml

MainMenu.cs

[Activity( Label = "theApp", Theme = "@android:style/Theme.NoTitleBar.Fullscreen", MainLauncher=true, ScreenOrientation=Android.Content.PM.ScreenOrientation.Landscape)]

public class MainMenu : Activity, IDialogInterfaceOnClickListener
{
......
void GoButton_Click(object sender, EventArgs e)
{
    Intent theActivity = new Intent(this, typeof(GameActivity));
    StartActivity(theActivity);
}

theActivity.cs

namespace theApp
{
    [Activity(Theme = "@android:style/Theme.NoTitleBar.Fullscreen", Label = "theApp", Icon = "@drawable/icon", ScreenOrientation = Android.Content.PM.ScreenOrientation.Landscape, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden)]

    public class GameActivity : Microsoft.Xna.Framework.AndroidGameActivity, IDialogInterfaceOnClickListener
    {
        myGame game = null;
        static GameBundle gameBundle = null;
        ProgressDialog dialog;
        const int WindowID = 10001;

        protected override void OnCreate(Bundle bundle)
        {
            loadedOnce = true;
//this works
//
//dialog = new ProgressDialog(this);
//dialog.SetMessage("Loading...");
//dialog.Show();
//

//Loading Splash screen invocation code goes here?

    if (game == null)
       {
         myGame.Activity = this;
         base.OnCreate (bundle);
         game = new myGame();
         game.NativeCommand = ProcessCommand;
         game.Window.GraphicsMode = new AndroidGraphicsMode(0, 4, 0, 0, 0, false);
         game.Window.Id = WindowID;

                if (gameBundle == null)
                {
                    game.Run();
                }
                else
                {
                    if (gameBundle != null)
                    {
                        resumeGame.Show();
                    }
                }
            }
            SetContentView(game.Window);
        }

myGame.cs

public class myGame : Microsoft.Xna.Framework.Game
{

public myGame()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Resources/Drawable";
        unloading = false;
        graphics.PreferMultiSampling = true;
        graphics.IsFullScreen = true;
        graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
    }

    protected override void Initialize()
    {
        graphics.SynchronizeWithVerticalRetrace = true;
        graphics.PreferredBackBufferWidth =  800;
        graphics.PreferredBackBufferHeight = 480;
        screenManager = new ScreenManager(this, 800, 480);
        base.Initialize();
    }

    bool loaded = false;
    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(this.GraphicsDevice);
        font = Content.Load<SpriteFont>("Arial");
        GraphicsDevice.Clear(Color.Black);
        ThreadPool.QueueUserWorkItem(state =>
            {
                            ...
                            loaded = true;
            });

如果我使用 setContentView(Resource.Layout.LoadingSplash) 调用 LoadingSplash;在 base.OnCreate(bundle) 之前我得到一个异常,必须调用 requestFeature。

最佳答案

我使用以下实现。我计划在不久的将来在 NuGet 中公开这个包,这样你就可以在我的存储库中查看它 https://github.com/AzuxirenLeadGuy/Azuxiren.MG (请为我的仓库加注星标)

无论如何,我已经在代码中这样做了。

首先我定义了一个IScreen接口(interface)如下:

public interface IScreen
{
    void LoadContent();
    void Update(GameTime gt);
    void Draw(GameTime gt);
}

接下来我定义了我的游戏类如下:

public abstract class AMGC<StartScreen,LoadScreen> : Game where StartScreen:IScreen,new() where LoadScreen:IScreen,new()
{
    public GraphicsDeviceManager graphics;
    internal bool isLoading;
    internal IScreen CurrentScreen,LoadingScreen;
    public AMGC()
    {
        graphics = new GraphicsDeviceManager(this);
        isLoading = false;
    }
    protected override void Initialize()
    {
        CurrentScreen = new StartScreen();
        LoadingScreen = new LoadScreen();
        base.Initialize();
    }
    protected override void LoadContent()
    {
        CurrentScreen.LoadContent();
        LoadingScreen.LoadContent();
        base.LoadContent();
    }
    protected override void Draw(GameTime gt)
    {
        if (isLoading) LoadingScreen.Draw(gt);
        else CurrentScreen.Draw(gt);
        base.Draw(gt);
    }
    protected override void Update(GameTime gameTime)
    {
        if (isLoading) LoadingScreen.Update(gameTime);
        else CurrentScreen.Update(gameTime);
        base.Update(gameTime);
    }
    public void ScreenLoad<T>() where T : IScreen, new()
    {
        isLoading = true;
        Task.Run(() =>
            {
                var screen = new T();
                screen.LoadContent();
                CurrentScreen = screen;
                isLoading = false;
            }
        );
    }
}

现在有了该代码,您就可以开始了。现在您的游戏是在 IScreen 实例中设计的。假设您制作了一个 LogoScreen(游戏开始时显示您游戏的 Logo )、MenuScreen(游戏的主菜单)和 SplashScreen(您想要的通用启动画面,显示游戏的“正在加载...”)。

您的游戏对象将像这样创建:

AMGC game=new AMGC<LogoScreen, SplashScreen>();

并且在 LogoScreen 中,当您必须从 LogoScreen 更改为 MenuScreen 时,您必须在屏幕更改逻辑中使用它。

game.ScreenLoad<MenuScreen>();

请注意,为此,游戏实例必须是全局的,以便可以从您的 LogoScreen 内部访问。

关于c# - LoadContent 在 AndroidGameActivity 中运行时的启动/加载屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20166496/

相关文章:

c# - IronPython 导入异常 : No module named logging

c# - 需要从 C# 创建一个 PDF 文件,并将另一个 PDF 文件作为背景水印

android - 为什么 startActivityForResult 不起作用?

单声道中的 C# MessageBox 没有响应

c# - Unity3d:仅将幅度钳制到 x 轴

android - 为什么 Eclipse 不在 gen 文件夹中生成 'R'?

c# - ADX : cannot ingest data with JSON mappings from . 网络 SDK

c# - 如何查找鼠标单击是否在 wf 面板中呈现的图像上?

c# - Azure DocumentDB异步请求问题

java - 在不创建全新列表类的情况下将 Arraylist 转换为 Observable 列表?