H073.TheaterKit
1.0.1
Prefix Reserved
dotnet add package H073.TheaterKit --version 1.0.1
NuGet\Install-Package H073.TheaterKit -Version 1.0.1
<PackageReference Include="H073.TheaterKit" Version="1.0.1" />
paket add H073.TheaterKit --version 1.0.1
#r "nuget: H073.TheaterKit, 1.0.1"
// Install H073.TheaterKit as a Cake Addin #addin nuget:?package=H073.TheaterKit&version=1.0.1 // Install H073.TheaterKit as a Cake Tool #tool nuget:?package=H073.TheaterKit&version=1.0.1
TheaterKit
TheaterKit is a .NET library designed for advanced scene management in MonoGame projects. This package provides a structured approach to managing, loading, and transitioning between game scenes seamlessly, including support for loading screens and asynchronous scene transitions.
Installation
To install TheaterKit, you can add it to your project as a NuGet package:
dotnet add package TheaterKit
Components
Scene
Scene
is an abstract base class that represents individual game scenes. To create a scene, inherit from Scene
and override its methods to define the specific behavior, content, and rendering for that scene.
Each Scene
provides:
- Lifecycle Methods:
Initialize
: Sets up the scene’s initial state.LoadContent
: Loads assets like textures, sounds, etc., necessary for the scene.Update
: Contains the logic for each frame’s updates.Draw2D
andDraw3D
: Allows separation between 2D and 3D rendering.UnloadContent
: Frees up resources once a scene is no longer in use.
Example of a custom Scene
implementation:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
public class MainMenuScene : Scene
{
public MainMenuScene(Game game) : base("MainMenu", game) { }
public override void Initialize()
{
// Set up scene-specific variables here
}
public override void LoadContent()
{
// Load textures, fonts, or other assets needed for the main menu
}
protected override void Draw2D(SpriteBatch spriteBatch, GameTime gameTime)
{
// Render 2D elements like buttons or backgrounds
}
protected override void Draw3D(GameTime gameTime)
{
// Optional 3D rendering, if needed
}
public override void Update(GameTime gameTime)
{
// Update menu-specific logic, such as navigation and animations
}
}
SceneManager
SceneManager
is a singleton class responsible for handling scene transitions, managing scene lifecycles, and providing an optional loading screen between scenes.
Key methods and properties:
- Add(Scene, bool): Adds a scene to the manager. Optionally overwrites existing scenes with the same name.
- Stage(string): Stages a scene for activation, loading its content in the background.
- StageAsync(string, int, int): Asynchronously stages a scene, with
pre
andpost
delays to customize the transition duration. - Grab(): Activates the staged scene, managing deactivation and unloading of the previous scene.
- OnLoadComplete: An event triggered when a staged scene completes loading.
Loading Scenes and Transitions
The SceneManager
supports using a LoadingScene
to provide visual feedback during scene loading. This can be helpful for complex scenes with many assets.
- Setting a Loading Scene: Assign a custom loading screen to
LoadingScene
property on theSceneManager
. This screen will be shown while new scenes load asynchronously. OnLoadComplete
Event: Subscribe to this event to handle actions once the loading of a staged scene finishes.
Example:
// Define and add scenes
var mainMenu = new MainMenuScene(game);
var gameplayScene = new GameplayScene(game);
var loadingScene = new LoadingScene(game); // Custom scene for showing loading visuals
SceneManager.Instance.Add(mainMenu);
SceneManager.Instance.Add(gameplayScene);
SceneManager.Instance.LoadingScene = loadingScene; // Assign loading screen
// Stage and transition to the gameplay scene with a loading screen
await SceneManager.Instance.StageAsync("GameplayScene", pre: 500, post: 500);
SceneManager.Instance.Grab(); // Activates the loaded scene
Full Example with LoadingScene and Camera2D
This example demonstrates how to create a LoadingScene
that uses a Camera2D
to manage camera position, zoom, and rotation, and animate a loading sprite.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TheaterKit;
public class Camera2D
{
public Vector2 Position;
public float Zoom;
public float Rotation;
private Viewport _viewport;
public Camera2D(Viewport viewport)
{
_viewport = viewport;
Zoom = 1.0f;
Rotation = 0.0f;
Position = Vector2.Zero;
}
public Matrix GetViewMatrix()
{
return Matrix.CreateTranslation(new Vector3(-Position.X, -Position.Y, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));
}
public void CenterOn(Vector2 target)
{
Position = target;
}
}
public class LoadingScene : TheaterKit.Scene
{
private Camera2D _camera;
private Texture2D _spriteSheet;
private int _currentFrame;
private int _totalFrames;
private readonly float _frameTime = 0.1f;
private float _timer = 0f;
private const int FrameWidth = 128;
private const int FrameHeight = 128;
public LoadingScene(Game game, string contentDirectory = "Content")
: base("Loading", game, contentDirectory) { }
public override void Initialize()
{
_camera = new Camera2D(GraphicsDevice.Viewport) { Zoom = 5f };
_currentFrame = 0;
TheaterKit.SceneManager.Instance.OnLoadComplete += TheaterKit.SceneManager.Instance.Grab;
}
public override void LoadContent()
{
_spriteSheet = Content.Load<Texture2D>("loader");
_totalFrames = _spriteSheet.Width / FrameWidth;
}
public override void Update(GameTime gameTime)
{
_timer += (float)gameTime.ElapsedGameTime.TotalSeconds;
// Switch frame after each interval
if (_timer >= _frameTime)
{
_currentFrame = (_currentFrame + 1) % _totalFrames;
_timer = 0f;
}
}
protected override void Draw2D(SpriteBatch spriteBatch, GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
var sourceRectangle = new Rectangle(_currentFrame * FrameWidth, 0, FrameWidth, FrameHeight);
spriteBatch.Begin(transformMatrix: _camera.GetViewMatrix(), samplerState: SamplerState.PointWrap);
spriteBatch.Draw(_spriteSheet, Vector2.Zero, sourceRectangle, Color.White, 0f,
new Vector2(FrameWidth / 2, FrameHeight / 2), 1f, SpriteEffects.None, 0f);
spriteBatch.End();
}
}
Full Game Example
In a typical MonoGame setup, the Game
class might handle scene transitions like so:
protected override void Initialize()
{
var mainMenu = new MainMenuScene(this);
var gameplayScene = new GameplayScene(this);
var loadingScene = new LoadingScene(this);
SceneManager.Instance.Add(mainMenu);
SceneManager.Instance.Add(gameplayScene);
SceneManager.Instance.LoadingScene = loadingScene;
SceneManager.Instance.Stage("MainMenu");
SceneManager.Instance.Grab();
base.Initialize();
}
protected override void Update(GameTime gameTime)
{
SceneManager.Instance.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
SceneManager.Instance.Draw(spriteBatch, gameTime);
base.Draw(gameTime);
}
// Transition to GameplayScene with loading
private async void StartGame()
{
await SceneManager.Instance.StageAsync("GameplayScene", pre: 1000, post: 1000);
SceneManager.Instance.Grab();
}
Contributing
Contributions are welcome! Submit issues or pull requests to improve the library.
License
This project is licensed under the MIT License.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- MonoGame.Framework.DesktopGL (>= 3.8.2.1105)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.