Microsoft Visual C++ 2005, 2008, 2010, 2012, 2013, 2015, 2017, 2019, 2022
Microsoft Visual C++ (MSVC) — пакеты библиотек, необходимых для запуска программ на С++. Интегрированная среда-комплект разработки программ и приложений на языке C++, разработчиком является компания Microsoft..
Visual C++ обладает мощной поддержкой разнообразных приложений на Managed C++ и C++/CLI, и C++, обладает возможностью генерировать код для различных платформ как NET Framework, так и в среде «чистой» Windows. В данном случае Visual C++ является незаменимым среди других программ, поскольку ни Visual J# , ни Visual Basic .NET не способны генерировать код.
В последнюю версию Visual Studio 2015 вставлен Visual C++ (14.0). Данный комплект предоставляет разработчикам больше возможностей, например поддержку нескольких мониторов.
Ключевые особенности Microsoft Visual C++
- Вместо кучи область стека или статической области,
- На смену явного указания типа автоматическое определение типа.
- Интеллектуальные указатели на смену необработанных указателей.
- На смену необработанных массивов char типы std::string и std::wstring.
- На смену необработанных массивов контейнеры STL такие же, как vector, list и map.
- На смену алгоритмов, закодированных вручную алгоритмы STL.
- При помощи STL std::atomic свободное взаимодействие между потоками.
- Встроенные лямбда-функции на смену небольших функций (реализуются отдельно).
- Циклы for, чтобы создавать циклы, основанные на диапазонах, которые работают с контейнерами STL.
Установка Microsoft Visual C++
Это важный компонент системы, поэтому установку следует запускать от имени администратора. Если у Вас 32 битная операционная система, следует выбрать для установки файл «vcredist2017_x86», но если у Вас 64 битная операционная система, то следует установить оба файла и «vcredist2017_x86» и «vcredist2017_x64». Правой кнопкой мышки нажимаем на установочном файле и выбираем «Запуск от имени администратора». Появится загрузочное окно, где необходимо ознакомиться с лицензионным соглашением и принять его, установив галочку. Кликаем на «Установить» Установочное меню покажет ход установки и менее чем через минуту установка успешно завершена. Нажимаем на «Закрыть». Сегодня рассматривалась установка версии 14.16.27024.1. Приятного пользования.
| Разработчик: | Microsoft |
| Версия: | 2005, 2008, 2010, 2012, 2013, 2015, 2017, 2019, 2022 |
| Дата обновления: | 08.08.2022 |
| Операционная система: | Windows XP / Vista / 7 / 8 / 10 |
| Язык интерфейса: | многоязычный (русский есть) |
| Категория: | Компоненты |
| Размер файла: | от 13.8 MB до 24.0 MB |
Скачать Microsoft Visual C++ 2005, 2008, 2010, 2012, 2013, 2015, 2017, 2019, 2022
Информация была полезной? Поделитесь ссылкой в соцсетях! Спасибо!
Другие программы в этой категории:
Java — исполнительная среда, позволяющая запускать и использовать приложения написанные на языке программирования Java
DirectX — комплект API, позволяющий запускать и отображать приложения, богатые элементами мультимедиа
Microsoft .NET Framework — библиотека плагинов для запуска и работы программ, написанных в «.NET»
Adobe Flash Player — популярная программа для воспроизведения файлов формата Flash, необходима для обработки Flash-графики в Интернете
Wise Windows Key Finder — программа для быстрого получения ключа и id Microsoft Windows и Microsoft Office
Wise Reminder — органайзер для Windows для составления расписаний и напоминании о задачах
Установка поддержки C++ в Visual Studio Code (VSCode)
Для разработки программ на языке c++ вы можете использовать среду разработки Visual Studio Code (VSCode).
Сегодня мы рассмотрим установку поддержки языка программирования с++ в этой IDE.
Выбор компилятора
Перед установкой расширения для поддержки с++ в VSCode нам нужно сначала определиться какой компилятор использовать.
Под Windows существует несколько возможностей:
- Вы можете использовать Windows Subsystem for Linux (WSL) и установив в виртуальной машине все необходимые пакеты компилировать программы с помощью специального расширения для VSCode.
- Вы можете установить MinGW или MSYS2 и использовать их компиляторы.
- Вы можете установить компилятор Microsoft C++ compiler (MSVC)
Сегодня мы рассмотрим самый простой способ – установку Microsoft C++ compiler (MSVC).
Установка Microsoft C++ compiler (MSVC)
Для начала скачаем установщик по ссылке:
Скачиваем файл, в моем случае он называется:
Запускаем, откроется окно:

Нажимаем «Продолжить» и ждем, пока не закончиться скачивание файлов:

После этого откроется окно:

Поставьте галочку рядом с Разработка классических приложений на C++

К сожалению, нет способа не ставить саму IDE.
Снимите галочки с:
- Live Share
- С++ AddressSanitizer
- Адаптер тестов для Boost.Test
- Адаптер тестов для Google Test

Ожидайте окончания установки.
После окончания загрузок перезагрузите ваш ПК
Проверка доступности компилятора
После перезагрузки проверим доступен ли компилятор, для этого запустите cmd.exe скопируйте и вставьте в консоль строку
Будет запущена консоль разработчика:
Компилятор успешно установлен и доступен.
Теперь пришло время установить расширение для поддержки с++ в VSCode.
Установка расширения для поддержки С++ в VSCode
Откроется панель Extensions: Marketplace – это каталог, из которого мы можем скачать все необходимые расширения и темы, достаточно знать их название.


Выберите указанный пункт и нажмите install

Будет начато скачивание дополнительных компонентов. После окончания загрузок расширение будет готово к использованию.
Настройка VSCode для использования компилятора MSVC
Для того, чтобы протестировать работу компилятора создадим тестовый проект.
Для нормального функционирования компилятора MSVC нужно установить несколько переменных окружения. Чтобы упростить задачу воспользуемся Visual Studio 2019 Developer Command Prompt.
Запустите его из меню Пуск введя слово developer, откроется консоль:

Допустим, наши проекты буду находится в папке d:\cpp
Создадим данную папку и перейдем в нее:
Создадим папку для проекта test
Запустим VSCode из этой папки
Откроется окно VSCode

Обратите внимание наша папка уже открыта.
Добавим новый файл для этого нажмите на кнопку:

В появившееся поле введите имя файла main.cpp
Введите текст программы и не забудьте сохранить результат:
Настройка компилятора для проекта
Теперь у нас есть программа, осталось её скомпилировать, давайте настроим задачу сборки для проекта.
Настройка задачи сборки (Build Task)
Выберите пункт меню Terminal –> Configure Default Build Task…

В окне выберите – cl.exe
Будет создан файл сборки:

Закройте вкладку с файлом tasks.json
Откройте файл main.cpp и нажмите

Сборка успешно завершена.
Щёлкните мышкой по терминалу и нажмите пробел, чтобы закрыть результаты сборки.
Введите main.exe и нажмите Enter

Поздравляю, мы успешно настроили среду разработки VSCode для работы с языком программирования C++.
Заключение
Сегодня мы добавили поддержку языка программирования C++ в среду разработки VSCode.
Нами был установлен компилятор Microsoft C++ compiler (MSVC) и проверена его работоспособность.
Мы добавили тестовый проект и настроили задачу сборки Build Task для нашего проекта.
Как скачать с для программирования
Одним из наиболее распространенных компиляторов для языка C++ является компилятор Clang , который развивается в рамках проекта LLVM. Рассмотрим создание первой простейшей программы на C++ с помощью Clang под ОС Windows.
Прежде всего нам надо установить непосредственно сам компилятор. Clang развивается в рамках проекта LLVM , репозиторий которого можно найти на github: https://github.com/llvm/llvm-project. И данный проект предоставляет готовый установщик компилятора под Windows
Для загрузки установщика под Windows перейдем на страницу релизов в данном репозитории по ссылке https://github.com/llvm/llvm-project/releases/

По умолчанию в самом верху будут ссылки на самую последнюю версию. Но по умолчанию ссылка на установщик для Windows может быть скрыта. В этом случае под набором ссылок необходимо нажать на ссылку Show All assets . И среди появившихся ссылок найдем пункт LLVM-XX.X.X-win64.exe , где XX.X.X — это версия. Например, в моем случае это файл LLVM-15.0.7-win64.exe

Это версия для 64-битной версии Windows. Если ОС 32-х битная, то необходимо загрузить файл LLVM-15.0.7-win32.exe
После загрузки запустим файл.

На стартовом экране программы нажмем на кнопку «Далее». Затем надо будет принять лицензионное соглашение

Далее надо будет указать опции установки:

Чтобы при компиляции не указывать полные пути к компилятору или вручную не добавлять путь к нему в переменные среды выберем на этом окне пункт Add LLVM to the system PATH for current user
На следующем окне укажем папку для установки. Можно оставать путь по умолчанию — «C:/Program Files/LLVM»:

На следующих окнах оставим все опции по умолчанию и запустим процесс установки. После успешной установки мы можем приступать к использованию Clang

Чтобы проверить установку Clang, в терминале/командной строке следует ввести команду
В этом случае нам должна отобразиться базовая информация о компиляторе, типа версии и т.д.:
Первая программа
После завершения установки если мы откроем каталог C:\Program Files\LLVM\bin , то найдем там все необходимые файлы компиляторов:

В частности, файл clang.exe предназначен для компиляции программы на языке Си, а clang++.exe как раз и будет представлять компилятор для языка С++. То есть нам нужен clang++.
Итак, создадим на жестком диске С папку для исходных файлов программы на языке C++. А в этой папке создадим новый текстовый файл, который переименуем в hello.cpp . То есть по сути файлы исходного кода на С++ — это обычные текстовые файлы, которые, как правило, имеют расширение cpp .

В моем случае файл hello.cpp находится в папке C:\cpp.
Теперь определим в файле hello.cpp простейший код, который будет выводить строку на консоль:
Для вывода строки на консоль необходимо подключить нужный функционал. Для этого в начале файла идет строка
Данная строка представляет директиву препроцессора, которая позволяет подключить библиотеку iostream. Эта библиотека нужна для вывода строки на консоль.
Далее идет определение функции main . Функция main должна присутствовать в любой программе на С++, с нее собственно и начинается выполнение приложения.
Функция main состоит из четырех элементов:
Тип возвращаемого значения . В данном случае это тип int . Этот тип указывает, что функция должна возвращать целое число.
Имя функции . В данном случае функция называется main.
Список параметров . После имени функции в скобках идет список параметров. Но в данном случае скобки пустые, то есть функция main не принимает параметров.
Тело функции . После списка параметров в фигурных скобках идет тело функции. Здесь и определяются собственно те действия, которые выполняет функция main.
В теле функции происходит вывод строки на консоль. Для обращения к консоли используется стандартный поток вывода std::cout . С помощью оператора << в этот поток (в данном случае фактически на консоль) передается строка символов, которую надо вывести на консоль, то есть «Hello METANIT.COM!».
В конце осуществляем выход из функции с помощью оператора return . Так как функция должна возвращать целое число, то после return указывается число 0. Ноль используется в качестве индикатора успешного завершения программы.
После каждой инструкции в языке C++ ставятся точка с запятой.
Каждая строка снабжена комментарием. Все, что написано после двойного слеша // представляет комментарий. Комментарий не учитывается при компиляции приложения, и не является частью программного кода, а служат лишь для его описания. Комментарий позволяет понять, что делает программа.

