Основы языка программирования (Language Basics)

Материал из Ren'Py Wiki
Перейти к навигации Перейти к поиску

Прежде чем мы сможем описать язык программирования на движке Ren'Py, сначала мы должны рассказать о структуре скрипта визуальной новеллы, созданной на данном движке. Структура скрипта включает информацию о том, как файлы разбиваются на блоки, состоящие из строк, и как эти строки разделяются на элементы, которые образуют операторы.

Файлы (Files)[править | править код]

Скрипт игры на Ren'Py состоит из всех файлов, найденных в папке игры, с расширением .rpy. Ren'Py рассмотрит каждый из этих файлов (в порядке Юникода) и использует содержимое файлов в качестве скрипта.

Как правило, нет разницы между скриптом, разбитым на несколько файлов, и скриптом, состоящим из одного большого файла. Управление между файлами может передаваться через прыжки (оператор jump) или вызов метки в другом файле. Это делает разделение скрипта на файлы делом вкуса, так как некоторые разработчики игр предпочитают маленькие файлы (к примеру, по файлу на событие или день), тогда как другие предпочитают один большой скрипт.

Чтобы ускорить время загрузки, Ren'Py компилирует файлы .rpy в .rpyc во время запуска. При изменении файла .rpy, файл .rpyc будет обновляться при запуске Ren'Py. Однако если файл .rpyc существует без соответствующего файла .rpy, то он будет использоваться. Если файл .rpy будет удален без удаления файла .rpyc, то это может привести к проблемам,

Базовый каталог (Base Directory)[править | править код]

Базовый каталог – каталог, содержащий все файлы, распространяемые вместе с игрой (может также содержать некоторые не распространяемые вместе с игрой файлы). Такие файлы, как README, должны быть помещены в базовый каталог, откуда они будут распространены.

Базовый каталог создаётся внутри директории Ren'Py и называется именем вашей игры. К примеру, если папка с Ren'Py называется «renpy-6.11.2», а ваша игра – «HelloWorld», то базовый каталог этой игры будет «renpy-6.11.2/HelloWorld».

Директория игры (Game Directory)[править | править код]

Директория игры почти всегда является папкой с названием «game» внутри базового каталога. К примеру, если базовый каталог – «renpy-6.11.2/HelloWorld», то директория игры будет «renpy-6.11.2/HelloWorld/game».

Однако следует учитывать, что Ren'Py выполняет поиск директорий в следующем порядке:

  • Имя исполняемого файла без расширения. К примеру, если исполняемый файл называется moonlight.exe, Ren'Py будет искать папку с названием moonlight в базовом каталоге.
  • Имя исполняемого файла без расширения и и с удаленным префиксом, оканчивающимся на _. К примеру, если исполняемый файл называется moonlight_en.exe, Ren'Py будет искать папку с названием en.
  • Папки «game», «data» и «launcher», именно в таком порядке.

Тем не менее Ren'Py Launcher будет корректно распознавать папки «game» и «data».

Директория игры содержит все файлы, используемые в игре. Она, включая все подкаталоги, сканируется Ren'Py на наличие файлов .rpy и .rpyc и они объединяются для создания скрипта игры. Директория игры сканируется на наличие архивных файлов .rpa и они автоматически используются игрой. Наконец, когда игра указывает путь к файлу загрузки, он загружается относительно директории игры (но учтите, что config.searchpath может изменить это).

Комментарии (Comments)[править | править код]

Скрипт Ren'Py может содержать комментарии. Комментарий начинается со знака решётки и заканчивается в конце строки, содержащей комментарий. В порядке исключения комментарий не может быть частью строки, заключенной в двойные кавычки.

# Это комментарий.
show black # Это тоже комментарий.

"# Это не комментарий, так как это часть строки."

Ren'Py игнорирует комментарии, так что скрипт обрабатывается так, словно в нём нет комментария.

Логические строки (Logical Lines)[править | править код]

