Search code examples
c#xnafile-browser

C# XNA - User Input


I am making 3D simulations with C# XNA, I use image\text files to load data.

I want to provide user the option to select a file which then my simulation will load and use. It's not possible with C# XNA.

I was able to embed the 3D XNA App in a WinForm using this tutorial, which worked for me but the problem is after that interaction based on keyboard is not smooth at all. It jut does not respond like a game any more.

How can I achieve file browsing and other things like buttons and and all with in a game?

I could have a logic to monitor the user input and use it to provide functionality like file browsing with in the game but that is too much trouble. Is there an easy was of achieving this. If not with XNA then may be some other way like DirectX


Solution

  • In regular XNA the Game class calls your Draw and Update functions regularly (usually at 60 frames per second).

    The XNA WinForms samples work slightly differently. There is no update/draw loop. Instead all you get is a Draw function. And that is only called when the control needs redrawing. This means that:

    1. You're not given a chance to regularly call Keyboard.GetState(), if that is how you are doing keyboard input.

    2. Even if you are using event-driven (non-XNA) input, your window won't be redrawn regularly so you might not actually see the results of your input until the XNA control is eventually redrawn much later.

    Fortunately there is a way to force the control to redraw rapidly. Take a look at the second of those WinForms samples. You will find it is animating (in other words: it is updating frequently). How does it do it? Take a look at this code from ModelViewerControl.cs:

    protected override void Initialize()
    {
        // Start the animation timer.
        timer = Stopwatch.StartNew();
    
        // Hook the idle event to constantly redraw our animation.
        Application.Idle += delegate { Invalidate(); };
    }
    

    It uses a Stopwatch to track how much time has elapsed (because there's no Game class to do it for you). And it invalidates on the Application.Idle event - in other words, whenever it's not busy processing something, it asks to be redrawn.

    (Of course, this is already explained in the documentation for that first WinForms sample. At the bottom, under "Animation".)

    Alternative bonus answer: There is nothing stopping you from making use of OpenFileDialog from WinForms within a regular XNA game. Just add a reference to System.Windows.Forms, create an instance of the object, set the appropriate properties on it, and call ShowDialog().