HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Improving XNA's default project template

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
templatexnadefaultprojectimproving

Problem

I hope this isn't getting annoying, but I've asked a lot of questions about improving my game lately:

  • How can I improve my game project design?



  • Using the observer pattern with collision detection



  • Is this a good way to cascade a property?



  • How should I implement my domain model?



  • Setting up keyboard bindings using JSON and reflection



  • Setting up keyboard bindings using JSON (no reflection!)



  • Get array of pressed buttons using extension method



No, you don't have to read all of those. I'm starting to think all my questions stem from problems I have with XNA's default project template. After creating a new Windows game project in Visual Studio, this is what it gives you:

static class Program
{
    /// 
    /// The main entry point for the application.
    /// 
    static void Main(string[] args)
    {
        using (Game1 game = new Game1())
        {
            game.Run();
        }
    }
}


```
///
/// This is the main type for your game
///
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

///
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
///
protected override void Initialize()
{
// TODO: Add your initialization logic here

base.Initialize();
}

///
/// LoadContent will be called once per game and is the place to load
/// all of your content.
///
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

// TODO: use

Solution

I haven't done enough XNA to really get to the core of this question, I hope to see this reviewed from an XNA perspective.

I'll only make a few observations about the Program class.
Main()

Looking at the Main method and the Program class, I see mixed abstraction levels and some temporal coupling, I'm tempted to move stuff around a bit:

public static class Program
{
    private static void Main(string[] args)
    {
        var data = GetGameFileData(); // temporal coupling removed!
        
        // extracted variables improve readability...
        var graphics = new Graphics(data.Settings.DisplaySettings, 
                                    data.Level, 
                                    data.Player);

        var input = new Input(data.Settings.GamePadSettings, 
                              data.Settings.KeyboardSettings, 
                              data.Level, 
                              data.Player);

        // ...and makes the intent clearer:
        using (var game = new MyGame(graphics, input))
        {
            game.Run();
            data.Save();
        }
    }

    private static GameFileData GetGameFileData()
    {
        var result = new GameFileData();
        result.Load();

        return result;
    }
}


private class GameFileData
{
    private readonly IFileHandler _fileHandler;

    public GameFileData() 
        : this(new FileHandler()) 
    {
    }

    // probably YAGNI
    public GameFileData(IFileHandler fileHandler)
    {
        _fileHandler = fileHandler;
    }

    public Settings Settings { get; private set; }
    public Level Level { get; private set; }
    public Entity Player { get; private set; }

    public void Load()
    {
        Settings = _fileHandler.Read("settings.json"),
        Level = _fileHandler.Read("level.json"),
        Player = _fileHandler.Read("player.json")
    }

    public void Save()
    {
        _fileHandler.Write("level.json", Level);
        _fileHandler.Write("player.json", Player);
    }
}


Nitpick

new Graphics( settings.DisplaySettings, level, player )
fileHandler.Write( "player.json", player );


If this is really how much whitespace your actual code has, ...you're fighting the IDE to achieve it - Visual Studio automatically removes these spaces then you hit ; or when you close a scope with }.

new Graphics(settings.DisplaySettings, level, player)
fileHandler.Write("player.json", player);

Code Snippets

public static class Program
{
    private static void Main(string[] args)
    {
        var data = GetGameFileData(); // temporal coupling removed!
        
        // extracted variables improve readability...
        var graphics = new Graphics(data.Settings.DisplaySettings, 
                                    data.Level, 
                                    data.Player);

        var input = new Input(data.Settings.GamePadSettings, 
                              data.Settings.KeyboardSettings, 
                              data.Level, 
                              data.Player);

        // ...and makes the intent clearer:
        using (var game = new MyGame(graphics, input))
        {
            game.Run();
            data.Save();
        }
    }

    private static GameFileData GetGameFileData()
    {
        var result = new GameFileData();
        result.Load();

        return result;
    }
}
private class GameFileData
{
    private readonly IFileHandler _fileHandler;

    public GameFileData() 
        : this(new FileHandler()) 
    {
    }

    // probably YAGNI
    public GameFileData(IFileHandler fileHandler)
    {
        _fileHandler = fileHandler;
    }

    public Settings Settings { get; private set; }
    public Level Level { get; private set; }
    public Entity Player { get; private set; }

    public void Load()
    {
        Settings = _fileHandler.Read<Settings>("settings.json"),
        Level = _fileHandler.Read<Level>("level.json"),
        Player = _fileHandler.Read<Entity>("player.json")
    }

    public void Save()
    {
        _fileHandler.Write("level.json", Level);
        _fileHandler.Write("player.json", Player);
    }
}
new Graphics( settings.DisplaySettings, level, player )
fileHandler.Write( "player.json", player );
new Graphics(settings.DisplaySettings, level, player)
fileHandler.Write("player.json", player);

Context

StackExchange Code Review Q#42472, answer score: 2

Revisions (0)

No revisions yet.