-
Notifications
You must be signed in to change notification settings - Fork 37
/
Game.cs
148 lines (126 loc) · 4.67 KB
/
Game.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System.IO.Compression;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json.Serialization;
using Arch.Core;
using Arch.Core.Extensions;
using Arch.Bus;
using Arch.Core.Extensions.Dangerous;
using Arch.Core.Utils;
using Arch.Persistence;
using Arch.Relationships;
using MessagePack;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using NUnit.Framework;
using Schedulers;
using Utf8Json;
using Utf8Json.Formatters;
using Utf8Json.Resolvers;
namespace Arch.Extended;
/// <summary>
/// The <see cref="Game"/> which represents the game and implements all the important monogame features.
/// </summary>
public class Game : Microsoft.Xna.Framework.Game
{
// The world and a job scheduler for multithreading
private World _world;
private JobScheduler _jobScheduler;
// Our systems processing entities
private System.Group<GameTime> _systems;
private DrawSystem _drawSystem;
// Monogame stuff
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
private Texture2D _texture2D;
private Random _random;
public Game()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// Setup texture and randomness
_random = new Random();
_texture2D = TextureExtensions.CreateSquareTexture(GraphicsDevice, 10);
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
_spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void BeginRun()
{
base.BeginRun();
// Create world & JobScheduler for multithreading
_world = World.Create();
_jobScheduler = new(
new JobScheduler.Config
{
ThreadPrefixName = "Arch.Samples",
ThreadCount = 0,
MaxExpectedConcurrentJobs = 64,
StrictAllocationMode = false,
}
);
World.SharedJobScheduler = _jobScheduler;
// Spawn in entities with position, velocity and sprite
for (var index = 0; index < 1000; index++)
{
_world.Create(
new Position{ Vector2 = _random.NextVector2(GraphicsDevice.Viewport.Bounds) },
new Velocity{ Vector2 = _random.NextVector2(-0.25f,0.25f) },
new Sprite{ Texture2D = _texture2D, Color = _random.NextColor() }
);
}
// Serialize world and deserialize it back. Just for showcasing the serialization, its actually not necessary.
var archSerializer = new ArchJsonSerializer(new SpriteSerializer{GraphicsDevice = GraphicsDevice});
var worldJson = archSerializer.ToJson(_world);
_world = archSerializer.FromJson(worldJson);
// Create systems, running in order
_systems = new System.Group<GameTime>(
"Systems",
new MovementSystem(_world, GraphicsDevice.Viewport.Bounds),
new ColorSystem(_world),
new DebugSystem(_world)
);
_drawSystem = new DrawSystem(_world, _spriteBatch); // Draw system must be its own system since monogame differentiates between update and draw.
// Initialize systems
_systems.Initialize();
_drawSystem.Initialize();
}
protected override void Update(GameTime gameTime)
{
// Exit game on press
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit();
// Forward keyboard state as an event to another handles by using the eventbus
var @event = (_world, Keyboard.GetState());
EventBus.Send(ref @event);
// Update systems
_systems.BeforeUpdate(in gameTime);
_systems.Update(in gameTime);
_systems.AfterUpdate(in gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
_graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// Update draw system and draw stuff
_drawSystem.BeforeUpdate(in gameTime);
_drawSystem.Update(in gameTime);
_drawSystem.AfterUpdate(in gameTime);
base.Draw(gameTime);
}
protected override void EndRun()
{
base.EndRun();
// Destroy world and shutdown the jobscheduler
World.Destroy(_world);
_jobScheduler.Dispose();
// Dispose systems
_systems.Dispose();
}
}