Теперь скомпилируем этот файл. Для этого откроем командную строку Windows и вначале с помощью команды cd перейдем к папке с исходным файлом:
Чтобы скомпилировать исходный код, необходимо компилятору clang++ передать в качестве параметра файл hello.cpp:
Дополнительный необязательный параметр -o hello указывает, что скомпилированный файл будет называться hello.exe. Если не указать этот параметр, то файл будет называться по умолчанию — a.exe.
После выполнения этой команды будет скомпилирован исполняемый файл, который в Windows по умолчанию называется hello.exe. И мы можем обратиться к этому файлу, и в этом случае консоль выведет строку «Hello METANIT.COM!», собственно как и прописано в коде.

Если вместо командной строки используется оболочка PowerShell, то для запуска файла надо прописать «./hello».
C# Урок 1. Установка Visual Studio Code
Че так долго = P.S. Словом, разлил газировку на ноут, был в депрессии, ай пофиг, начали.
1. C чего начать
Для работы с текстом вам нужен текстовый редактор (World), для обработки фотографий вам нужен графический редактор (Photoshop), для программирования требуется IDE(интегрированная среда разработки).
IDE – это комплекс программных средств для разработки ПО, такие как
a. Текстовой редактор (Ну это просто, это там, где мы пишем код)
b. Компилятор/интерпретатор (переводит наш код в машинный код, способный к выполнению процессором)
c. Средства автоматизации сборки (Помогает собрать наш проект. К примеру, в исполняемый .exe файл)
d. Отладчик/Debugger (Можно ставить всякие точки остановки (breakpoint и watch) чтобы отслеживать, что выполняет код на данной строчке кода)
Под C# основной IDE является Visual Studio (Community является бесплатной, и в принципе там есть практически всё). Но(!) в наших уроках мы будем писать в Visual Studio Code (редактор кода).

