MonoGame: пошаговый урок — создаём первую 2D-игру
Урок 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)
Десять инструментов для быстрого прототипирования игр, от no-code движков до фреймворков, отобранных по скорости, стоимости и пригодности для 2D.
10 лучших программ для спрайт-анимации в 2026 году
Выбор зависит от стиля и бюджета. Сравниваем Aseprite, Piskel, Spine, DragonBones, Krita, Pro Motion NG, Blender и Adobe Animate — цены и рекомендации.
8 главных инструментов MonoGame для профессионалов
MonoGame — фреймворк, а не движок, поэтому профи собирают свой набор: MGCB, MonoGame.Extended, Nez, FlatRedBall, Aseprite, Tiled, LDtk и TexturePacker.