Основы языка microScript

image-loader.svg

Привет Хабр!

Под предыдущей статьей собралось много вопросов и рассуждений относительно microStudio, в частности языка microScript, которому я не уделил внимания в предыдущей статье. Да я и не ставил цель затронуть все вопросы в одной статье.

Напомню: microStudio это бесплатная интегрированная среда разработки видеоигр.

В этой статье рассмотрим язык microScript.

Итак, для начала, microScript — это локальный язык. В настоящее время он используется только в пределах microStudio. Программа написанная на языке microScript транспилируется в javascript. microScript — это довольно простой в изучении язык, по синтаксису схож с языком Lua.

Вот некоторые общие принципы языка microScript о которых поговорим подробнее в этой статье:

  • По умолчанию переменные являются глобальными. Чтобы определить локальную переменную, нужно использовать ключевое слово «local».

  • Разрывы строк не имеют особого значения, они рассматриваются как пробелы.

  • Нет значения nullnil или undefined. Любая неопределенная или нулевая переменная по умолчанию равна 0.

  • Нет логического типа. 0 — это ложь, а все что не 0 — истина.

  • Нет ошибки выполнения или исключения. Любая переменная, которая не определена, возвращает значение 0.

  • Вызов значения в качестве функции, которое не является функцией, возвращает само значение.

«Hello, world!» на языке microScript:

print("Hello, world!")

Написание однострочных комментариев с помощью //:

print("Hello, world!") //здесь можно написать комментарий

Все, что следует до следующего разрыва строки, игнорируется при работе программы. Многострочные комментарии в microScript не предусмотрены.

Переменные

Любая переменная, которая еще не использовалась, может считаться существующей и иметь значение 0. Чтобы начать использовать переменную, ей нужно присвоить значение со знаком равенства:

x = 1

Все переменные в microScript считаются глобальными, если они явно не объявлены как локальные.

Локальную переменную можно определить используя ключевое слово «local»:

myFunction = function()
	local i = 0
end

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

Имя переменной должно начинаться либо с латинской буквы,  либо с символа нижнего подчеркивания _, после которых могут следовать латинские буквы, цифры или символы подчеркивания:

_x1 = 2
var_a = 3

Прописные и строчные буквы различны, потому что microScript, как и Lua, чувствителен к регистру.

Есть список зарезервированных слов, которые нельзя использовать в качестве идентификатора переменной: and, break, by, class, continue, else, elsif, end, for, function, if, in, local, new, not, object, or, return, then, to, while.

Типы значений

microScript распознает пять типов значений:

Числа

Значения типа «число» в микроскрипте могут быть целыми или десятичными числами. Например:

pi = 3.1415
x = 1
half = 1/2

Строки

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

name = "Вася"
print('Привет' + name) //конкатенация сток с помощью оператора
											 //сложения "+"               

В консоли: Привет Вася

Списки

В список можно поместить сколько угодно необходимых значений любого из пяти типов:

empty_list = [] //пустой список
prime_numbers =[2,3,5,5,7,11,13,17,19] //список чисел
mixed_list =[1,"кот",[1,2,3],draw()] //смешанный список

Можно получить доступ к элементам списка по их индексу, т. е. их положению в списке, начиная с индекса 0:

list = ["кот", "собака", "мышь"]
list[0] //"кот"
list[1] //"собака"
list[2] //"мышь"

Можно просмотреть список с помощью цикла for:

for element in list
	print(element) //на консоль выведутся все элементы списка начиная с первого
end

Объекты

Объект в микроскрипте это форма ассоциативного списка. Объект имеет одно или несколько «полей», которые имеют ключ и значение. Ключ представляет собой строку символов, значением может быть любое значение микроскрипта. Определение объекта начинается с ключевого слова «object» и заканчивается ключевым словом «end». Между ними можно определить несколько полей. Пример:

my_object = object
  x = 10
  y = 20
  name = "object 1"
end

Можно получить доступ к полям объекта с помощью оператора .:

print(my_object.x)

В консоли: 10

Таким образом, приведенный выше пример можно записать и так:

my_object.x = 0
my_object.y = 0
my_object.name = "object 1"

Можно добавить новое поле для объекта my_object:

my_object.vx = 5

Также, к полям объекта можно получить доступ с помощью скобок []:

my_object["x"] = 0
my_object["y"] = 0
my_object["name"] = "object 1"

Функции

Функция определяется ключевым словом «function» и заканчивается ключевым словом «end»:

nextNumber = function(x)
	x+1
end

Вызов функции:

nextNumber(10)
print(nextNumber(10))

В консоли: 11
Когда вызывается значение в качестве функции, которое при этом не является функцией, оно просто возвращает свое значение. Пример:

x = 1
print(x())

В консоли: 1
Приведенный выше код возвращает значение »1» без возникновения ошибки. Таким образом, можно даже вызвать функцию, которая еще не определена (тогда она возвращает 0), не вызывая ошибки. Это позволяет очень рано начать структурировать свою программу с помощью подфункций, над которыми вы будете работать позже. Например:

draw = function()
  drawSky()
  drawClouds()
  drawTrees()
  drawEnemies()
  drawHero()
end

Классы

В микроскрипте классы и объекты являются очень похожими понятиями и могут почти взаимозаменяемо использоваться.

Создание класса начинается с ключевого слова «class» и заканчивается ключевым словом «end». Пример:

