public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
// Hold the dimensions of the screen as a Point
private Vector2 dimensions = new Vector2(1055, 635);
// Hold the scene layers in a list
private List<Scene> scenes = new List<Scene>();
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
//Initialize
// Create the window constraits
_graphics.PreferredBackBufferWidth = (int)dimensions.X;
_graphics.PreferredBackBufferHeight = (int)dimensions.Y;
_graphics.ApplyChanges();
Window.Title = "Random Colors";
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
// Add a new scene
scenes.Add(new ColorBox(Services, GraphicsDevice, new Vector2(200, 200), ColorTool.RandomColor()));
}
// Delete and dispose of the scenes
else if (Keyboard.GetState().IsKeyDown(Keys.Back) && scenes.Count != 0)
{
Scene toDelS = scenes[scenes.Count - 1];
scenes.RemoveAt(scenes.Count - 1);
toDelS.Dispose();
toDelS = null;
}
else if (Keyboard.GetState().IsKeyDown(Keys.C)) { System.GC.Collect(); }
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
// Render each scene
foreach(Scene s in scenes) { s.RenderToTarget(GraphicsDevice, _spriteBatch, gameTime); }
GraphicsDevice.Clear(Color.Wheat);
// Prepare the spritebatch
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend,
SamplerState.LinearClamp, DepthStencilState.Default,
RasterizerState.CullNone);
// Draw each scene to the menu
for (int i = 0; i < scenes.Count; i++)
{
_spriteBatch.Draw(scenes[i].RenderTarget, new Rectangle((105 * (i % 10) + 5), (i / 10) * 105 + 5, 100, 100), Color.White);
}
// End the draw function
_spriteBatch.End();
base.Draw(gameTime);
}
}
The Abstract Scene
abstract class Scene : IDisposable
{
/// <summary>
/// Implement Dispose
/// </summary>
// Calls Dispose(true)
protected bool isDisposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
if (Content != null)
{
Content.Unload();
Content.Dispose();
Content = null;
}
if (RenderTarget != null)
{
RenderTarget.Dispose();
RenderTarget = null;
}
}
isDisposed = true;
}
// What the scene is drawn to
public RenderTarget2D RenderTarget { get; private set; }
public ContentManager Content { get; private set; }
// Scene dimensions
public Vector2 SceneDimension { get; set; }
/// <summary>
/// Create a generic scene which hold objects, child scenes, and preforms actions, and draws to the screne
/// </summary>
/// <param name="service">The service provider for the scene</param>
/// <param name="GraphicsDevice">The source used to create a render target</param>
/// <param name="sceneDimension">The vector2 declaring the dimenstion of the screne</param>
public Scene(IServiceProvider service, GraphicsDevice GraphicsDevice, Vector2 sceneDimension)
{
SceneDimension = sceneDimension;
// Create a new content manager for just this scene
Content = new ContentManager(service, "Content");
// Create the graphics manager just for this scene
RenderTarget = new RenderTarget2D(GraphicsDevice, (int)sceneDimension.X, (int)sceneDimension.Y,
false, GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24);
}
public abstract Boolean Update(GameTime gameTime);
public abstract void RenderToTarget(GraphicsDevice GraphicsDevice, SpriteBatch spriteBatch, GameTime gameTime);
}
The Child
class ColorBox : Scene
{
Texture2D blankTex;
Color col1, col2;
Rectangle drawRec = new Rectangle(25,25,150,150);
/// <summary>
/// Dispose code
/// </summary>
protected override void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
// Dispose managed resources
blankTex.Dispose();
}
isDisposed = true;
// Call base class implementation.
base.Dispose(disposing);
}
public ColorBox(IServiceProvider service, GraphicsDevice graphicsDevice, Vector2 screenDim, Color c1) : base(service, graphicsDevice, screenDim)
{
// Load the texture
blankTex = Content.Load<Texture2D>("blank");
// Create the first and second color
col1 = c1;
col2 = ColorTool.CompositeColor(col1);
}
public override void RenderToTarget(GraphicsDevice GraphicsDevice, SpriteBatch spriteBatch, GameTime gameTime)
{
// Set the render target
GraphicsDevice.SetRenderTarget(RenderTarget);
GraphicsDevice.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };
// Refresh
GraphicsDevice.Clear(col1);
// Begin spritebatch
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.LinearWrap, null, null, default);
// Draw the square
spriteBatch.Draw(blankTex, drawRec, col2);
// Drop the spritebatch
spriteBatch.End();
// Drop the render target
GraphicsDevice.SetRenderTarget(null);
return;
}
public override bool Update(GameTime gameTime) { return true; }
}