Файл скрипта разбивается на логические строки. В файле логическая строка всегда начинается с начала строки. Логическая строка заканчивается в конце строки, кроме тех случаев, когда:

  • Последний символ в строке – обратная косая черта.
  • Строка содержит открывающуюся скобку ( '(' , '{', или '[' ), которая не сопровождается соответствующей закрывающейся скобкой (( ')' , '}' , или ']' ).
  • Конец строки возникает в ходе последовательности символов.

После того, как логическая строка заканчивается, следующая логическая строка начинается с начала следующей строки.

Большинство операторов на языке Ren'Py состоять из одной логической строки, в то время как некоторые операторы состоят из нескольких строк.

"Это одна логическая строка" 

"Так как эта строка содержит последовательность символов, то она продолжается
 даже тогда, когда строка заканчивается."

$ a = [ "Из-за скобок, эта строка тоже",
        "охватывает больше, чем одну строку." ]

Пустые логические строки игнорируются Ren'Py.

Отступы и блоки (Indentation and Blocks)[править | править код]

Отступы – имя, которое мы даем пространству в начале каждой логического строки, которое используется для выравнивания операторов Ren'Py. В Ren'Py отступы должны состоять только из пробелов.

Отступы используется для группировки операторов в блоки. Блок представляет собой группу строк и часто группу операторов.


Правила для разделения файла на блоки:

  • Блок открывается в начале файла.
  • Новый блок запускается всякий раз, когда логическая строка отступает от предыдущей логической строки.
  • Все логические строки внутри блока должны иметь одинаковый отступ.
  • Блок заканчивается, когда обнаруживается логическая строка с меньшим отступом, чем строки в блоке.


Отступ очень важен для Ren'Py и является причиной синтаксических или логических ошибок, когда расположен неправильно. В то же время использование отступов для передачи структуры блока дает нам возможность указывать на эту структуру, не перегружая текст скрипта.

"Этот оператор say и нижеследующий оператор if являются частью блока."

if True:

    "Но этот оператор say – часть нового блока."

    "Это тоже часть нового блока."

"Это снова часть первого блока."

Инициализация (Init)[править | править код]

Оператор init используется для выполнения блоков операторов Ren'Py до того, как скрипт будет запущен. Блоки инициализации используются для определения изображений и персонажей, настройки структуры постоянных данных игры и персонализации Ren'Py. Внутренний код блоков инициализации не должен взаимодействовать с пользователем или изменять какие-либо слои, как и содержать операторы say, menu, scene, show и hide, а также вызывать любую функцию, которая может выполнить вышеуказанное.

Оператор init начинается с ключевого слова init, за которым следует необязательный указатель приоритета и обязательное двоеточие. Если очередность не задана, то она по умолчанию указывается как 0. Указатели приоритета должны располагаться в диапазоне от -999 до 999. Номера за пределами этого диапазона зарезервированы кодом Ren'Py.

Указатель приоритета используется для определения порядка выполнения кода в блоке инициализации. Блоки инициализации выполняются в приоритетном порядке возрастания номеров. В пределах файла скрипта, блоки инициализации с одинаковым приоритетом выполняются в порядке от верхней части файла вниз. Порядок оценки последовательности выполнения приоритетных блоков с одинаковым приоритетом между файлами скрипта не определен.

Блоки инициализации исполняются только один раз, во время специальной фазы инициализации. Когда контроль достигает конца такого блока во время нормального выполнения кода скрипта, его выполнение заканчивается. Если оператор init возникает во время нормального выполнения файла скрипта, такой блок инициализации не выполняется. Вместо этого управление передается следующему оператору.

Элементы операторов Ren'Py (Elements of Statements)[править | править код]

Операторы Ren'Py состоят из нескольких основных частей:

Ключевое слово
Ключевое слово – слово, которое должно дословно воспроизводится в скрипте игры. Оно используются для объявления операторов и свойств в коде.
Имена ключевого слова, начинающиеся с одинарного подчёркивания, зарезервированы для внутреннего использования Ren'Py, если иное не задокументировано. Когда имя начинается с __, но не заканчивается __, то оно изменяется на определённую версию файла с таким именем.
Имя
Имя начинается с буквы или символа подчеркивания, за которым следует ноль или более букв, чисел и подчеркиваний. В нашем случае символы Юникода между U+00a0 и U+fffd рассматриваются как буквы.
Имя изображения
Имя изображения состоит из одного или более элементов, разделенных пробелами. Первый составной элемент имени изображения называется тегом изображения. Второй и последующие компоненты имени – атрибуты изображения. Элемент изображения состоит из последовательности букв, чисел и подчеркиваний.
Например, возьмем имя изображения mary beach night happy. Тегом изображения в данном случае будет mary, а атрибутами изображения – beach, night и happy.
Строка (Последовательность символов)
Строка начинается с символа кавычки (один из ", ' или `), содержит некоторую последовательность символов и заканчивается тем же символом кавычки, с которого началась.
Обратная косая черта используется для исключения кавычек и специальных символов, таких как % (записываются как \%), [ (записываются как \[) и { (записываются как \{). Также обратный слеш используется для включения разрыва строк с помощью \n.
Внутри строки в Ren'Py, несколько пробелов подряд сокращается до одного пробела, если только пробелу не предшествует обратный слеш.
'Строки не\'могут содержать свой разделитель, если только вы сможете избежать его.'
Простое выражение
Простое выражение – выражения языка Python, используемое для включения синтаксиса языка Python в некоторые части скрипта Ren'Py. Простое выражения начинаются с:
  • ​Имени.
  • Последовательности символов.
  • Числа.
  • Любого выражения Python, в скобках.
За этим может следовать любое количество:
  • Точки, за которой следует имя.
  • Выражение Python, заключенное в скобки.
Например, 3, (3+4), foo.bar, и foo(42) – всё это простые выражения. Но 3+4 не является простым выражением, поскольку выражение заканчивается в конце строки.
В списке
В списке приведен список простых выражений, разделенных запятыми.
Выражение Python
Выражение Python – произвольное выражение Python, которое может не включать двоеточие. Выражения используются для выражения условия в операторах if и while.

Общий синтаксис для оператора (Common Statement Syntax)[править | править код]

Большинство операторов Ren'Py имеют общий синтаксис. За исключением оператора say, операторы начинаются с ключевого слова, которое вводит оператор в код. За ключевым словом следует параметр, если оператор его принимает.

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

Если оператор включает в себя блок, строка заканчивается двоеточием. Иначе строка просто заканчивается.

Синтаксис выражения языка Python (Python Expression Syntax)[править | править код]

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



Многие элементы Ren'Py принимают выражения языка Python. Например, определение нового персонажа связано с вызовом функции Character. Хотя выражения Python очень эффектны, только часть возможностей необходима для написания базовой игры на движке Ren'Py.


Вот краткий обзор выражений Python:

Целое число
Целое число представляет собой число без десятичной точки. 3 и 42 – целые числа.
Число с плавающей точкой
Число с плавающей точкой (англ. float) – число с десятичной точкой. .5, 7., 9.0 – это всё числа с плавающей точкой.
Строка (Последовательность символов)
Строки в Python начинаются с двойных (") или одинарных (') кавычек и заканчиваются тем же символом кавычки, с которого начались. Обратный слеш используется, чтобы избежать символа окончания строки и для внедрения специальных символов, таких как символ разрыва строк. В отличие от строк в Ren'Py, строки в Python не могут быть изменены.
Истина, Ложь, Отсутствие значения
Существует три специальных значения. True – истинное значение, False – ложное значение, а None означает отсутствие значения.
Кортеж
Кортежи применяются для представления контейнеров, где количество элементов имеет важное значение.
Например, можно было бы использовать двухэлементный кортеж (еще называют пара) для обозначения ширины и высоты или четырехэлементный кортеж (х, у, ширина, высота) для представления прямоугольника.
Кортежи начинаются с открывающей (левой) круглой скобки, состоят из нуля или более выражений языка Python, разделенных друг от друга запятыми, и заканчиваются правой (закрывающей) круглой скобкой. В качестве исключения, одноэлементный кортеж должен иметь запятую, следующую за элементом. Например:
()
(1,)
(1, "#555")
(32, 24, 200, 100)
Список
Списки применяются для представления контейнеров, где количество элементов может варьироваться. Список начинается с открывающейся квадратной скобки, содержит список выражений, разделенный запятыми, и заканчивается закрывающейся квадратной скобкой. Например:
[ ]
[ 1 ]
[ 1, 2 ]
[ 1, 2, 3]
Переменная
Выражения в Python могут использовать переменные, которые хранят значения, определенные с помощью оператора define или операторов python. Переменная начинается с буквы или символа подчеркивания и состоит из нуля или более букв, цифр и подчеркиваний. Например:
name
love_love_points
trebuchet2_range
Переменные, начинающиеся с _, зарезервированы для внутреннего использования Ren'Py и не должны использоваться в пользовательском коде.
Доступ к полю
Модули и объекты языка Python имеют поля, доступ к которым можно получить с помощью комбинации выражения (как правило, переменной) и имени поля, разделенных точкой. Например,
config.screen_width
Приведенное выражение состоит из переменной (config) и доступа к полю (screen_width).
Вызов
Выражения языка Python могут вызывать функцию, которая возвращает значение. Они начинаются с выражения (как правило, переменной), за которым следует левая круглая скобка, список аргументов, разделенных запятыми, и заканчиваются правой круглой скобкой. Список аргументов начинается с позиционных аргументов, которые являются выражениями языка Python. Далее следуют именованный аргумент, которые состоят из имени аргумента, знака равенства и выражения. Например, в приведенном примере
Character("Эйлин", type=adv, color="#0f0")
мы вызываем функцию Character. Она содержит один позиционный аргумент ("Эйлин"), два именованных аргумента: type со значением переменной adv и color со значением строки "#0f0".
Конструкторы представляют собой тип функции, которая возвращает новый объект и называется аналогичным образом.


При чтении этой документации, вы можете заметить сигнатуру функции как:

Sample(name, delay, position=(0, 0), **properties)
Пример функции, которая фактически не существует в Ren'Py, но используется только в документации.

Данная функция:

  • Называется "Sample".
  • Имеет два позиционных параметра: name и delay. В реальной функции типы этих параметров будут четко изложены в документации.
  • Имеет один именованный аргумент, position, который имеет значение по-умолчанию (0,0).

Поскольку функция заканчивается на **properties, это значит, что она может принимать свойства стиля в качестве дополнительных именованных аргументов. Другими специальными значениями являются *args (означает, что функция принимает произвольное число позиционных параметров) и **kwargs (означает, что именованные аргументы описаны в документации).


Python является гораздо более мощным языком программирования, чем поместилось в этом руководстве. Чтобы изучить Python более подробно, мы рекомендуем начать с учебника по Python, который доступен на сайте python.org. Хотя мы и не считаем, что глубокое знание языка Python необходимо для работы с движком Ren'Py, основные положения о операторах и выражениях языка Рython часто оказываются полезными.

Источник[править | править код]

Статья "Language Basics" на английском языке.


На главную страницу Официальная документация движка Вернуться к началу статьи