Enemy = class
  constructor = function(position)
  	this.position = position
  end
  hp = 10
  velocity = 1
  move = function()
  	position += velocity
  end
  hit = function(damage)
  	hp -= damage
  end
end 

Первое свойство, которое мы определили в приведенном выше классе — это функция «конструктор». Эта функция вызывается при создании экземпляра объекта класса. Она установит свойство положения (position) объекта. this относится к экземпляру объекта, на котором будет вызвана функция, таким образом, установка this.position означает, что объект устанавливает свойство position для себя.

Создание экземпляров объектов из класса:

enemy_1 = new Enemy

Оператор new используется для создания нового экземпляра объекта, производного от класса.

Создадим еще один объект:

enemy_2 = new Enemy

Оба объекта enemy_1 и enemy_2 имеют одинаковые поля velosity равные 1:

enemy_1.velosity //равно 1
enemy_2.velosity //равно 1

Можно поменять значение velosity для enemy_1 например:

enemy_1.velosity = 2

Переменные hp и velocity также доступны нам сразу из класса:

Enemy.hp
Enemy.velosity

Условный оператор

В микроскрипте условия записываются следующим образом:

if age<18 then
	print("ребенок")
else
	print("взрослый")
end

«if» означает «если»; «then» означает «тогда»; «else» означает «иначе»; «end» означает «конец».
В приведенном выше примере, если значение переменной возраста меньше 18, то инструкция print("ребенок") будет выполнена, иначе будет выполнена инструкция print("взрослый").

Можно проверить несколько гипотез, используя ключевое слово «elsif» (сокращение от «еще, если»).

if age<10 then
	print("ребенок")
elsif age<18 then
	print("подросток")
elsif age<30 then
	print("молодой человек")
else
	print("очень взрослый")
end 

Цикл for

Цикл for широко известен в программировании, так же как и условный оператор if, тем не менее я опишу кратко его применение в микроскрипте.

Этот цикл позволяет проводить одинаковую обработку всех элементов списка или ряда значений:

for i=1 to 10
	print(i)
end

В приведенном выше примере мы выведем на консоль каждое число от 1 до 10.

Мы можем сделать тоже самое, только с шагом равным 2:

for i=0 to 10 by 2
	print(i)
end

В приведенном примере мы выведем на консоль числа от 0 до 10 с шагом 2(by 2).

Цикл while

Этот цикл позволяет выполнять операции повторно, пока не будет получен удовлетворительный результат:

x = 1
while x*x<100
   print(x*x)
   x = x+1
end

В приведенном выше примере выводится квадрат x, затем увеличивается значение x (прибавляется единица к x), если квадрат x меньше 100.

Прервать или продолжить цикл

Мы можем прервать цикл досрочно используя оператор break:

while true
   x = x+1
   if x>= 100 then break end //если x больше либо равен 100, цикл будет прерван
end

Можно пропустить оставшиеся операции цикла и перейти к следующей итерации цикла с помощью оператора continue. Пример:

for i=0 to 10000
	if i%10 == 0 then continue end //это позволит пропустить обработку чисел,
                                 //кратных 10
	doSomeProcessing(i)
end

Арифметические Операторы

Оператор

Описание

+

Сложение

-

Вычитание

*

Умножение

/

Деление

%

Деление по модулю (остаток от деления)

^

Возведение в степень

Бинарные операторы сравнения

Оператор

Описание

==

a == b верно только в том случае, если a равно b

!=

a != b верно только в том случае, если a отличается от b

<

a < b верно только в том случае, если a строго меньше b

>

a > b верно только в том случае, если a строго больше b

<=

a <= b верно только в том случае, если a меньше или равно b

>=

a >= b верно только в том случае, если a больше или равно b

Булевы операторы

Оператор

Описание

and

логическое И: a and b истинно только в том случае, если a и b истинны

or

логическое ИЛИ: a or b истинно только в том случае, если a истинно или b истинно

not

логическое НЕТ: a не истинно, если a ложно, и ложно, если a истинно

Логические значения

В microScript нет логического типа. 0 считается ложным, а любое другое значение является истинным. Операторы сравнения возвращают значение 1 (true) или 0 (false). Для удобства microScript также позволяет использовать следующие предопределенные переменные:

Переменная

Значение

true

1

false

0

Три основные функции в языке microScript

Открыв окно проекта microStudio (в разделе «код») вы увидите три основные предопределенные функции:

init()
update()
draw()

Окно проекта microStudioОкно проекта microStudio

Функция init ()

Функция инициализации вызывается только один раз при запуске программы. Это полезно, в частности, для определения начального состояния глобальных переменных, которые могут использоваться в остальной части программы.

Функция update ()

Функция обновления вызывается 60 раз в секунду. Тело этой функции — лучшее место для программирования логики и физики игры: изменения состояния, движения спрайтов, обнаружение столкновений, оценка входов с клавиатуры, оценка сенсорных или геймпадных входов и т.д.

Функция draw ()

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

Послесловие

Итак, считаю что я рассмотрел в этой статье основы данного языка. А если я упустил из виду какие-то базовые вещи, дайте мне знать об этом.

Уроки по изучению программирования на этом языке я буду публиковать у себя в группе ВК, как только наберется хотя бы небольшая заинтересованная в этом аудитория. Если вы новичок в программировании, и хотите изучить этот язык, подписывайтесь, добавляйтесь в друзья, всем буду очень рад!

И как всегда, спасибо за внимание!

© Habrahabr.ru