Итак, определились. Скачиваем Visual Studio Code ( https://code.visualstudio.com/ )

Нажимаем на нужную кнопку “Windows” и скачиваем установщик. Там всё стандартно, ставим галочку «Добавить в Path».
А затем скачиваем .NET Core SDK ( https://dotnet.microsoft.com/download ). Просто ждем установки, после установки вроде потребуется перезагрузить ПК, я уже не помню.

Далее запускаем VSCode, переходим на вкладку Extension и устанавливаем расширение для VSCode ->C#. Для этого нужно в поиске расширений просто написать C#

Далее создаем какую-нибудь папку, где у нас будет проект, и открываем эту папку в VSCode File->Open Folder…
Далее нам нужно создать консольное приложение на языке C#. Переходим по этой ссылке, https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-ne. , и находим среди всех команд ту что нужно.

Далее в VSCode выбираем меню Terminal->New Terminal и пишем туда команду
dotnet new console
Ждем и затем пишем
dotnet restore
чтобы скачались нужные компоненты (требуется один раз). Далее пишем
и в терминале происходит запуск нашей программы. Выглядит не Айс, поэтому идет до конца.
Запускаем нашу программу Debug-Start Debugging. Выбираем (.NET Core), чем будем компилировать наш код и открывается окно настройки.

В данном окне настройки поменяем строку
«console»: «internalConsole»,
«console»: «externalTerminal»,

Затем добавляем в наш код следующий код Console.ReadLine(); и вновь запустим Debug-Start Debugging. Мы должны увидеть следующее


Конечно, это не конечный вариант, конечный вариант будет в виде видеоурока на youtube (писать что и как устанавливать, это конечно же жесть) https://www.youtube.com/channel/UCxHlqdzYPZCKHTDWFZ895Qg?vie. . Спасибо за внимание.
Много раз видел здесь уроки, но обычно авторы после первой статьи сливаются
Уважаемые пикабушники, а что делать, если я нажимаю запустить код, а он мне открывает вот это?

«Для работы с текстом вам нужен текстовый редактор (World)»
Я конечно понимаю, что опечатка, но.
Мне нужен этот Чертов «world», причем весь 🙂
Подпишусь. Продолжай. А форму с кнопкой оно умеет делать как в делфи? Я в делфи пописывал иногда, потом мне сказали что делфи умер.
Где делают приятные интерфейсы, те же диаграммы?
Вот например пробовал в VB+ASPNet — используя стандартные контроллы, выходит не очень

Пишем примитивную 3D игру. Расширяем пространство. Запускаем корабль. Часть 2
Всем добрый вечер! Материал к данному посту уже давно был готов, но не получилось выпустить его так быстро, как хотелось. Но, тем не менее.
Часть 1. Введение, строим 2D объект

Я прочитал некоторые отзывы на первый пост, особенно, касательно программной части. Ещё раз акцентирую внимание — данные примеры не являются идеальными в плане кода, так как написаны исключительно для демонстрации алгоритма. Рекомендую не использовать их, а попытаться самостоятельно разработать их аналоги.
Итак, в прошлый раз мы остановились на том, что научились поворачивать 2D-область с помощью матриц. Некоторые просили рассказать подробнее о том, как их решать. Думаю, в этом посте завеса тайны будет чуть приоткрыта. Давайте начнём операции по расширению пространства до трёхмерного и добавим z-ось. Для этого мы сделаем следующее:
Задача 1. Изменим структуру нашего объекта, позволив хранить трёхмерные координаты.


Для того, чтобы понять, почему количество значений увеличилось на столько порядков, сразу же небольшая беседа о структуре 3D объекта. По-научному это называется «полигональная сетка».
Если кратко, то мы можем хранить описание 3D объекта в виде:
1. Списка вершин (Vertices)
2. Списка ребёр (Edges)
3. Списка, ну скажем так, граней (Faces)
В нашем случае, третье пока не рассматривается (хотя до него руки тоже дойдут). Рассмотрим первые два варианта. Список крайних точек может быть представлен следующим образом:

Рассмотрим куб. Куб имеет 8 крайних точек. Описываются их координаты по 3 осям, скажем так, в явно заданном виде (обычно они задаются в виде векторов, т.е. <0.5f, 0.23f, -0.09f>и т.п.). Далее следует порядок их объединения.
Специальный алгоритм, который мы сами должны написать, восстановит список рёбер по списку вершин. Так как основной задачей на данный момент не является написание такого алгоритма, то мы сразу выберем вариант отображения в виде списка ребёр (edges), хотя он громоздкий и работать с ним не очень удобно.
Представим куб в виде пар координат. Две крайние точки, соединяются в ребро, которое будет отображено в виде линии на экране. Тогда одно такое ребро будет задано координатами (x1, y1, z1, x2, y2, z2). Логичнее разместить их попарно (

Если 2D прямоугольник в виде точек описывался массивом [4][2], то куб в виде рёбер уже [12][6].
Также, к центру объекта добавляется третье измерение: float center[3] = < 0.f, 0.f, 0.f >;
Задача 2. Организуем проекцию трёхмерного пространства на двумерное
Как я уже упоминал в первом посте, который некоторые незаслуженно назвали «бредом», модель находится где-то там, в невидимом пространстве, а вот практическую реализацию мы можем увидеть. Проекция двумерных координат очень проста по своей сути: x точки отображаем как x на экране, а y, как y. Здесь же мы имеем дело так же с x и y, но при этом куда-то нужно ещё вставить зависимость от координаты z. Можно сделать это также несколькими способами:
1. Построить ортогональную проекцию, например, представив x как x+ k*cos(a)*z, но этот вариант рассматривать мы сейчас не будем.
2. Непосредственно разделить на z: x’=kx/z и y’=ky/z
Второй вариант, на самом деле, очень прост. формулы расскажут его лучше, чем я:

Для получения двумерной координаты достаточно лишь сделать вот так. WW/2 — половина ширины экрана (x), FOV — коэффициент поля видимости, x — координата из массива (value[0]), z — то же самое (value[2]).
Здесь вводится коэффициент FOV, характеризующий глубину поля зрения. Если кто-то когда-либо интересовался анаглифными 3D-очками, то он мог заметить, что при изменении FOV на рендерере изменяется нагрузка на глаза. При сильных значениях изображение вообще перестаёт сходится. Проще показать наглядно, что я и сделаю в примере. В нашем случае примем его как константу 200-300 единиц, и более не будем трогать. Получив все координаты x’ и y’, осуществляем рендеринг, аналогично 2D из первого поста.
Так как я демонстрирую алгоритм, а не работу с библиотекой, я не использую вспомогательные средства SFML, а только лишь отображение объектов по явным координатам, подобно тому, как это делалось на древних компьютерах типа ZX Spectrum.
Ии.. мы получили вот такую картину:

Четыре точки на поле. А чем она отличается от той, что была в первом посте, спросите вы? Не торопитесь. Давайте теперь включим отображение линий:

Что-то начинает проясняться.. Мы находимся в центре куба, и смотрим прямо. Потому и видим четыре точки одной из его граней. Так и должно быть. При таком способе проекции наш экран соответствует координате z = 0. Таким образом, остальные 4 точки остались за нашей спиной, и к ним уходят соответствующие рёбра. Так же, чтобы избежать вылета приложения при делении на z = 0, нужно перед операцией деления явно указать: if (z=0) z=(0.01f). На этом задача по рендерингу окончена.
Задача 3. Расширяем функции поворота для 3D пространства
Вот здесь мы снова сталкиваемся с матрицами. Только для двумерного прямоугольника они были второго порядка, а сейчас нас ожидают матрицы 3 порядка (иллюстрация с сайта Wikipedia):

Не стоит пугаться этих матриц. Разрешаются они стандартно, умножением на вектор-столбец с координатами:

(цифры выше для примера). В нашем столбце будут координаты трёх вершин 1-й точки. Для линии, соответственно, делается два умножения. Более подробно для людей, мало знакомых с матрицами:
1. Сначала составляется матрица Mx, My, Mz в зависимости от того, вращение вокруг какой оси вам потребовалось: x,y,z.
2. Затем полученная матрица векторно перемножается на данные координаты
3. Полученные координаты записываются в новый объект, который будет являться уже повёрнутой копией старого объекта (в ООП), либо просто в поля (область памяти) старого объекта, как делалось на старинных компьютерах.

Показан пример счета сразу трёх матриц одновременно. С точки зрения оптимизации это не нужно, достаточно будет одной лишь матрицы в зависимости от заданного аргумента.
Также, процедура умножения матрицы на вектор-столбец (это не самый красивый вариант, как её реализовать, но рабочий):

newValue[i] — новое значение x[0], y[1], z[2] для первой точки линии. Для второй точки — аналогично.
oldData[i] — старое значение x[0], y[1], z[2] для первой точки линии. Аналогично newValue
center[i] — аналогично заданные координаты центра объекта.
Именно здесь нам и пригодился центр объекта. При повороте относительно произвольной оси, если объект уже был сдвинут, при неверно заданном центре объект начнёт вращаться либо с большим радиусом, либо вообще непредсказуемо. Поэтому при операции сдвига, например, +100 по z, в center так же записывается z: 0,0,100.
Грубо говоря, в процессе перемножения матрицы, координата центра вычитается, и объект как бы «возвращается» в центр поля, вычисляется, и затем сдвигается обратно. Скорее всего, есть и более эффективные алгоритмы для решения данной задачи.
Давайте теперь испытаем полученные функции, и попробуем повернуть куб (как я и говорил, поворот осуществляется по прерыванию, т.к. игровой таймер всё ещё отсутствует):
Также, демонстрация изменения константы FOV из задачи 2 на развёрнутом кубе:
Т.е. изменение FOV как бы искажает отклонение осью z оси x. Проявляется это увеличением количества видимых на экране объектов.
Задача 4. Элементы «гейм-дизайна»
Давайте теперь попробуем реализовать элемент игры, а именно, космический корабль, которым мы управляем. Нам понадобится модель корабля. Так как пишем мы примитивную игру, так сказать, «следуя по стопам» за гигантами прошлого века, модель тоже должна быть несложной в исполнении. Я смоделировал её в 3D редакторе:

Теперь нужно получить её рёбра. Сделать это явно мы не сможем, поэтому получим хотя бы вершины. Экспортируем модель в формате .obj. На примере куба:

Как мы можем видеть, содержимое файла, если открыть его в редакторе, похоже на упомянутое в первой задаче. Но есть небольшие отличия:
v — непосредственно вершины, в виде нормализованного к единице вектора
vn — нормали (нам не нужны)
f — грани (faces). Они нам не помогут. На первый взгляд сложно. Рассмотрим ещё более простую модель: грань.

4 вершины, 1 «face»: задан как 1//1 2//1 4//1 3//1. Но наша программа устроена по другому принципу. Возьмём отсюда только лишь вершины. Так как писать автоматизированное ПО для одной модели нецелесообразно, порядок соединения выставим вручную. Воссоздаём модель корабля:

Вот, как будет выглядеть модель, если неправильно были выставлены оси координат. Помните ложку из 1 части поста? А это в подобном представлении наш корабль..

Но, тем не менее, каркасная модель выполнена и состоит из 36 рёбер:

Давайте запустим программу:

В движении смотрится более эффектно:
К полёту готов! Также сразу же можно выполнить некоторую «постановку» сцены: корабль сдвигается вместо центра примерно на 0,7 экрана по y. Однако, конечно, пока это ещё не игра, а всего лишь просмотрщик 3D модели. Но, всё это, как и прежде, поправимо. Вопрос только, когда..
Всем спасибо, с вами был Kekovsky, надеюсь, пост был для вас информативным, комментируйте, поддерживайте автора и т.д.
Ответ на пост «Бесплатно помогаю пикабушникам учить программирование, часть 30: "О уместности и правилах хорошего тона."»
Начну с того, что в 2020 году я закончил медицинский университет на специальность врача-стоматолога без особого желания работать стоматологом и с огромным желанием работать в IT.
Мои познания программирования начались с того, что на 3 курсе мне предложили обучать детей HTML/CSS, Scratch и Python, хотя на тот момент я вообще не имел никакого понятия о том, что это и как с этим работать. Все знания приходилось получать от того же материала, который я приподносил детям. То есть за день, а иногда даже за пару часов до урока я открывал материал, учил его и объяснял уже на уроке.
Всё пришло к тому, что в 2020 я знал базовый HTML/CSS, Python. Ну и на этом всё. В том же году наткнулся на пост про обучение Ruby, загорелся и начал изучать план обучения в телеграм канале. Тогда же у меня родилась дочь, и всё свелось к тому, что мне предстоял выбор между неизвестной мне профессией и работой, которой я посвятил 6 лет обучения в университете. Учитывая давление родственников и родителей выбрал я второе и на программирование на некоторое время полностью забил.
Как начинающему специалисту денег мне не хватало, работы было много, работать приходилось через немогу. Через полгода мне предложили преподавать программирование онлайн, и точно так же я учил материал за пару часов до урока и объяснял его. Время от времени просматривал вакансии на hh и отправлял свои резюме.
К июню 2022, 2 месяца назад я для себя окончательно решил, что хочу работать в IT. Обратно вернулся к плану обучения.
Весь июнь и июль я работал в стоматологии с 9:00 до 18:00, с 19:00 до 00:00 преподавал программирование, а с 00:00 до 3:00 учил Ruby и Ruby on Rails.
Для кого интересно, я постараюсь расписать что я учил до того как получить оффер.
1. Были базовые знания HTML/CSS, JavaScript.
2. Прошёл первые 10 уроков на https://rubyrush.ru/
3. Прочёл Руби для Романтиков и выполнил все задания с этой книги
4. Прочёл где то до 11 главы Майкл Хартл, Ruby on Rails. Дальше всё пошло плохо, так как в книге использовалась старая версия Ruby и Ruby on Rails, до этого как то получалось справляться с ошибками, а потом всё начало полностью ломаться и я забил.
5. Куча видео с youtube, где создавались приложения, делал я их с учётом того, что половину я понимал, а половину не понимал.
В начале августа я активно начал искать работу, составил резюме и отправлял во все появляющиеся вакансии.
Учитывая, что я знал HTML/CSS, JavaScript, Ruby on Rails на базовом уровне, на youtube просмотрел несколько видео по React, я отправлял вакансии и на Frontend, и на Backend. Так же увидев кучу вакансий по PHP решил подучить и его, просмотрел несколько видео и добавил соответствующую графу в резюме. В какой то момент, после первой сотни отправленных резюме мне стало всё равно, в какой стек, на какую должность я попаду, хотелось только сделать первые шаги в IT, а дальше набраться опыта и подыскать работу на Ruby on Rails.
За 2 года я отправил 424 резюме, получил кучу отказов, сделал кучу тестовых заданий, и на днях получил оффер на позицию Ruby on Rails/React разработчик с зп 50 000 рублей удалённо.
Сейчас в голове только страх перед началом работы, так как тестовое задание и техническое интервью были для меня очень сложными, ну и огромное предвкушение перед началом.
Спасибо @prodigal.son, если бы не ваш пост и ваша группа, я так и не сделал бы первые шаги в IT.

Пишем примитивную 3D игру. Как программировать, чтобы работало. Зачем программисту математика. ч.1
Всем привет! В предыдущих постах я программировал посудомоечную машину. Теперь решил сделать мини-серию постов о программировании, а точнее, о том, как надо мыслить для того, чтобы программа получилась. Я не буду вдаваться в нюансы написания самого кода. Здесь, скорее, будут размышления на тему, так что быть программистом для чтения не обязательно (и не желательно). Поехали.

Для начала, небольшой ракурс в историю. Первая игровая приставка (в привычном нам понимании) появилась в 1972 году. Разработала её группа военных инженеров во главе с Ральфом Бером -"Отцом видеоигр". Эта самая приставка была впоследствии названа Magnavox Odyssey. Выполнена она была полностью на транзисторах. Можете себе представить? (фото взято с сайта Wikimedia).

Такая приставка умела немного. Однако, важнее всего была суть — возможность генерировать свой управляемый телевизионный канал. До этого подобное не приходило никому в голову. Так вот, примерно спустя 10 лет после этих событий, появились в продажу компактные ЭВМ для массового потребления — ZX Spectrum, IBM PC и другие. Каждый получил возможность изучить компьютеры и обрёл пространство для своих творческих экспериментов. А пятьдесят лет спустя, мы привыкли видеть компьютерные игры уже так:

Конечно, у нас есть новейшие производительные процессоры. Практически каждый школьник теперь может "собрать" свой компьютер (вставив для этого комплектующие в соответствующие для них слоты). Но, когда у кого-либо возникает желание разобраться поподробнее, как это всё устроено, и, может быть, написать свою игру (где будут девушки с большими прелестями, можно грабить корованы и т.д.), тут уже возникают нюансы и, оказывается, не всё так просто в этом мире. Но на помощь нам приходят учебники по программированию. Однако, как известно, учат в школе многих, да немногие в итоге выучиваются.
Кстати говоря, скоро наступает 1 сентября. Вспоминаются мои институтские годы — как мы пришли, и первой парой стояла высшая математика. До сих пор во многих провинциальных вузах программа первого семестра начинается с матриц. Я помню ребят, которые невесть как попали в институт, смотрели с задних парт круглыми глазами и только повторяли "- И чё мы тут вообще забыли?". Кстати говоря, ребята эти в итоге семестр не пережили и были отчислены. Но это уже их проблемы. Однако, даже у тех, кто остался, часто возникали вопросы: зачем? что это мы такое учим?
Понимание приходит не сразу, однако, когда ты сталкиваешься с какой-то задачей, то со временем уже начинает что-то доходить. Так же и здесь. Оказывается, с помощью тригонометрических функций, производных и интегралов, матриц очень удобно осуществлять операции над множествами точек и фигур, что является незаменимым при создании графики в компьютерных играх. Собственно, возможность быстро производить подобные операции и характеризует "крутизну и навороченность" компьютера.
Но давайте приступать. Для начала, чтобы программа получилась, необходимо мышление программиста. Я его понимаю, как две составляющие: некая абстрактная модель и её реализация. Короче говоря, теория и практика. Чтобы было более понятно, о чём я говорю, давайте представим, что мы программируем обычную столовую ложку, как в фильме "Матрица"

Так вот, если думать, как программист, то эту ложку можно разделить на две составляющие.
1. Теория ложек
Какие параметры существуют у ложки? Такие, какие вы ей сами зададите. Вы можете взять тарелку, зачерпывать ей суп, и тем самым объявить тарелку ложкой. Но немногие с вами согласятся, ведь, во-первых, это неудобно. Во-вторых, все привыкли видеть ложку привычной ложкой. Поэтому рассмотрим более детальные требования:
— Ложка имеет хлебало и держало черенок и чашечку. Чашечка, в свою очередь, имеет форму полусферы. Мы можем задать чашечку, например как функцию z^2 = x^2 + y^2

Это, конечно же, весьма грубое сравнение. Но оно позволяет представить, каким образом будет реализована дальнейшая ложка. Аналогично можно математически описать и остальные части. Это — будет наша модель ложки. Опять же, одна из возможных.
2. Практика ложек
Как мы знаем, обычно ложки вырезаются из дерева, либо изготавливаются штамповкой из металла. В нашем случае давайте представим, что мы решили запрограммировать ложку в компьютер. Полученная двумерная проекция на экран при этом вполне может выглядеть так:


И то и это — нормально. Всё дело в представлении ложки. В том, как мы её видим и в том, как мы её задали. Последнее компьютер выполняет, в отличие от людей, весьма чётко. Мы задали какую-то задачу, и получили конкретный результат.
Именно поэтому важна проработка обоих частей программы. Понятное дело, новички, когда только врубаются в основы программирования, изучают язык подобно маленьким детям. Т.е., пытаются повторять и копировать какие-то фрагменты кода, составляя из них программу. Однако, каждый чужой кусочек кода является именно практикой, следствием где-то существующей модели. Именно поэтому программа новичка, порою, выглядит, как на известных мемах:

Но, если не сдаваться и упорно двигаться вперёд, можно прийти к какому-то конкретному результату. Для этого требуется выполнять различные "задачки": на сортировку, на реализацию функций, на описание структур и т.д., пробовать выполнять какие-то кусочки больших и сложных моделей: хвост оленя, чашку ложки и т.п. Собственно, подобным образом осваиваются и другие человеческие науки: для рисования нужно отрабатывать тени и завитки, для игры на музыкальных инструментах — гаммы и аккорды, ну и так далее.
Давайте рассмотрим одну из таких задачек. Вспомним ракурс в историю, который был в начале поста. Первые 3D игры для первых ЭВМ были примерно такие: Battle Tank

Star Wars: Empire strikes back.

Всё это было до Джона Кармака, появления Direct3D, OpenGL и т.д. Примерно в таком ракурсе мы и будем с вами сегодня сегодня работать. Писать будем пока на плюсах, хотя для новичков проще это будет сделать, наверное, на питоне. В качестве подспорья возьмём графическую библиотеку SFML. С 2018 года она уже не поддерживается, но, для иллюстрации сути поста её будет достаточно. Мы хотим получить что-то вроде этого:

Для того, чтобы обдумать реализацию, и, в дальнейшем, это получить, мы должны разобрать "по косточкам" происходящее на экране. Мы видим:
1. GUI (интерфейс с очками и временем). Пока отбросим его.
2. Пространство с астероидами
3. Космический корабль
Также мы знаем, что происходит при нажатии клавиши:
1. Космический корабль наклоняется в сторону
2. Пространство поворачивается вокруг корабля, создавая иллюзию того, что корабль куда-то летит (да, когда вы играете в компьютерную игру, это не игрок поворачивается в пространстве, а пространство вокруг игрока).
Теперь рассмотрим более подробно первую задачу: по нажатии клавиши космический корабль поворачивается. Давайте разберём корабль, по аналогии с ложкой. Он представляет собой проекцию трёхмерного объекта на двумерное, группу точек, соединённых рёбрами (в случае Wireframe моделей — линиями, в остальных — треугольниками, полигонами). Значит, теория корабля следующая:
1. Где-то есть группа точек. Её мы просто задаём, как набор переменных. Произвольно. Но хотя бы один экземпляр её должен существовать.
2. Есть способ изменения этой группы точек по внешним параметрам. Для этого есть матрицы сдвига, масштабирования и поворота в трёхмерном пространстве (материал взят с сайта Wikipedia):

3. Есть способ отображения их на мониторе (хотя это уже больше относится к реализации)
Прежде, чем приступать к реализации 3D варианта (он будет во второй части поста), давайте упростим наш корабль до прямоугольника, и одно измерение уберём. Таким образом, будет проще разобрать задачи на начальном этапе. Да и матрица поворота сильно упрощается и теряет один порядок:

С теорией понятно, давайте перейдём к практике.
1. Развернём IDE, подключим библиотеки, подготовим точку входа.

2. Создадим класс Box2D. Зададим группу точек нашего прямоугольника как двумерный массив — массив пар координат. Пока что с конечным размером.:
float vertices[4][2] = < <-50.f, 50.f>, <-50.f, -50.f>, <50.f, -50.f>, <50.f, 50.f>>;

Также добавим переменную center, характеризующую сдвиг центра объекта. Это необходимо для возможности дальнейшего поворота относительно произвольной оси, но пока не нужно.
3. Добавим методы, осуществляющие поворот объекта по заданному углу. Код здесь получился несколько кривой в результате быстрого его портирования с питона, но, в дальнейшем, поправим:

Обратите внимание.
В generateMatrix переменная newMatrix — та самая матрица поворота. Вспоминаем нашу математику. Функция подготовит матрицу поворота на конкретно заданный градус. Именно на неё мы будем перемножать имеющиеся ранее заданные значения точек, чтобы получить новые координаты.
calculatePerVertex — перемножает координаты на матрицу.
recalculateRotation — проходит по всем координатам объекта и выполняет их обработку.
Таким образом, используя матрицу newMatrix, мы можем повернуть любое множество точек, перебрав их каждую по очереди. В двумерном пространстве это будет выглядеть, как движение точки по касательной окружности (в случае положительного угла — по часовой стрелке, и наоборот).
Ну и осталось спроецировать эти точки на экран. Тут есть множество вариантов — можно также создать копию массива точек, соответствующих полученным значениям, если в дальнейшем нам нужно применять к точкам ещё какие-либо операции. В нашем случае это не нужно, поэтому все точки можно просто забить поочерёдно в дисплейную область оперативной памяти посредством средств библиотеки SFML — объекта "Circle" со смещением на координаты, задаваемые вершинами.

Готовый результат при таком способе проекции будет выглядеть так:

При нажатии клавиши фигура поворачивается на заданный угол. На данный момент фигура поворачивается по прерыванию от клавиши, так как игровой таймер ещё не реализован, что будет поправлено в следующих постах, если эта тема понравится.
Обобщим вышесказанное:
Мы имеем некоторую воображаемую модель множества точек. Над которой осуществляем операции, и затем практически отображаем результат этих операций. Именно за это и отвечает математика. Хотя, конечно, это чуть ли не школьный уровень.
Давайте изменим практическую реализацию и соединим наши точки линиями. Для этого мы сообщаем в модель ещё один внешний параметр — порядок соединения этих линий. Он может быть произвольным. Но, как мы знаем, у прямоугольника каждая вершина соединяется лишь с двумя другими под углом 90 градусов. Поэтому порядок соединения будет 1-2-3-4-1.

Центр обозначен красной точкой. Уже становится немного понятно, каким образом осуществляется управление воображаемым космическим кораблём. Далее остается лишь добавить третье измерение, и получить куб. Немного забежим вперёд:

Трёхмерный куб вращается относительно произвольной оси, центр куба не равен линии вращаемой оси (обратите внимание на красную точку). Вершины куба также обозначены окружностями для наглядности. Реализовать такой куб, и, затем, космический корабль мы попробуем во второй части поста.
А для тех, кто дочитал и кто любит компьютерные игры, забежим ещё очень сильно вперёд. В 2009 году Маркус Перссон, изобретатель игры "Minecraft" написал маленький апплет, под названием Minecraft 4k. Вот, как он выглядел:

Переписывание этого апплета также является хорошим упражнением для развития навыков по программированию. Обратите внимание: разворачивается трёхмерный массив кубов, который вращается вокруг игрока, создавая иллюзию того, что игрок осматривается. Оптимизация отсутствует, отрисовываются все грани, однако, также выполняется рейкастинг по 3 осям, и ближайшие грани кубов перекрывают более дальние, создавая такую картинку.
С вами был Kekovsky, на сегодня всё, приятных выходных. Если какие-то из моих постов понравились или были для вас информативными, можете поддержать меня, благодаря стараниям администрации Пикабу у меня теперь так же есть донатная кнопка.
Всем успехов в освоении новых наук!

Интересный Python #14: визуализируем данные
Сегодня напишем вот такое приложение всего в 53 строки кода. Да, всего 53, без шуток. И всё благодаря Streamlit.

Что такое Streamlit?
Streamlit — это библиотека, которая позволяет создавать веб-интерфейс для приложений, работающих с данными. Так что если вы работаете с Pandas, используете Matplotlib, Bokeh, Altair и подобные инструменты, то с помощью Streamlit сможете оборачивать свои скрипты в интерактивные веб-интерфейсы и делиться ими с другими пользователями.
Для кого этот пост?
Для тех, кто уже неплохо знаком с Python и часто работает с данными. Для начинающих многие вещи будут сложноватыми.
Как установить Streamlit
1. Откройте терминал (командную строку);
2. Если умеете пользоваться виртуальным окружением, то создайте и активируйте его. Если нет, то пропустите этот шаг;
3. Выполните команду pip install streamlit.
Документация
Документация просто великолепная, очень удобная и красивая. Ознакомиться с ней можно здесь.
Для начала соберём интерфейс приложения. Он будет состоять из:
— формы (контейнера для других элементов);
— пары полей для ввода чисел;
Для каждого из этих элементов в Streamlit есть отдельный класс.

Форма нужна для того, чтобы скрипт не перезапускался полностью при каждом изменении слайдера или поля для ввода (по умолчанию в Streamlit реализовано именно такое поведение).
Задаём настройки страницы, добавляем заголовок «Симулятор ставок» и создаём форму с элементами.

Запускаем сервер
Чтобы запустить сервер Streamlit, выполните в терминале следующую команду:
Вместо main.py , конечно же, укажите имя вашего основного модуля.
Если всё сделано правильно, то спустя несколько секунд откроется окно браузера, в котором отрисуется интерфейс.

Важно: запускать программу с помощью интерпретатора Python не нужно, сервер Streamlit сам это сделает. Если вы внесёте изменения в исходный код, то достаточно будет просто обновить страницу, чтобы изменения вступили в силу.
Теперь реализуем внутреннюю логику. Нужно будет при каждом нажатии на кнопку в форме генерировать датафрейм с результатами ставок.
Начнём с импорта нужных модулей.

Так как нужно будет генерировать N наборов данных, построенных по одинаковому принципу, то упакуем начальные «настройки» в класс, и будем использовать их при вызове методов.

Соединяем интерфейс и логику
Осталось сделать так, чтобы при клике по кнопке приложение забирало данные из элементов интерфейса и отдавало их в Simulator.

Приложение готово. Обновите страницу в браузере, и Streamlit автоматически подтянет все изменения.
Streamlit щедро раздаёт свои облачные ресурсы, так что развернуть приложение можно буквально в пару команд. Пушим код на Github, даём Streamlit ссылку на репозиторий, немного ждём и получаем ссылку на наше приложение в облаке. Подробности — в документации.

Интересный Python #13: играем "Имперский марш"
В прошлых постах было слишком много слов «работаем». Поэтому сегодняшний пост будет про то, как играть. Причём играть не что-то там, а музыку. Причём музыку не какую-то там, а «Имперский марш» из «Звёздных войн». Так что, товарищи Дарты Вейдеры, отвлекитесь на пару минут от удушения очередного офицера и насладитесь чудесными звуками.

Для воспроизведения звуков будем использовать модуль winsound из стандартной библиотеки Python. Устанавливать ничего не нужно, он уже идёт в комплекте с интерпретатором.
В нём есть функция Beep(), с помощью которой можно воспроизвести звук заданной частоты и заданной длительности.
Важно: модуль работает только под Windows. Господа линуксоиды, сегодня вы в пролёте 🙁

Также понадобится модуль time, с помощью которого будем создавать паузы.

Каждой ноте соответствует определённая частота звука, выраженная в герцах. Таблицу можно увидеть здесь или здесь.
Составим список необходимых нот:

Ключ — это название ноты, а значение — это частота.
Запишем мелодию в виде набора нот.

1/4, 3/16 и прочее — это длительность каждой ноты.

Нам понадобятся 2 функции: одна для воспроизведения конкретной ноты, а вторая — для воспроизведения всей мелодии.
Воспроизводим ноту

Воспроизводим мелодию

Наслаждаемся результатами
Оригинальный темп мелодии — 103 BPM.

Забрать полный код в текстовом виде можно здесь.

GameMaker Studio 2. Урок 8. Звук
Это воскресенье, мои чуваки.
Всем привет. Сегодня поговорим с вами о том, как подключить звук к своей игре. Как обычно: немного теории, немного практики.
Покажу вам сайт, где большинство звуков можно взять бесплатно и как его настраивать.
Ну и небольшие бонусы, само собой.
Ссылки на предыдущие гайды:
Второй гайд — События отрисовки, коллизия, скрипты.
Третий гайд — Камера и разрешение экрана.
Четвертый гайд — Иерархия объектов. Глобальные переменные.
Пятый гайд — Структуры данных. Сетка комнаты и размещение объектов по сетке.
Шестой гайд — Алгоритмы поиска путей.
Седьмой гайд — Сохранения и их загрузка. Бонус в конце!
План:
— Создание звука
— Подключим звук к кнопкам
— Глобальная настройка звука
— Заставим человечков издавать звук
— Музыка
— Тест звука
— Немного бонусов
Тема сегодня небольшая, поэтому сразу перейдём к делу.
Создание звука.
Прежде, чем приступать к работе, нам нужно подготовить материал. Вы можете записать звук самостоятельно, либо использовать свой: найденный в интернете или записанный самостоятельно.
Я предлагаю скачать уже готовый набор звуков для меню по ссылке:
Ссылка
Как видно, там несколько форматов: OGG, WAV и MP3. Использовать мы можем все из них.
Сохраните архив, распакуйте в удобное место. Можете сразу скопировать путь до него. Дальше нам нужно создать звук и загрузить его. Для этого найдём папочку Sound и там создадим, собственно, Sound.

Звук назовём sndButton.
Итак. Если сейчас мы нажмём на появившийся звук, то увидим небольшое меню настроек для нашего звука. Пока нам это не интересно. Чтобы загрузить звук, нужно нажать на три точки справа от названия звука.

Там всё просто: указываем путь до нужного нам файла. У меня это «modern2.wav«. Можете выбирать любой формат, пока это не столь важно. Стоит лишь отметить, что форматы отличаются не только весом, но и качеством звука и возможностью на него влиять внутри движка.
Нажав пробел, когда меню выделено, либо нажав на стрелочку, вы можете прослушать звук, как просто для того, чтобы убедиться, что вы загрузили то, что нужно, так и для настроек.
Обратите внимание: внизу указанного меню у вас есть вкладка Audio Group. Это ничто иное, как группа звуков. Её можно (и нужно) использовать в тех случаях, когда нам нужно уменьшить или увеличить только определённые звуки. Например, сделать три настройки звука: общий, музыка, игра. С-но, здесь будет три аудио группы: стандарт, музыка, игра.
Чтобы добавить свою аудио группу нужно в верхней части экрана найти вкладку Tools, там — Audio Groups.

Подключим звук к кнопкам.
Для удобства используем объект oMMenu, который сделаем родительским объектом для всех наших кнопок в меню, в т.ч. в настройках.
Не забудьте прописать event_inherited(); у дочерних объектов в тех событиях, которые нужно будет унаследовать.
Для начала, в Create объявим одну переменную:
Она позволит нам проигрывать звук при наведении только один раз.
Теперь в Step’e сделаем простую конструкцию: если наведены на текущий объект и раньше его не касались, то проигрываем звук и говорим, что мы его коснулись.
Соответственно, чтобы проиграть звук нам была нужна команда:
audio_play_sound(Звук, Приоритет, Зациклить)
Приоритет — то, в каком порядке звук обрабатывается. Значения либо от 0 до 100, либо от 0 до 1. Чем больше число — тем выше приоритет.
Глобальная настройка звука.
Раз есть звук — значит его можно настроить.
Для этого в комнате настроек создадим ещё одну кнопку: oSSound.
Как ни странно, но с помощью этой кнопки мы будем устанавливать значение громкости для всех звуков, в т.ч. музыки.
Для этого нужно в событии step будет прописать следующий код:
audio_master_gain(x) принимает на вход значение от 0 до 1 (0% — 100%) и устанавливает громкость звуков.
Есть похожая функция, но которая называется audio_set_master_gain(ID слушателя, Громкость). Соответственно, она необходима нам в том случае, если у нас несколько «слушателей«. Полезно при создании мультиплеера, либо для того, чтобы позволить нашему ИИ ориентироваться на звук.
Результат:
Заставим человечков издавать звук.
Прежде, чем приступим, немного теории.
Мы ведь не хотим, чтобы те звуки, которые есть в комнате, были слышны ото всюду, верно? Следовательно, нам нужно использовать немного другой подход к созданию звуков.
Чтобы в дальнейшем иметь возможность на эти звуки влиять, предлагаю воспользоваться эмиттером — или излучателем.
Делать он будет ровно то, о чем говорится в его названии: излучать звук.
А ещё мы сможем его настроить таким образом, чтобы звук был слышен только на определённом расстоянии от излучателя, а также начинал затухать спустя определённое расстояние.
Здесь всё предельно просто.
Перейдём к oCharPlayer и создадим у него событие — alarm 0. Это событие — «будильник», или, если по нормальному, таймер, в котором будет работать код раз в определённое количество кадров. А теперь пошагово:
Как видно, звук перемещается вместе с нашими человечками. Накладывается друг на друга, но играет строго раз в определённый отрезок времени, успевая полностью «проиграться».
По аналогии с oSSound, создадим oSMusic. Разница в том, что в oSMusic мы в Create сразу пропишем переменную music, равную 0.1. Она и будет отвечать у нас за громкость музыки. Соответственно, нужно sound заменить на music в коде и всё.
Создаём файл для музыки: sndMusic
Заходим в Tools -> Audio Groups. Создаём аудио группу под названием audio_music.
Жмакаем «add asset» и выбираем sndMusic.
Теперь перейдём к oGameManager.
В Create допишем:
По сути, обозначенный выше код будет загружать нашу аудио группу музыки в память и начнёт её проигрывать.
Немного бонусов.
В ходе этой недели провёл небольшой рефакторинг кода.
Во-первых, простенькая отрисовка путей для наших человечков, что можно было видеть по видео.
Во-вторых, теперь нам не нужны объекты под каждый вид тайла.
Вместо этого теперь используем структуру и конструктор прямо в объектах меню приказов.
Там всё просто: в массив передаём информацию для конструктора о том, какой тайл нам нужен. Затем, обращаясь к массиву по индексу, вычленяем нужные нам данные по ключевым словам.
Для примера — в проекте советую открыть код для oGBuilding и oCell.
Также дополнил код для игрока, чтобы данную систему можно было спокойно тестировать и работать с ней.
Там же в проекте встроен сделан скрипт по созданию прямоугольных областей с заполнением или без.
Соответственно, где заполнения нет — обводка только по периметру.
Там так-то всё просто. Общая логика работы следующая:
Когда нажали (разово) левую кнопку мыши, мы запоминаем координаты клетки, на которую были наведены.
Далее, отдельно проверяем: если кнопка мыши зажата и координаты первой клетки запомнены, на постоянной основе обновляем координаты второй. Заодно создаём прямоугольник с заполнением или без.
Ну и при отпускании ЛКМ — проверяем, что первая координата у нас задана, обновляем картинку и обнуляем все использованные переменные.
Соответственно, как это выглядит при работе:
Сайт, откуда можно брать бесплатные ассеты: звуки, музыку, спрайты и прочее.
Либо из маркета YoYo. На ваше усмотрение.
Серия гайдов подошла к концу. У нас есть заготовка, которую остаётся дорабатывать, рефакторить и всячески дополнять, чтобы создать полноценную игру. Впрочем, это не значит, что я перестану писать всякие статейки, нет.
Буду и дальше разбирать интересные темы, делиться скриптами и заодно рассказывать о ходе работы над проектом.
На повестке: моддинг без кода ( для игроков:D )
Спасибо всем за тёплые слова и поддержку.
До скорых встреч.

Путь дурака. Игра на Unity с нуля до выпуска. Часть 2 — Как сделать главное меню игры (пост #1)
В прошлой части мы скачали Unity, подготовились к работе, создали проект, первую сцену и на ней объекты Canvas и Background. В этот раз мы создадим главное меню нашей игры.
Для начало запомните важную вещь — в 2D игре интерфейс построен на слоях. Одно поверх другого. А также связь Parent — Child (Children) — когда один объект находится в другом и свойства родительского объекта влияют на свойства потомка. Именно по этим принципам мы и будем строить наше меню. Давайте попробуем визуально представить как его можно расположить на экране.

Левый блок — это будет объект mainMenu. Он будет родителем для объектов «название игры», «пункты меню» и «ваше лого». Они тоже будут содержать в себе объекты. Начнем.
Создайте пустой объект (Empty Object) и сделайте его дочерним объекта Canvas (в иерархии перетяните один объект на другой). Другой вариант — клик ПКМ по объекту Canvas и затем выбор создания пустого объекта. Так он автоматически станет дочерним. Переименуйте его в mainMenu.

Чтобы mainMenu стало видно на экране, ему нужно добавить компонент Image через меню Add Component в инспекторе (как добавлять компонент я рассказывал в прошлом посте). Так, ну и где же он?

Чтобы придать нашему меню нужное положение, воспользуемся его компонентом Rect Transform. В разделе Anchors устанавливаем:
Затем Left, Right, Top, Bottom ставим по нулям.

Теперь установим нашему меню вместо белого пятна приятный глазу цвет. В компоненте Image нажмите на поле Color и установите:
— R — 0.012 (красный)
— G — 0.012 (зеленый)
— A — 0.7 (альфа-канал или прозрачность)

Для закрепления материала по размещению объекта на экране создадим два декоративных элемента — две полоски по бокам от плашки меню.
1. Создаём два пустых объекта как Child объекта mainMenu — line1 и line2
2. Назначаем Anchors для line1
3. Назначаем Anchors для line2
4. Устанавливаем обоим объектам цвет как у mainMenu
Теперь можно похвалить себя и подышать свежим воздухом. Далее нам нужно создать объекты для названия игры, пунктов меню и логотипа. Делаем мы это по тому же принципу — создаем дочерние объекты в mainMenu — top, middle и bottom. Для наглядности сразу добавляем им компонент Image с белым цветом (потом изменим).
Аккуратно распределяем объекты на объекте mainMenu, расставляя значения Anchors.
Top —> X: (0, 1) Y: (0.8, 0.96)
Middle —> X: (0, 1) Y: (0.15, 0.8)
Bottom —> X: (0, 1) Y: (0.04, 0.15)
Для создания небольших отступов или точного корректирования положения объекта можно задавать значения Left, Right, Top, Bottom в компоненте Rect Transform. Попробуйте поставить всем трем объектам эти значения по 2 пикселя. Главное не злоупотреблять этим, а то может верстка перестать быть стабильной.
Итак, мы нашли хорошее расположение для блоков и теперь можем удалить у них компоненты Image и Canvas Renderer, так как больше они нам не понадобятся.
Давайте сделаем для игры графическое название. Можно, конечно, и текстом, но графикой будет симпатичнее. Мы же делаем игру для людей, а не черновик для себя — так ведь?
Откроем Фотошоп и создадим в нём новый файл размером 1000х1000 пикселей.

Затем добавим название игры.

Нарисуем декоративную линию.

Добавьте слоган внизу, затем подрежьте инструментом «Рамка» лист по самые края логотипа.

Далее удаляем слой фона, чтобы сделать логотип прозрачным. Затем устанавливаем размер изображения с шириной в 1000 пикселей. После этого нам очень важно сделать так, чтобы каждая сторона изображения была кратна 4 — это необходимо для применения алгоритмов сжатия, чтобы уменьшить вес игры. Так как обрезать уже нечего, то через «Размер холста» делаем высоту 212 пикселей. Итоговый размер 1000х212.

Когда всё готово, вы должны поменять цвет всех объетов на белый. Зачем? На белое изображение в Unity мы легко сможем наложить любой цвет, если нам приспичит. На чёрный — не получится.
Сохраните полученое изображение в формате PNG и положите его в папку проекта Assets/Resources/Images (создайте её). Сам исходный файл PSD сохраните в отдельной папке вне проекта, где вы будете хранить исходники графики.
Самое время добавить созданное название в игру! Создаем для top дочерний объект gameName, добавляем ему компонент Image и выравниваем на экране. Для того, чтобы изображение не искажалось, в компоненте Image активируем Preserve Aspect — эта функция позволит сохранить пропорции.

Отлично! Гейб Ньюэлл вами был бы доволен.
Теперь займёмся объектом middle и сделаем в нем несколько кнопок, которые будут вести в нужное место — «Новая игра», «Загрузить игру», «Настройки», «Об игре», «Выход».
Нам пригодится полезный компонент под названием Vertical Layout Group. Он выравнивает дочерние объекты по вертикали, регулирует их высоту, ширину и отступы. Это означает, что нам не придётся вручную устанавливать размеры и положение кнопок. Его можно сразу добавить к объекту middle.

Таким же образом добавьте еще 4 кнопки и настройте Vertical Layout Group у объекта middle.
Padding — это отступы всего списка кнопок относительно объекта.
Spacing — это отступы между кнопок.
Потыкайте настройки, чтобы понять, как это работает, а потом сделайте как на скриншоте. Как видите, теперь у нас есть аккуратный список кнопок.

Обратите внимание на иерархию — у каждой кнопки есть дочерний объект Text. Это такой же объект, как и все, только с прикрепленным компонентом Text. В нем можно вписать текст объекта, указать шрифт, размер, начертание, цвет, выравнивание. Этих настроек вполне достаточно для нашей игры. Установите размер шрифта 24 пикселя.

Теперь можно нажать кнопку Play вверху рабочего стола и потыкать по кнопкам.
У каждой кнопки есть компонент Button, у которого есть целый ворох настроек как кнопка будет меняться при нажатии, наведении курсора итд. Однако, для мобильных платформ, где не мышка, а тачскрин, это не нужно. Поэтому отключите эту функцию, поставив Trasition —> none.
Далее можно удалить у кнопок компонент Image — для такого минималистичного дизайна он не нужен. Цвет текста сделайте белым.
В объекте bottom осталось место для вашего логотипа. Подыщите что-нибудь прикольное, нарисуйте в фотошопе и сделайте так же, как мы делали с названием игры.
Пришло время для правой части меню — не забыли про неё? Для начала определимся, что будет делать каждая кнопка.
Новая игра — выдает список слотов сохранений, при нажатии на который запустится новая игра и автоматически сохранится в этот слот.
Загрузка игры — аналогично, только загружает сохранение.
Настройки — выбор языка игры, громкости звука и музыки.
Дополнительно — авторы, ссылки, благодарности и прочая второстепенная информация.
Выход — закрывает приложение.
Сделаем на каждую кнопку кроме «Выход» своё поле с информацией, которое будет активироваться при нажатии. Создайте в Canvas дочерний объект newGameList, скопируйте для него компонент Image из объекта mainMenu и установите Anchors —> X: (0.31, 0.9) Y: (0, 1).
В нем создайте 6 кнопок для слотов сохранений и назовите их game_0, game_1, game_2, game_3, game_4, game_5. В этот раз мы не будем распределять их с помощью Vertical Layout Group, но сделаем их с небольшой графикой.
Для начала распределите их равномерно по объекту newGameList, используя Anchors.

Теперь создайте в Фотошопе новое изображение размером 400х400 пикселей. Нарисуйте в нем прямоугольник с границей, но без заливки, как показано на скриншоте.

А затем нарисуйте прямоугольник поменьше, но с заливкой.

Удалите слой фона, сделайте прямоугольники белого цвета и сохраните как PNG в папку Assets/Resources/Images под именем frame_1.
В Unity нам потребуется отредактировать границы спрайта изображения, для того чтобы мы могли его без искажений растягивать в разные стороны. В дереве проекта выберите наше новое изображение frame_1, нажмите в инспекторе Sprite Editor и в открывшемся окне установите Border (границы) на 12 пикселей. Именно в этих местах спрайти будет растягиваться, подгоняясь под размеры кнопки. Закройте это окно и нажмите Save.

Примените новый спрайт ко всем кнопкам и в компоненте Image установите Image Type на Sliced. Надо поправить цвет кнопок.
— R — 0.012 (красный)
— G — 0.012 (зеленый)
— A — 0.7 (альфа-канал или прозрачность)
Если вам хочется немного свободно места между слотами, то добавьте на кнопки отступы по 5 пикселей с каждой стороны.
Цвет текста кнопок так же меняем на белый.

Так как нам нужно точно такое же поле для раздела «Загрузка игры», мы можем просто скопировать это. Деактивируйте объект newGameList, нажав на галочку возле его имени в инспекторе, затем в иерархии щёлкните по нему ПКМ и нажмите Duplicate. Теперь нужно только его переименовать в loadGameList, чтобы не путаться. Деактивируйте его, чтобы не мешался.
Раздел «Настройки». Создайте такое же поле, но только без кнопок. Этот раздел посложнее предыдущего, поэтому сделаем для начала небольшие намётки.

Первым сделаем блок выбора языка с выпадающим списком. Нужно создать объект language внутри optionsList и установить ему Anchors X: (0.03, 0.97) Y (0.85, 0.95). Внутри language создаем объект header, устанавливаем Anchors X: (0, 0.48) Y (0, 1), добавляем ему компонент Text с размером шрифта 24 и выравниванием по правому краю и по центру.

Теперь нам нужно сделать выпадающий список. В Unity уже есть готовое решение — нам нужно только правильно его настроить. Добавьте в language объект UI -> Dropdown и устанвите ему Anchors X: (0.5, 1) Y (0, 1). Сразу же можно установить ему почти чёрный цвет с прозрачностью 0.78.

В нём достаточно много дочерних объектов. Разверните его полностью и внимательно поменяйте настройки. По шаблону «Объект: Компонент —> настройки».
— Dropdown: Dropdown —> Transition «none», список Options — поменять Option A итд на названия языков игры.
— Label: Text —> Русский, размер шрифта 24, цвет белый.
— Arrow: Rect Transform —> PosX -20, Wigth 40, Height 40.
— Template: Rect Transform —> Height 450; цвет сделать как у объекта Dropdown
— Content: Rect Transform —> Height 80.
— Item: Rect Transform —> Height 80; Toggle —> Transition «none»
— Item Background: цвет сделать как у объекта Dropdown
— Item Checkmark: Rect Transform —> PosY -5
— Item Label: Rect Transform —> Left 25, Top 15; Text —> размер шрифта 24, цвет белый.
Если ничего не пропустить, то результат будет как на видео ниже.
По аналогии с языковой панелью делаем объект music, размещаем в нём объект header с компонентом Text (пишем «Громкость музыки»). Нам понадобится слайдер — добавляем его UI/Slider с Anchors X: (0.5, 1) Y (0.3, 0.7).
В компоненте Slider отключаем Transition.
В дочернем объекте Background делаем черный цвет.
Таким же образом создаём слайдер для «Громкости звуков».
Готово! Вы — великолепны!
Лимит картинок опять исчерпан, поэтому продолжим в следующий раз.
Экспериментируйте с оформлением и не бойтесь трогать все настройки подряд. В этот раз я приложу ссылку на архив с проектом из поста.

GameMaker Studio 2. Урок 2. События отрисовки. Коллизия. Как работают скрипты. Как подключить русский шрифт. Переходы между комнатами
Сегодня у нас много матчасти и не очень много кода.
Конкретизация разработки.
Как было сказано в прошлом посте, игра, которая будет сделана в ходе данных гайдов, будет относиться к жанру стратегий, а в качестве источников для «вдохновения» у нас — «Oxygen Not Included» и «Rimworld«. Теперь же конкретно поговорим с вами о том, что в игре должно быть реализовано, по пунктам.
—) Персонаж — игровой «объект», способный перемещаться по игровому миру и взаимодействовать с ним. Делятся на подконтрольных и неподконтрольных игроку. Игрок НЕ имеет прямого управления над своими подопечными, кроме специального «боевого» режима.
—) Каждый персонаж должен иметь или уметь следующее:
—) Взаимодействовать с предметами, расположенными на карте: подбирать их в свой инвентарь или выкладывать; взаимодействовать с рабочими станциями; сражаться (наносить, получать урон).
—) Каждый персонаж смертен. Каждый персонаж должен иметь ряд характеристик, которые он будет пытаться «поддерживать» на должном уровне, чтобы не умереть и продолжать быть эффективным. Эти характеристики:
—) Каждый персонаж уникален и должен отличаться от других. Черты, навыки с различными уровнями прокачки. Этот пункт может игнорироваться в случае, если это не подходит под конкретного персонажа.
—) Объекты, с которыми можно взаимодействовать через интерфейс игры и с которыми могут взаимодействовать персонажи или иные игровые сущности с какой-то целью.
—) Пример: верстак для создания вещей; исследовательский стол для открытия новых вещей и пр.
-) Интерфейс.
—) Простой, понятный. Желательно, на русском языке.
—) Хотя бы минимально настраиваемый.
Скажу сразу, что персонажей мы делать будем позже. Начнём мы с интерактивных объектов и размещения их в мире. Но, это будет потом.
Сейчас — продолжаем изучать матчасть.
События отрисовки.
Событие отрисовки добавляется на объект как и любое другое, через кнопку «Добавить событие (Add Event)».
Имеется два события:
—) Событие, которое отрисовывает объект в комнате.
—) Событие, которое отрисовывает объект на экране.

