Switch(scene, transition) covers the old scene, swaps at full coverage (hiding slow OnLoad), then reveals the new one. Built-in Fade and Wipe transitions draw through TransitionRenderer (BasicEffect quad, no SpriteBatch); custom transitions subclass Transition. Runs on unscaled time so it works while gameplay is paused; Switch during a transition replaces the pending target. Sample: Tab now fades into the stress scene and wipes back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
72 lines
3.0 KiB
C#
72 lines
3.0 KiB
C#
using Friflo.Engine.ECS;
|
|
using Microsoft.Xna.Framework;
|
|
using MrGameEng.Assets;
|
|
using MrGameEng.Core;
|
|
using MrGameEng.Graphics;
|
|
using MrGameEng.Input;
|
|
|
|
namespace MrGameEng.Sample.Scenes;
|
|
|
|
/// <summary>
|
|
/// Стресс-сцена: 100 000 спрайтов скачут в мире 4000×4000. Колесо — зум (чем дальше,
|
|
/// тем больше спрайтов в кадре), Tab — обратно в основную сцену. Цель: 60 FPS.
|
|
/// </summary>
|
|
public sealed class StressScene : Scene
|
|
{
|
|
private const int SpriteCount = 100_000;
|
|
private static readonly RectF WorldBounds = new(-2000f, -2000f, 4000f, 4000f);
|
|
|
|
protected override void OnLoad()
|
|
{
|
|
var assets = Context.Services.Get<AssetManager>();
|
|
var input = this.UseInput();
|
|
var actions = SampleInput.CreateActions(input);
|
|
|
|
var renderer = this.UseRenderer2D();
|
|
SampleLayers.EnsureRegistered(renderer);
|
|
|
|
var shapesTexture = assets.Load(GameAssets.Textures.Shapes);
|
|
var regions = new[]
|
|
{
|
|
new Texture2DRegion(shapesTexture, new Rectangle(0, 0, 32, 32)),
|
|
new Texture2DRegion(shapesTexture, new Rectangle(32, 0, 32, 32)),
|
|
new Texture2DRegion(shapesTexture, new Rectangle(0, 32, 32, 32)),
|
|
new Texture2DRegion(shapesTexture, new Rectangle(32, 32, 32, 32)),
|
|
};
|
|
|
|
var random = new Random(7);
|
|
for (var i = 0; i < SpriteCount; i++)
|
|
{
|
|
var sprite = new Sprite(regions[random.Next(regions.Length)]);
|
|
sprite.CenterOrigin();
|
|
var angle = random.NextSingle() * MathF.Tau;
|
|
Store.CreateEntity(
|
|
new Transform2D(
|
|
new Vector2(
|
|
random.NextSingle() * WorldBounds.Width + WorldBounds.Left,
|
|
random.NextSingle() * WorldBounds.Height + WorldBounds.Top),
|
|
scale: new Vector2(0.4f + random.NextSingle() * 0.6f)),
|
|
sprite,
|
|
new Velocity { Value = new Vector2(MathF.Cos(angle), MathF.Sin(angle)) * (30f + random.Next(150)) });
|
|
}
|
|
|
|
var camera = Store.CreateEntity(new Camera(Vector2.Zero, zoom: 0.3f));
|
|
|
|
UpdateSystems.Add(new BounceSystem(WorldBounds));
|
|
UpdateSystems.Add(new StressCameraSystem(camera, input));
|
|
UpdateSystems.Add(new SceneHotkeysSystem(Context, actions, () => new MainScene(), Transition.Wipe(0.8f, Color.DarkSlateBlue)));
|
|
UpdateSystems.Add(new TitleStatsSystem(Context, renderer, $"Stress {SpriteCount:N0}"));
|
|
}
|
|
|
|
/// <summary>Только зум колесом — чтобы регулировать число видимых спрайтов.</summary>
|
|
private sealed class StressCameraSystem(Entity cameraEntity, InputManager input)
|
|
: Friflo.Engine.ECS.Systems.BaseSystem
|
|
{
|
|
protected override void OnUpdateGroup()
|
|
{
|
|
ref var camera = ref cameraEntity.GetComponent<Camera>();
|
|
camera.Zoom = Math.Clamp(camera.Zoom * (1f + input.WheelDelta * 0.001f), 0.05f, 5f);
|
|
}
|
|
}
|
|
}
|