3

First of all I want to say that I'm really new to C# and Monogame in general.

My problem is with displaying a screen. I have a layout resource called loadingsplash.xml and want to show it while the Game activity is running LoadContent();

Flow diagram is: Main.xml: on button press > ProgressDialog during LoadContent > GameActivity

Flow diagram I want: Main.xml: on button press > show loadingsplash.xml during LoadContent > GameActivity

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;
            });

If I invoke the LoadingSplash with setContentView(Resource.Layout.LoadingSplash); before base.OnCreate(bundle) I get an exception with requestFeature must be called.

user3019799
  • 309
  • 3
  • 7

2 Answers2

1

I use the following implementation. I plan to expose this package in NuGet in the near future so you can check it on my repository at https://github.com/AzuxirenLeadGuy/Azuxiren.MG (Please Star my repository)

Anyways, I have done this in the Code.

First I have defined an interface IScreen as follows:

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

Next I have defined my game class as follows:

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;
            }
        );
    }
}

Now with that code you're good to go. Now your game is designed in IScreen instances. Suppose you make a LogoScreen (Starting of the game showing the Logos of your Game), MenuScreen (Main menu of the game) and SplashScreen (Your intended universal Splash Screen showing "Now Loading..." for the Game).

Your Game object will be creates like this:

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

and in the LogoScreen, when you have to change from LogoScreen to MenuScreen you will have to use this in the screen changing logic.

game.ScreenLoad<MenuScreen>();

Please note that for this, the game instance must be global in order to be accessible from inside your LogoScreen.

AzuxirenLeadGuy
  • 2,470
  • 1
  • 16
  • 27
0

For someone who is still looking for the answer of this question, I would recommend that you shouldn't use separate screen by using different xml file, just manipulate it in Monogame itself.

Please have a look at my answer in this post: https://stackoverflow.com/a/55667101/8594783

Silver
  • 482
  • 2
  • 6