Иными словами, событие отрисовки GUI позволяет нам закрепить на экране наш интерфейс и то, что мы хотим игроку показывать всегда. Draw — стандартная отрисовка.
Возникает вопрос: зачем нам отдельно добавлять событие отрисовки, если объект спокойно отрисовывается и без него?
Ответ: в событии отрисовки можно написать код, который позволит нам менять параметры отрисовки, будь то: изменение размера (соотношения сторон); изменение цвета; создание дополнительных графических эффектов; etc.
Если вы добавили событие отрисовки, то вам необходимо написать в коде следующую строку:
В противном случае, объект не будет отрисован.
Проделайте это сами. 🙂
Итак. Что мы можем делать в событиях отрисовки:
-) Отрисовка спрайтов:
—) draw_self() — отрисовывает спрайт текущего объекта с настройками по умолчанию.
—) draw_sprite_ext( название спрайта в обозревателе, номер изображения, x, y, x-масштабирование, y-масштабирование, поворот, цвет, прозрачность) — отрисовка спрайта «расширенная» — т.е. с настройками. Можно отрисовать любой спрайт, как и везде, где его нужно отдельно указывать.
—) draw_sprite_part(название спрайта в обозревателе, номер изображения, x координата левой верхней точки спрайта, y координата левой верхней точки спрайта, ширина, высота, x, y) — отрисовка части спрайта
—) draw_sprite_stretched(название спрайта в обозревателе, номер изображения, x, y, ширина, высота) — отрисовка спрайта с его «растяжением». Если у спрайта включить и настроить функцию Nine Slice (девять «срезов»), то можно создавать масштабируемые (с одинаковым разрешением, пропорциями и качеством по итогу) элементы интерфейса: окошки, кнопки, etc.
-) Отрисовка фигур:
—) draw_circle(x, y, радиус, заполнение (True/False)) — рисуем круг. Аналогичное есть для прямоугольника (rectangle), стрелки (arrow), эллипса (ellipse), линии (line).
—) draw_button(x, y, x2, y2, up) — Отрисовка кнопки. Где up — True или False, нажата кнопка или нет.
-) Настройки отрисовки.
—) ВАЖНО. Любые настройки отрисовки нужно проводить ПЕРЕД отрисовкой. Можно делать в любом событии, но для удобства лучше тут же.
—) draw_set_color(col) — устанавливаем цвет отрисовки. Базовые значения цветов начинаются с приписки «c_». Пример: c_black, c_red.
—) Для продвинутых — можно использовать HEX, как в CSS: #11CCFF как пример. Используется стандартная RGB система. Если заменить решётку на $, то система сменится на BBGGRR, т.е. наоборот.
—) draw_set_alpha(alpha) — прозрачность отрисовки
—) draw_set_font(font) — устанавливаем шрифт
—) draw_set_halign(halign) — Расположение текста по горизонтальной оси (fa_ left/center/right)
—) draw_set_valign(valign) — Расположение текста по горизонтальной оси (fa_ top/middle/bottom)
Это та часть, что касается кода и с которой мы с вами будем непосредственно работать. Можете держать как памятку у себя перед глазами, когда начнём писать код.
Коллизия — иначе говоря, столкновение объектов, происходит благодаря «маске» спрайта. Если спрайт — это картинка объекта, то маска — это «твёрдое тело», отвечающее за считывание столкновений.
Чтобы её посмотреть, откройте настройки спрайта и разверните пункт «Collision Mask«

