patterncsharpMinor
Improving XNA's default project template
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:
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:
```
///
/// 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
- 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
Main()
Looking at the
Nitpick
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
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.