MonoGame: пошаговый урок — создаём первую 2D-игру
MonoGame — это бесплатный открытый фреймворк для .NET, на котором 2D- и 3D-игры пишут на C#; это поддерживаемое сообществом продолжение Microsoft XNA. В этом уроке вы соберёте первый проект MonoGame с нуля: установите .NET SDK, создадите проект командой dotnet new, разберёте игровой цикл Game1, загрузите текстуру, нарисуете спрайт через SpriteBatch и будете двигать его клавишами. В конце у вас будет окно со спрайтом игрока, которым можно управлять, и понятный путь к столкновениям, анимации и звуку.
MonoGame — это бесплатный открытый фреймворк для .NET, на котором 2D- и 3D-игры пишут на C#; это поддерживаемое сообществом продолжение Microsoft XNA. В этом уроке вы пройдёте путь от пустой папки до окна со спрайтом игрока, которым управляете стрелками, и заодно разберёте те части MonoGame, которые используются в каждой игре: шаблон проекта, игровой цикл, загрузку текстур, отрисовку через SpriteBatch и ввод с клавиатуры.
Ни движок, ни Visual Studio не нужны. Достаточно .NET SDK и текстового редактора. Актуальный стабильный выпуск MonoGame — 3.8.4.1 (июнь 2025 года); версия 3.8.5 доступна в виде preview, но пока не выпущена как стабильная.
Что мы построим
Минимальную, но законченную игру на MonoGame: окно 800×600 со спрайтом, который перемещается при нажатии стрелок. Это покрывает примерно 80% того, что делает любая 2D-игра на MonoGame, — загрузить изображение, отрисовать его каждый кадр и считать ввод, чтобы что-то изменить. Столкновения, анимация и звук дальше надстраиваются на тот же цикл.
Шаг 0 — установите .NET SDK
MonoGame работает поверх .NET, поэтому установите .NET 8 SDK (или новее) со страницы dotnet.microsoft.com/download. Проверьте, что всё работает:
dotnet --version
Эта единственная команда — вся системная настройка, нужная MonoGame. Сам фреймворк подтянется через NuGet при создании проекта, отдельный установщик не требуется.
Шаг 1 — создайте проект
MonoGame распространяет шаблоны проектов как пакет NuGet. Установите их один раз:
dotnet new install MonoGame.Templates.CSharp
Затем создайте проект DesktopGL — кроссплатформенный шаблон под Windows, macOS и Linux:
dotnet new mgdesktopgl -o MyFirstGame
cd MyFirstGame
mgdesktopgl — короткое имя шаблона DesktopGL. Есть и другие шаблоны под конкретные платформы: mgwindows (Windows, DirectX), mgandroid и mgios. Для первой игры DesktopGL — правильный выбор, потому что он работает везде, где вы разрабатываете.
Шаг 2 — как устроен Game1.cs
Откройте Game1.cs. Шаблон создаёт класс, построенный вокруг четырёх методов, — это игровой цикл, на котором держится любая игра на MonoGame:
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize() { base.Initialize(); }
protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); }
protected override void Update(GameTime gameTime) { base.Update(gameTime); }
protected override void Draw(GameTime gameTime) { }
}
Четыре метода запускаются по строгому циклу, унаследованному от XNA:
| Метод | Когда вызывается | Что в нём делают |
|---|---|---|
Initialize | Один раз, при старте | Настройка состояния, не связанного с графикой, запрос сервисов |
LoadContent | Один раз, при старте | Загрузка текстур, шрифтов, звуков |
Update | Каждый кадр | Чтение ввода, перемещение объектов, игровая логика |
Draw | Каждый кадр | Отрисовка всего на экран |
Цикл идёт так: Update → Draw → Update → Draw, десятки раз в секунду. Держите логику в Update, а отрисовку в Draw — и вы получаете структуру игры.
Шаг 3 — загрузите текстуру
Добавьте PNG-изображение в папку проекта (например, player.png; подойдёт любая небольшая квадратная картинка). В MonoGame загрузить его можно двумя способами. Для первой игры быстрее всего обойтись без конвейера контента и прочитать файл напрямую:
private Texture2D _playerTexture;
private Vector2 _playerPosition;
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
_playerTexture = Texture2D.FromFile(GraphicsDevice, "player.png");
_playerPosition = new Vector2(400, 300);
}
Texture2D.FromFile читает PNG во время работы, без шага сборки. Альтернатива — конвейер контента MonoGame (MGCB): он компилирует ресурсы в оптимизированные файлы .xnb, которые загружаются через Content.Load<Texture2D>("player"). Конвейер быстрее во время работы и обязателен для шейдеров и эффектов (.fx), но для первого проекта прямая загрузка PNG позволяет сосредоточиться на игровом цикле. Перейти на конвейер можно позже.
Шаг 4 — нарисуйте спрайт
SpriteBatch — основной инструмент 2D-отрисовки в MonoGame. Каждый кадр открывайте его, рисуйте и закрывайте:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
_spriteBatch.Begin();
_spriteBatch.Draw(_playerTexture, _playerPosition, Color.White);
_spriteBatch.End();
base.Draw(gameTime);
}
Clear очищает экран в каждом кадре (классический васильковый фон из XNA). Между Begin и End SpriteBatch собирает вызовы отрисовки и эффективно отправляет их на видеокарту, поэтому все вызовы Draw за кадр помещайте внутрь одной пары Begin/End.
Шаг 5 — двигайте спрайт клавишами
Теперь заставьте спрайт реагировать на ввод. В Update считывайте состояние клавиатуры и меняйте позицию:
protected override void Update(GameTime gameTime)
{
var keyboard = Keyboard.GetState();
float speed = 200f * (float)gameTime.ElapsedGameTime.TotalSeconds;
if (keyboard.IsKeyDown(Keys.Left)) _playerPosition.X -= speed;
if (keyboard.IsKeyDown(Keys.Right)) _playerPosition.X += speed;
if (keyboard.IsKeyDown(Keys.Up)) _playerPosition.Y -= speed;
if (keyboard.IsKeyDown(Keys.Down)) _playerPosition.Y += speed;
base.Update(gameTime);
}
Тут важны две вещи. Во-первых, Keyboard.GetState() возвращает текущее состояние всех клавиш, а IsKeyDown проверяет одну. Во-вторых, перемещение умножается на ElapsedGameTime, поэтому скорость считается в секунду, а не в кадр — игрок движется с одинаковой скоростью и на ноутбуке с 60 Гц, и на мониторе с 144 Гц. Приучите себя к этому с первого же урока, и вы избежите целого класса багов в духе «на новом компьютере игра летит слишком быстро».
Шаг 6 — запустите игру
dotnet run
Откроется окно 800×600: васильковый фон очищается каждый кадр, а спрайт перемещается стрелками. Перед вами работающая игра на MonoGame. Полный Game1.cs — это те же четыре метода, собранные вместе.
Куда двигаться дальше
Отсюда любая 2D-возможность — это надстройка над тем же циклом:
- Столкновения — в
Updateпроверяйте прямоугольники двух спрайтов черезRectangle.Intersects. - Анимация — храните массив прямоугольников-кадров на спрайт-листе и сдвигайте индекс по таймеру.
- Звук — загрузите
SoundEffectчерез конвейер контента и вызовите.Play(). - Текст — загрузите
SpriteFontи выводите строки через_spriteBatch.DrawString. - Шейдеры — напишите эффект
.fx, скомпилируйте его через MGCB и применяйте вSpriteBatch.
Когда дойдёте до того, что нужны редактор сцен, тайловые карты и визуальная логика вместо рукописного кода, — тут и пригождается инструмент, построенный на MonoGame. См. 8 инструментов MonoGame, которыми пользуются профессионалы, истории и уроки инди-разработчиков на MonoGame и как выпустить игру на MonoGame в одиночку.
Частые ошибки
- Логика внутри
Draw. Ввод и перемещение держите вUpdate.Drawдолжен только отображать текущее состояние. - Забыли умножить перемещение на длительность кадра. Движение начинает зависеть от частоты кадров и на разных машинах идёт с разной скоростью.
- Несколько пар
SpriteBatchза кадр. Одна параBegin/Endна батч обходится дешевле, чем множество. - Вызов
Content.Loadв каждом кадре. Грузите один раз вLoadContentи храните ссылку; загрузка в каждом кадре перегружает память. - Сырые пиксели как единицы физики. Если позже добавите физический движок, он ждёт метры, а не пиксели. См. гайд по 2D-физике, чтобы понять, почему масштаб важен.
Роль Egmatic
MonoGame даёт C#, .NET, полный доступ к исходникам, отсутствие роялти и такой же охват платформ, как у стека, на котором сделаны Stardew Valley и Celeste, — но каждый слой вы собираете сами. Egmatic — это редактор и движок для 2D-игр, построенный на рантайме MonoGame, поэтому редактор сцен, конвейер контента и узловая логика в нём уже объединены, а не сшиты вручную. Вы сохраняете кроссплатформенный охват MonoGame и избавляетесь от работы по интеграции. Если нужна мощь стека MonoGame без недель на связывание инструментов — для этого и существует Egmatic.
Заключение
Первая игра на MonoGame — это четыре метода: Initialize, LoadContent, Update и Draw. Установите .NET SDK, создайте проект командой dotnet new mgdesktopgl, загрузите текстуру, отрисуйте её через SpriteBatch и двигайте с помощью Keyboard.GetState. Это весь цикл, а столкновения, анимация и звук — лишь надстройки над ним. Запустите проект командой dotnet run, и перед вами окно со спрайтом, которым вы управляете, — честная отправная точка для любой следующей игры на MonoGame.
Похожие статьи
10 лучших инструментов для быстрого прототипирования игр (2026)
Правильный инструмент для прототипирования сокращает недели разработки. Вот 10 инструментов, отобранных по скорости, стоимости и пригодности для прототипирования 2D-игр — от no-code движков до профессиональных фреймворков.
10 лучших программ для спрайт-анимации в 2026 году
Выбор инструмента для спрайт-анимации зависит от стиля графики, бюджета и конвейера разработки. Сравниваем десять программ — Aseprite, Piskel, LibreSprite, Spine, DragonBones, Krita, GraphicsGale, Pro Motion NG, Blender и Adobe Animate — с актуальными ценами, возможностями и рекомендациями по типам проектов.
8 главных инструментов MonoGame, которыми пользуется каждый профи
MonoGame — это C#-фреймворк, а не готовый движок, поэтому профессиональные разработчики закрывают недостающее проверенным набором инструментов. Восемь самых ходовых: конвейер контента MGCB, библиотеки MonoGame.Extended и Nez для недостающих возможностей движка, FlatRedBall с GUM как движок и редактор интерфейса, Aseprite и MonoGame.Aseprite для спрайтов, Tiled и LDtk для уровней и TexturePacker для атласов. В руководстве объяснено, что делает каждый инструмент и как они сочетаются.