Хотя маска может иметь несколько форм, о которых будет написано ниже, устанавливается она исходя из четырёх позиций — левого верхнего и правого нижнего углов. Именно эта маска считывает столкновения, а не сам спрайт.
Mode — режим маски. Варианты:
— Автоматическая
— На всё изображение
— Ручная
Type — тип маски. Варианты:
— Прямоугольник
— Прямоугольник с поворотом
— Эллипс (работает медленнее)
— «Алмаз» (ромб) (работает медленнее)
— Предрасчет / Точный (медленнее) — ГМС постарается сам подстроить маску под форму объекта.
— Предрасчет / Точный по кадрам.
Мой совет:
Если игра небольшая, ставьте ручной режим и настраивайте сами те объекты, для которых это важно. Особенно те объекты, столкновение с которыми должно происходить только в определённой позиции (скажем, как в Стардью, сталкиваешься с основанием дерева, но не с его кроной).
В нашей игре данная настройка нам практически не пригодится, так как будет использоваться система поиска путей. Тем не менее, с помощью маски можно будет реализовать «выталкивание» застрявших персонажей, а также настроить косметическое «расталкивание» персонажей, если те проходят через занятую другим персонажем клетку.
Как работают скрипты.
Скрипт (функция) — именованный блок кода, выполняющий определённую задачу.
Все команды, которые мы использовали до этого, являются такими «скриптами». Иногда я буду называть их функциями, оба варианта правильные.
Создать скрипт просто. Для этого нажмите ПКМ по папке «Scripts» и выберете там «Script«. Назовите его scrMove
У вас откроется следующее окно:

scrMove — название нашей функции. В круглых скобках мы в неё можем передавать аргументы. Аргумент — это переменная, которая используется только в функции, передаётся в неё при вызове и может иметь любое название. В скобках напишите spd — это будет как раз наша переменная скорости.
Вырежьте код движения из Step-события у игрока и вставьте в скрипт, а в Step-событии игрока напишите следующий код:
scrMove(player_speed);
Получится следующая картина:


Как вы заметили, «x» и «y» у нас по прежнему работают. Это потому, что мы выполняем скрипт в объекте oPlayer: данные переменные подтягиваются из объекта автоматически.
Когда нужно применять скрипты?
-) Когда код, который мы пишем, нужно использовать несколько раз.
-) Когда код, который мы пишем, занимает много места, чтобы его было проще отладить.
-) Когда нам нужно получить какое-либо значение на основе каких-либо данных, так как скрипт может не просто выполнять код, но и возвращать значения.
Для того, чтобы скрипт вернул какое-то значение, нужно написать:
Переменную можно написать только одну. Команда return прерывает выполнение скрипта. Переменную / возвращаемое значение можно не писать, тогда скрипт просто прервётся.
Конструкцию с прерыванием следует добавлять везде, где это может повлиять на игру, особенно её работоспособность.
Раньше скрипты выполнялись медленнее, чем код, написанный просто в объекте. Сейчас это не так (или, по крайней мере, не так критично).
Также стоит понимать, что создав объект «Скрипт«, вы, по сути, создали просто файл для хранения кода. В одном скрипте может быть собрано сразу множество разных функций, отвечающих за выполнение одной задачи. При вызове обращаться нужно именно к имени функции.
Скрипт для отрисовки текста с обводкой.
Создаём новый скрипт и называем его scrOutlinedText
Нам понадобятся следующие аргументы:
-) xPos — позиция текста по X
-) yPos — позиция текста по y
-) col — цвет текста
-) outlineCol — цвет обводки
-) text — текст
-) curdepth — текущая «глубина» объекта.
-) Шрифт, которым будем рисовать.
-) Позиционирование по X
-) Позиционирование по Y
Общая схема работы скрипта:
1) Назначаем максимальную «глубину».
2) Рисуем текст цветом обводки.
3) Поверх рисуем текст нужным нам цветом, но с небольшим смещением.
4) Возвращаем глубину к первоначальным показателям.
Код:
https://pastebin.com/TahYZKc8
P.S.
Изначально код не мой, а честно стырен подсмотрен с интернета, но я в него добавил больше переменных для лучшей настройки и отрисовки. Фактически, значение глубины тоже можно передавать как аргумент, чтобы разный текст выводился по разному.

