-
-
Notifications
You must be signed in to change notification settings - Fork 108
ru Programming
microScript - это простой язык, вдохновленный Lua. Вот некоторые общие принципы, используемые в microScript:
- По умолчанию переменные являются глобальными. Чтобы определить локальную переменную, используйте ключевое слово "local".
- Переносы строк не имеют особого значения, они рассматриваются как пробелы.
- в microScript нет значений
null
,nil
илиundefined
. Любая неопределенная или нулевая переменная равна0
. - В microScript нет булевого типа.
0
- это false, а все, что не0
- true. - В microScript нет ошибок выполнения или исключения. Любая переменная, которая не определена, возвращает
0
. Вызов значения, которое не является функцией, как функцию, возвращает само значение.
Переменная - это имя (или "идентификатор"), которому можно присвоить значение. Таким образом, она позволяет хранить это значение.
Переменные в microScript не нужно объявлять. Любая переменная, которая еще не использовалась, может считаться существующей и иметь значение 0
.
Чтобы начать использовать переменную, просто присвойте ей значение с помощью знака равенства:
x = 1
Значение x теперь равно 1.
microScript распознает пять типов значений: числа, строки (текст), списки, объекты и функции.
Значения типа "число" в microScript могут быть целыми или десятичными числами.
pi = 3.1415
x = 1
half = 1/2
Строка - это текст или фрагменты текста. Она должна быть заключена в кавычки.
animal = "кот"
print("Привет "+animal)
Списки могут содержать несколько значений:
empty_list = []
prime_numbers = [2, 3, 5, 5, 7, 11, 13, 17, 19]
mixed_list = [1, "кот", [1, 2, 3]]
Вы можете получить доступ к элементам списка по их индексу, т.е. их позиции в списке от 0:
list = ["кот", "собака", "мышь"]
print(list[0])
print(list[1])
print(list[2])
Также легко просматривать список с помощью цикла for
:
for element in list
print(element)
end
Объект в microScript - это форма ассоциативного списка. Объект имеет одно или несколько "полей", которые имеют ключ и значение. Ключ - это строка символов, а значение может быть любым значением microScript. Определение объекта начинается с ключевого слова "object" и заканчивается ключевым словом "end". Между этими двумя словами может быть определено несколько полей. Пример:
my_object = object
x = 0
y = 0
name = "объект 1"
end
Вы можете получить доступ к полям объекта с помощью оператора .
. Следовательно, приведенное выше определение также может быть записано:
my_object.x = 0
my_object.y = 0
my_object.name = "объект 1"
К нему также можно обратиться с помощью скобок []
. Следовательно, приведенное выше определение также может быть записано:
my_object["x"] = 0
my_object["y"] = 0
my_object["name"] = "объект 1"
Вы можете просматривать список полей объекта с помощью цикла for
:
for field in my_object
print(field + " = " + my_object[field])
end
Более подробное описание объекта см. в разделе "Классы".
Значение может быть функцией. При записи draw = function() ... end
создается значение функции и присваивается в переменную draw
(см. раздел о функциях ниже).
По умолчанию переменные, объявленные с помощью присваивания, являются глобальными. Можно определить локальную переменную, как часть функции, используя ключевое слово "local". Пример:
myFunction = function()
local i = 0
end
Функция - это последовательность операций, которая выполняет работу, вычисления и иногда возвращает результат.
Функция задается ключевым словом "function" и заканчивается ключевым словом "end". Пример:
nextNumber = function(s)
x+1
end
print(nextNumber(10))
Когда вы вызываете значение, которое не является функцией, как функцию, оно возвращает свое значение. Пример:
x = 1
x(0)
Приведенный выше код возвращает значение 1, не вызывая ошибки. Таким образом, вы даже можете вызвать функцию, которая еще не определена (тогда она будет иметь значение 0
), без возникновения ошибки. Это позволяет вам начать структурировать вашу программу на самом раннем этапе с подфункций, над которыми вы будете работать позже. Например:
draw = function()
drawSky()
drawClouds()
drawTrees()
drawEnemies()
drawHero()
end
// Я могу реализовать вышеуказанные функции в своем собственном темпе.
Условный оператор позволяет программе проверить гипотезу и выполнить различные операции в зависимости от результата проверки. В microScript условия записываются следующим образом:
if age<18 then
print("ребенок")
else
print("взрослый")
end
"if" означает "если"; "then" означает "тогда"; "else" означает "иначе"; "end" означает "конец".
В приведенном выше примере, если значение переменной age меньше 18, то будет выполнена команда print("ребенок")
, иначе будет выполнена команда print("взрослый")
.
Здесь перечислены бинарные операторы, которые можно использовать для сравнения:
Оператор | Описание |
---|---|
== |
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 | логическое НЕ: not a истинно, если a ложно, и ложно, если a истинно |
В языке microScript нет булевых типов. Значение 0
считается ложным, а любое другое значение - истинным. Операторы сравнения возвращают 1
для true
или 0
для false
. Для удобства, microScript также позволяет вам использовать эти две предопределенные переменные:
Переменная | Значение |
---|---|
true | 1 |
false | 0 |
Можно проверить несколько гипотез, используя ключевое слово "elsif" (сокращение от "else if")
if age<10 then
print("ребенок")
elsif age<18 then
print("подросток")
elsif age<30 then
print("молодой взрослый")
else
print("солидный возраст")
end
Циклы позволяют выполнять многократные обработки.
Цикл for
широко используется в программировании. Он позволяет выполнять одну и ту же обработку всех элементов списка или последовательности значений.
for i=1 to 10
print(i)
end
Приведенный выше пример выведет в консоль каждое число от 1 до 10.
for i=0 to 10 by 2
print(i)
end
Приведенный выше пример выведет в консоль числа от 0 до 10 с шагом 2.
list =[2, 3, 5, 7, 11]
for number in list
print(number)
end
В приведенном выше примере создается список, а затем выводится каждый элемент списка.
Цикл while
позволяет выполнять операции многократно до тех пор, пока не будет получен удовлетворительный результат.
x = 1
while x*x<100
print(x*x)
x += 1
end
В приведенном выше примере выводится квадрат x, затем инкрементируется x (т.е. прибавляется 1 к x) до тех пор, пока квадрат x меньше 100.
Вы можете преждевременно завершить цикл for
или while
с помощью оператора break
. Пример:
while true
x += 1
if x >= 100 then break end
end
Вы можете пропустить оставшиеся операции цикла и перейти к следующей итерации цикла с помощью оператора continue
. Пример:
for i=0 to 10000
if i%10 == 0 then continue end // это пропустит обработку чисел, кратных 10
doSomeProcessing(i)
end
Вот список бинарных операторов в microScript (исключая операторы сравнения, уже упомянутые выше)
Оператор | Описание |
---|---|
+ | Сложение |
- | Вычитание |
* | Умножение |
/ | Деление |
% | Модуль: x % y равно остатку от деления x на y |
^ | Степень: x ^ y равно x в степени y - pow(x, y)
|
Функция | Описание |
---|---|
max(a, b) | Возвращает наибольшее число a или b |
min(a, b) | Возвращает наименьшее число a или b |
round(a) | Возвращает значение a, округленное до ближайшего целого значения |
floor(a) | Возвращает значение a, округленное до нижнего целого числа |
ceil(a) | Возвращает значение a, округленное вверх |
abs(a) | Возвращает абсолютное значение a |
sqrt(a) | Возвращает квадратный корень из a |
pow(a, b) | Возвращает a в степени b (другие возможные обозначения: a ^ b ) |
PI | Константа, равная числу Pi |
log(a) | Возвращает натуральный логарифм от a |
exp(a) | Возвращает число Эйлера, возведенное в степень a |
Функция | Описание |
---|---|
sin(a) | Возвращает синус от a (a в радианах) |
cos(a) | Возвращает косинус от a (a в радианах) |
tan(a) | Возвращает тангенс от a (a в радианах) |
acos(a) | Возвращает арккосинус от a (результат в радианах) |
asin(a) | Возвращает арксинус a (результат в радианах) |
atan(a) | Возвращает арктангенс a (результат в радианах) |
atan2(y, x) | Возвращает арктангенс y/x (результат в радианах) |
Функция | Описание |
---|---|
sind(a) | Возвращает синус от a (a в градусах) |
cosd(a) | Возвращает косинус от a (a в градусах) |
tand(a) | Возвращает тангенс от a (a в градусах) |
acosd(a) | Возвращает арккосинус от a (результат в градусах) |
asind(a) | Возвращает арксинус от a (результат в градусах) |
atand(a) | Возвращает арктангенс a (результат в градусах) |
atan2d(y, x) | Возвращает арктангенс y/x (результат в градусах) |
Объект random
используется для генерации псевдослучайных чисел. Генератор можно инициализировать функцией seed
, чтобы при каждом выполнении получать одну и ту же последовательность чисел или наоборот, каждый раз разную.
Функция | Описание |
---|---|
random.next() |
Выдает новое случайное число в диапазоне от 0 до 1 |
random.nextInt(a) |
Возвращает новое целое случайное число от 0 до a-1 |
random.seed(a) |
Переустановка последовательности случайных чисел с помощью значения a; если вы используете одно и то же инициализирующее значение дважды, вы получите одну и ту же последовательность случайных чисел. Если a == 0, генератор случайных чисел инициализируется случайным образом и поэтому невоспроизводим. |
Операция | Описание |
---|---|
string1 + string2 |
Оператор + может использоваться для объединения строк |
string.length |
Значение, которое хранит длину строки |
string.substring(i1, i2) |
Возвращает подстроку символьной строки, начинающуюся с индекса i1 и заканчивающуюся индексом i2 |
string.startsWith(s) |
Возвращает 1 (true), если строка начинается точно с s
|
string.endsWith(s) |
Возвращает 1 (true), если строка заканчивается точно на s
|
string.indexOf(s) |
Возвращает индекс первого вхождения s в string или -1, если string не содержит такого вхождения |
string.lastIndexOf(s) |
Возвращает индекс последнего вхождения s в string или -1, если string не содержит ни одного такого вхождения |
string.replace(s1, s2) |
Возвращает новую строку, в которой первое вхождение s1 (если оно есть) заменено на s2
|
string.toUpperCase() |
Возвращает строку, преобразованную в верхний регистр |
string.toLowerCase() |
Возвращает строку, преобразованную в нижний регистр |
string.split(s) |
Функция split делит строку на список подстрок путем поиска подстроки-разделителя, заданного в качестве аргумента, и возвращает этот список |
Операция | Описание |
---|---|
list.length |
Хранит длину списка (количество элементов в списке) |
list.push(element) |
Добавляет элемент в конец списка |
list.insert(element) |
Вставляет элемент в начало списка |
list.insertAt(element, index) |
Вставляет элемент в список по заданному индексу |
list.indexOf(element) |
Возвращает позицию элемента в списке (0 для первого элемента, 1 для второго элемента и т.д.). Возвращает -1, если элемент не найден в списке. |
list.contains(element) |
Возвращает 1 (true), если element находится в списке или 0 (false), если элемент не найден в списке |
list.removeAt(index) |
Удаляет из списка элемент по заданному index
|
list.removeElement(element) |
Удаляет из списка element , если он найден в списке |
list1.concat(list2) |
Возвращает новый список, полученный путем добавления list2 к list1
|
Вы можете сортировать элементы списка с помощью функции list.sortList(compareFunction)
. Предоставляемая вами функция compareFunction
должна принимать два аргумента (которые мы будем называть a
и b
) и возвращать:
Возвращаемое значение | Когда возвращается |
---|---|
Отрицательное число | Когда a должно быть отсортировано перед b (a меньше b) |
Ноль | Когда a и b имеют равное положение относительно желаемого критерия упорядочения |
Положительное число | Когда a должны быть отсортированы после b (a больше b) |
В примере ниже предполагается, что список содержит точки, каждая из которых имеет координату x
. Мы хотим отсортировать точки от меньшего значения point.x к большему значению point.x:
compare = function(point1,point2)
return point1.x - point2.x
end
list.sortList(compare)
Обратите внимание, что приведенный выше код можно сделать короче:
list.sortList(function(point1,point2) point1.x - point2.x end)
Если функция сравнения не задана, элементы списка будут отсортированы в алфавитном порядке.
Комментарии в microScript могут быть добавлены после двойного слеша: //
; все, что следует за ними до следующего перевода строки, игнорируется при анализе программы.
myFunction = function()
// мои заметки о роли функции myFunction
end
Класс в языке программирования - это своего рода чертеж или шаблон для создания объектов. Класс определяет свойства и функции по умолчанию, которые представляют собой состояние и поведение по умолчанию всех объектов, которые будут созданы на его основе. Вы можете создавать экземпляры объектов, производные от класса, которые будут наследовать все свойства класса. Использование классов и их производных объектов в программе называется объектно-ориентированным программированием (ООП).
Чтобы наглядно продемонстрировать эти понятия, мы рассмотрим, как можно использовать классы для управления врагами в вашей игре:
Мы начнем с создания класса Enemy
, который будет общим для всех наших врагов. Каждый враг будет иметь позицию (на экране). Он будет иметь очки здоровья hp
и двигаться с определенной скоростью velocity
:
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
В языке microScript классы и объекты являются очень похожими понятиями и могут использоваться практически взаимозаменяемо. Таким образом, определение класса начинается с ключевого слова class
и заканчивается ключевым словом end
. Первое свойство, которое мы определили в приведенном выше классе - это функция "constructor". Эта функция вызывается, когда создается экземпляр класса. Она установит свойство position объекта. this
относится к экземпляру объекта, на котором будет вызвана функция, поэтому установка this.position
означает, что объект устанавливает свойство position на себя.
Давайте создадим два объекта-врага, производных от нашего класса:
enemy_1 = new Enemy(50)
enemy_2 = new Enemy(100)
Оператор new
используется для создания нового экземпляра объекта, производного от класса. Аргумент, который мы передаем здесь, будет направлен на функцию конструктора нашего класса. Таким образом, мы создали экземпляр врага в позиции 50 и другой экземпляр врага в позиции 100.
Оба врага имеют одинаковую скорость или очки здоровья (hp). Однако мы можем задать второму врагу другую скорость:
enemy_2.velocity = 2
Теперь мы можем заставить наших врагов двигаться, вызвав:
enemy_1.move()
enemy_2.move()
Второй враг будет двигаться в два раза быстрее, потому что мы изменили его свойство velocity перед вызовом функции move.
Мы можем заставить класс наследоваться от другого класса. Например, если мы хотим создать разновидность нашего Enemy
, мы можем поступить следующим образом:
Boss = class extends Enemy
constructor = function(position)
super(position)
hp = 50
end
move = function()
super()
hp += 1
end
end
Мы создали новый класс Boss
, расширив класс Enemy
. Наш новый класс разделяет все свойства класса Enemy, за исключением того, что он заменяет некоторые из этих свойств своими собственными значениями. Вызов super(position)
в конструкторе нашего нового класса гарантирует, что конструктор нашего родительского класса Enemy также будет вызван.
Мы создали новое поведение move
для нашего Босса, которое переопределяет поведение Врага по умолчанию. В этой новой функции мы вызываем super()
, чтобы сохранить поведение по умолчанию, которое было определено в классе Enemy; затем мы увеличиваем значение hp
, что подразумевает, что наши Боссы будут восстанавливать очки здоровья при перемещении.
Теперь мы можем создать экземпляр нашего Босса в позиции 120:
the_final_boss = new Boss(120)
-
пространство переменных: когда функция вызывается на объекте (например,
enemy_1.move()
), переменные, на которые ссылаются в теле вызываемых функций, являются свойствами объекта. Например, в теле функции move,position += 1
увеличит свойствоposition
самого объекта. -
Иногда необходимо использовать
this
, чтобы убедиться, что мы правильно ссылаемся на свойство нашего объекта. Вот почему в конструкторе нашего класса Enemy мы используемthis.position = position
, потому чтоposition
также относится к аргументу функции и, таким образом, "скрывает" свойство нашего объекта. -
super()
можно использовать в функции, присоединенной к объекту или классу, чтобы вызвать аналогичную функцию родительского класса.