Создание русского шрифта
Проверим, как работает скрипт.
Сначала мы создадим русский шрифт. Для этого найдём папку «Fonts«, нажмём ПКМ и создадим «Font«.
Выбирайте любой шрифт и размер, который хотите. Нам с вами нужна кнопка «Add«, чтобы добавить диапазон с русским шрифтом.


Здесь напишем 1040 to 1105, чтобы захватить весь русский алфавит, затем нажмём «Add Range».
Шрифт называйте на Ваше усмотрение. Я назову его: fontArialRusSmall
Теперь перейдём к объекту игрока. Создадим событие Draw GUI и напишем следующий код:
scrOutlinedText(10, 10, c_yellow, c_red, «Скорость: » + string(player_speed), depth, fontArialRusSmall, fa_left, fa_top)
Результат:

Можете заменить c_yellow и c_red на любые цвета. Помните, что можно передавать цвета в HEX с помощью # и $ (в обратном порядке).
Скрипт для поиска значения в массиве:
Так как эту тему мы не проходили, заострять внимание не буду, но вдруг кому пригодится:
https://pastebin.com/1VTNg4Bp
Переходы между комнатами. Создаём меню.
Наконец, с матчастью мы закончили. Приступим к тому, что создадим меню нашей игры.
Создаём новую комнату и обзываем её rmMainMenu. Затем нажмите на значок «домика», чтобы поменять стартовую комнату (ту, что отображается при запуске игры).

Сделайте так, чтобы домик был напротив созданной комнаты.
Заметьте, что при создании новой комнаты у неё изменяются все настройки! Это важно.
Создадим в «Objects» папку «Меню«, где создадим следующие объекты: «oMStart«, «oMSettings«, «oMExit«, «oMMenu«.
OMStart — кнопка для старта нашей игры.
OMSettings — кнопка для перехода в настройки игры.
oMExit — кнопка для выхода из игры
oMLoad — кнопка для загрузки игры
oMMenu — управляющий объект, который будет располагать наши кнопки.
Зайдём в комнату MainMenu и поставим там объект oMMenu.
Затем перейдём в код oMMenu и выберем событие создания (Create)
Там напишем следующий код:
Теперь нужно каждую из этих кнопок разместить. Но, чтобы правильно их разместить, сделаем на все кнопки один спрайт. Размер подбирайте под себя.
У каждого объекта создадим два события: Draw, которое оставим пустым, и Draw GUI, где напишем draw_self();
Там же напишем:
Где «Здесь текст кнопки» — заменить на нужное: «Начать игру«, «Загрузить игру«, «Настройки«, «Выход«
Вернёмся в OMMenu.
Нажмите правой кнопкой мыши. Наведитесь на пункт «Code Snippets» и выберите пункт 5.
В данном меню расположены готовые шаблоны кода, а мы создали шаблон цикла.
Напишите следующий код:
for (var i = 0; i < array_length(buttons); ++i)
<
instance_create_layer(room_width / 2, room_height / 2 — 50 + sprite_get_height(sButton) / 2 + 100 * i, «Instances», buttons[i])
>

Теперь нужно сделать отслеживание нашей мышки. Кнопку «Настройки» мы сделаем чуть позже. Пока перейдём к кнопке для выхода из игры.
До текста отрисовки нашего текста, нам нужно сделать небольшую подсветку нашей кнопки, чтобы мы знали, что она работает. Для этого нам нужно отслеживать позицию нашей мыши относительно интерфейса, для чего есть специальная команда.
ОК. Теперь мы отслеживаем нашу мышку относительно GUI. Нужно проверить, наведены ли мы на конкретный объект и если да — нарисовать поверх него полупрозрачный белый прямоугольник. Для этого есть команда:
instance_position(x, y, obj)
В x и y мы передадим переменные выше, а в качестве объекта напишем «self«, чтобы проверять координаты нашего объекта.
Уже после этого пишем наш текст.
Теперь при наведении на кнопку «выхода» мы увидим, что она «активна».
Вырежем наши две переменные, добавим их в событие create. Теперь мы можем использовать эти переменные в любом коде этого объекта.
Теперь перейдём в событие step. Сюда также добавим наши две переменные. Теперь они будут постоянно обновляться.
Начнём настраивать логику работы.
Можете скопировать тот код, что мы писали выше, но удалить всё изнутри.
Нам нужно сделать проверку:
Если мы наведены на объект И нажата левая кнопка мыши — выйти из игры. То есть, немного её дополнить.
Для проверки нажатия кнопки левой мыши будем использовать команду:
mouse_check_button_pressed(mb_left)
Для выхода из игры:
game_end()
В итоге, в коде step будет следующий код:
Итого, если мы наведёмся на кнопку выхода — она подсветится. Нажмём — игра закроется.
Аналогичный код с подсветкой и проверкой просто скопируем в oMStart. В других кнопках логику работы в step пока не настраиваем на них, работаем с кнопкой начала игры.
Нужно внести одно изменение.
Вместо game_end() нам нужно написать код для смены уровня.
Для этого напишем:
room_goto(Room1)
Где Room1 — название комнаты, в которую вы хотите переместиться. Оно должно совпадать с названием комнаты в браузере ассетов.
Итого, мы можем выйти из игры или перейти в комнату, где у нас есть игрок, которым мы можем управлять. Осталось дополнить написать код, чтобы мы могли вернуться обратно в меню, при этом так, чтобы положение игрока на экране сохранялось.
Для этого нам придётся создать новый объект и назвать его oGameManager.
Разместим его в самой первой комнате и отметим у него чекбокс «Persistent«
Затем напишем у него в Step код:
Если индекс текущей комнаты != 0 и нажата ESC — деактивируем все инстансы, кроме текущего и переходим в меню.

При старте комнаты, если эта комната не является меню, мы будем запускать все инстансы.
Реализация сложнее. О том, как работает Nine Slice.
Ниже будет приведена реализация меню с использованием функции Nine Slice, которая позволит нам делать кнопки других размеров.
Используя Nine Slice мы не сможем проверять, наведены ли мы сейчас на нужный нам объект. Также эта функция годится только для отрисовки типовых форм с типовым шрифтом. Если у вас спрайт кнопки идёт с текстом, то данная функция не подойдёт.
Чтобы отслеживать нажатия и наведение, нам необходимо проверять, находятся ли координаты мыши в нужной области. Для этого существует команда
Итак. Первый шаг — это убрать спрайт у каждой нашей кнопки.
Для этого откроем объект каждой кнопки, нажмём на выбор спрайта и выберем «None«.
Шаг второй.
У каждой кнопки в событии Create мы пропишем:
При создании кнопок мы и так будем знать их x и y координаты, а ширину и высоту будем передавать.
Шаг третий
Нарисуем спрайт в виде одноцветного квадрата размером 9х9 пикселей.
Затем добавим ему две обводки разных цветов, каждая шириной в 1 пиксель.
Получим следующую картину:

Теперь перейдём в настройки спрайта.
Назовём его sButtonSlice.
Слева выберем и откроем пункт Nine Slice.
После чего поставим галочку «Activate Nine Slice«.
Далее — смотрим на наш спрайт и настраиваем его, как показано на скриншоте ниже:

Чтобы двигать фиолетовые полоски — достаточно на них навестись и зажать ЛКМ.
В правом окошке вы можете порастягивать данный спрайт, как хотите и посмотреть на итоговый результат.
Растягивающаяся рамка для кнопок готова!
Шаг четвертый.
Пропишем в Draw GUI отрисовку кнопки вместо draw_self():
Таким образом, мы отрисовываем кнопку.
Вернёмся в oMMenu, в Create, где немного допишем наш код.
Мы создадим переменную, которой будем присваивать значение ID только что созданного объекта. Затем, обращаясь к этой переменной, мы будем менять у данного объекта параметры: ширину и высоту.
Меняя значения bwidth и bheight вы сможете сами настроить нужные размеры кнопок.
Обратите внимание, что создавая инстанс мы можем передать struct — то есть структуру данных.
Тогда не нужно будет обращаться к инстансу через переменную, но придется удалить код
При создании наших объектов, а сам код для создания инстанса преобразится следующим образом:
Какой из вариантов удобнее — решать вам.
Вариант с переменными, которые объявляются при создании объекта, я лично считаю более надёжным, а функциональных отличий между данными командами не так много. С другой стороны, такая возможность появилось недавно и её нужно тестировать.
Теперь задача — сделать так, чтобы мы могли считывать, наведены ли мы сейчас на кнопку.
Для этого мы берём координаты x и y, после чего проверяем, находится ли наша мышь в области:
Остальное — копируем из прошлого кода. Получается следующий блок:
Шаг седьмой.
Проделать тоже самое в событии Step. (По сути, просто заменяем instance_position)
Шаг восьмой.
Донастраиваем все кнопки.
Какой из вариантов использовать — решать Вам.
Можно вообще использовать следующий вариант:
Создать спрайт нужных размеров и залить его белым цветом с «прозрачностью» в 1 единицу. Совершенно незаметно. Используя bbox_left / top / right / bottom нарисовать поверх прозрачной основы кнопку и проверять уже не через «point_in_rectangle», а как в первом способе.
На этом сегодняшний гайд подходит к концу.
Вкратце мы разобрали события отрисовки; как с ними работать; как работать со скриптами; как работать со шрифтами; а также вы можете смело скопировать себе и использовать несколько других скриптов в своих проектах.
Что нужно подготовить к следующему гайду:
— Минимум два спрайта «породы» — на фон (темнее) и для объекта (светлее). Размер одного спрайта — 32х32.
— Желательно спрайты нескольких объектов, вроде стен, дверей. Исходите из того, что размер одной клетки будет равен 32х32 пикселей.
— Спрайт для неба/космоса/прочего на фон на ваше усмотрение.
Я подготовлю свои варианты и, используя их, на следующем занятии мы с вами разберёмся, как работает камера.
Сделаем меню настроек с возможностью переключения в полноэкранный режим.
И небольшой спойлер на будущее.
Взаимодействовать с миром можно будет двумя способами: через ЛКМ и наведением «тела» игрока на тот или иной объект.
Загрузить файл проекта и всё пощупать самому можно по ссылке:
Яндекс диск
— Камера и её настройка. Разные способы реализации: от простого к сложному.
— Иерархия объектов. «Объекты-родители» и их «дети». Решение часто встречающихся проблем и немного про то, как удобно выстраивать взаимодействие с объектами. Глобальные переменные.
— Массивы и с чем их едят, а также grid (сетка комнаты), размещение объектов по сетке. Включая объяснение, в каких случаях лучше использовать встроенные функции, в каких – писать свои с нуля.
— Пути. Один большой гайд, включая скрипты поиска путей для различных сеток в т.ч. с примерами из моего личного проекта.
— Иные способы хранения информации в GMS2, когда их стоит или не стоит использовать.
— Сохранение. Встроенное VS самописное.
Есть вопрос — задавай, постараюсь ответить.
Что-то не получилось, вылезла ошибка и так далее — тоже пиши, помогу или поможем.