-
-
Notifications
You must be signed in to change notification settings - Fork 109
pt Programming
microScript é uma linguagem simples inspirada em Lua. Aqui estão alguns princípios gerais usados em microScript:
- as variáveis são globais por padrão. Para definir uma variável local, use a palavra reservada "local".
- quebras de linha não tem um significado particular, são consideradas espaços.
- em microScript não há valores
null
,nil
ouundefined
. Qualquer variável de valor indefinido ou nulo é igual a0
. - em microScript, não há um tipo Booleano.
0
é false e tudo que não é0
é true. - não há erro de execução ou exceção em microScript. Qualquer variável não definida retorna
0
. Invocar um valor que não é uma função como uma função retorna o próprio valor.
Uma variável é um nome (ou "identificador") ao qual se decide atribuir um valor. Tornando possível, o armazenamento desse valor.
Variáveis em microScript não precisam ser declaradas. Qualquer variável que ainda não tenha sido utilizada pode ser considerada existente e tem o valor 0
.
Para começar a usar uma variável, basta atribuir-lhe um valor com o sinal de igual:
x = 1
O valor de x agora é 1.
microScript reconhece cinco tipos de valores: números, strings (texto), listas, objetos e funções.
Os valores do tipo Número em microScript podem ser inúmeros inteiros ou decimais.
pi = 3.1415
x = 1
half = 1/2
Strings são textos ou partes de textos. Devem ser definidos entre aspas.
animal = "gato"
print("Olá " + animal)
Listas podem conter uma série de valores.
empty_list = []
prime_numbers =[2,3,5,5,7,11,13,17,19]
mixed_list =[1,"gato",[1,2,3]]
Você pode acessar os elementos da listas pelo seu índice, por exemplo, sua posição na lista a partir de 0:
list = ["gato", "cachorro", "rato"]
print(list[0])
print(list[1])
print(list[2])
Também é facil navegar por uma lista usando o laço for
:
for element in list
print(element)
end
Um objeto em microScript é uma forma de lista associativa. O objeto tem um ou mais "campos" que têm uma chave e um valor. A chave é uma string de caracteres, o valor pode ser qualquer valor microScript. A definição de um objeto inicia com a palavra reservada object e termina com a palavra reservada end. Entre os dois podem ser definidos vários campos. Exemplo:
my_object = object
x = 0
y = 0
name = "objeto 1"
end
Você pode acessar os campos de um objeto com o operator .
. A definição acima também pode ser escrita da seguinte forma:
my_object.x = 0
my_object.y = 0
my_object.name = "objeto 1"
Também pode ser acessado com colchetes []
. A definição acima também pode, portanto, ser escrita como se segue:
my_object["x"] = 0
my_object["y"] = 0
my_object["nome"] = "objeto 1"
Você pode navegar pela lista de campos de um objeto com um laço for
:
for field in my_object
print(field +" = " + " + my_object[field])
end
Veja "Classes" para uma cobertura mais aprofundada do objeto.
Um valor pode ser do tipo função. Ao escrever draw = function() ... end
, um valor de função é criado e atribuído à variável draw
(ver seção sobre funções abaixo).
Por padrão, as variáveis declaradas pela atribuição são globais. É possível definir uma variável local, como parte de uma função, usando a palavra reservada local:
myFunction = function()
local i = 0
end
Uma função é uma subsequência de operações, que realizam uma tarefa, um cálculo e às vezes retorna um resultado.
A function is defined with the keyword "function" and ends with the keyword "end". Uma função é definida pela palavra reservada function e termina com a palavra reservada end.
nextNumber = function(s)
x+1
end
print(nextNumber(10))
Quando você invoca uma valor que não é uma função como se fosse uma função, ele simplesmente retornar seu valor. Por exemplo:
x = 1
x(0)
O código acima retorna o valor 1, sem gerar um erro. Assim, você pode até invocar uma função que ainda não esteja declarada (seu valor serpa 0
), sem gerar nenhum erro. Isso permite a você estruturar seu programa bem cedo com sub-funções, as quais você trabalhará mais tarde. Por exemplo:
draw = function()
drawSky()
drawClouds()
drawTrees()
drawEnemies()
drawHero()
end
// Pode implementar as funções acima quando necessário.
Uma declaração condicional permite que o programa teste uma hipótese e realize operações diferentes dependendo do resultado do teste. Em microScript, as condições são escritas da seguinte forma:
if age < 18 then
print("criança")
else
print("adulto")
end
"if" significa "se"; "then" significa "então"; "else" significa "caso contrário"; "end" means "fim"
No exemplo acima, se o valor da variável age for menor que 18, então a instrução print("criança")
será executada, caso contrário a instrução print("adulto")
será executada.
Eis os operadores binários que podem ser usados para fazer comparações:
Operador | Descrição |
---|---|
== |
a == b true apenas se a for igual a b
|
!= |
a != b true apenas se a for diferente de b
|
< |
a < b true apenas se a for menor que b
|
> |
a > b true apenas se a for maior que b
|
<= |
a <= b true apenas se a for menor ou igual a b
|
>= |
a >= b true apenas se a for maior ou igual a b
|
Operador | Descrição |
---|---|
and | E lógico: a and b será true apenas se a e b são true
|
or | OU lógico: a or b será true apenas se a for true ou b for true
|
not | NÃO lógico: not a será true se a for false e será false se a for true
|
Em microScript, não há um tipo booleano. 0
é considerado false e qualquer outro valor, true. Operadores de comparação retornam 1
para true ou 0
para false. Por conveniência, microScript também permite usar estas duas variáveis predefinidas:
Variável | Valor |
---|---|
true | 1 |
false | 0 |
It is possible to test multiple hypotheses using the keyword "elsif" (contraction of "else if")
É possível testar múltiploas hipóteses usando a palavra reservada elsif
(contração de "else if")
if age<10 then
print("criança")
elsif age<18 then
print("adolescente")
elsif age<30 then
print("adulto jovem")
else
print("idade muito respeitável")
end
Os laços permitem a realização de tarefas repetitivas.
O laço for
é amplamente utilizado na programação. Ele permite que o mesmo tratamento seja realizado em todos os elementos de uma lista ou série de valores.
for i=1 to 10
print(i)
end
O exemplo acima mostra cada número de 1 a 10 no console.
for i=0 to 10 by 2
print(i)
end
O exemplo acima mostrada os números de 0 a 10, de dois em dois, no console.
list = [2,3,5,5,7,11]
for number in list
print(number)
end
O exemplo acima define uma lista e mostra cada item da mesma.
O laço while
permite que operações sejam realizadas repetidamente até que um resultado satisfatório seja obtido.
x = 1
while x*x<100
print(x*x)
x = x+1
end
O exemplo acima imprime o quadrado de x
, depois incrementa x
(ou seja, adiciona 1 a x
), desde que o quadrado de x
seja inferior a 100.
Você pode sair de um laço for
ou while
prematuramente quando utilizar break
. Exemplo:
while true
x = x+1
if x >= 100 then break end
end
Você pode pular as operações restantes de um laço e continuar para a próxima iteração do laço usando continue
. Exemplo:
for i=0 to 10000
if i%10 == 0 then continue end // isso irá pular o processamento dos múltiplos de 19
doSomeProcessing(i)
end
Aqui está a lista de operadores binários em microScript (excluindo comparações, já mencionadas acima)
Operador | Descrição |
---|---|
+ | Adição |
- | Subtração |
* | Multiplicação |
/ | Divisão |
% | Módulo: x % y é igual ao resto da divisão de x por y
|
^ | Potência: x ^ y é igual a x elevado a y , tal como pow(x,y)
|
Função | Descrição |
---|---|
max(a,b) | Retorna o maior número entre as opções a ou b
|
min(a,b) | Retorna o menor número entre as opções a ou b
|
round(a) | Retorna o valor um arredondado para o valor inteiro mais próximo |
floor(a) | Retorna o valor um arredondado para baixo |
ceil(a) | Retorna o valor um arredondado para cima |
abs(a) | Retorna o valor absoluto de a
|
sqrt(a) | Retorna a raiz quadrada de a
|
pow(a,b) | Retorna a elevado a b (outra notação possível: a ^ b ) |
PI | Constante que é igual ao valor de Pi |
log(a) | Retorna o logarítmo natural de a |
exp(a) | Retorna o número de Euler elevado a a
|
Função | Descrição |
---|---|
sin(a) | Retorna o seno de a (a em radianos) |
cos(a) | Retorna o cosseno de a (a em radianos) |
tan(a) | Retorna tangente de a (a em radianos) |
acos(a) | Retorna o arco cosseno de a (resultado em radianos) |
asin(a) | Retorna o arco seno de a (resultado em radianos) |
atan(a) | Retorna o arco tangente de a (resultado em radianos) |
atan2(y,x) | Retorna o arco tangente de y/x (resultado em radianos) |
Função | Descrição |
---|---|
sind(a) | Retorna o seno de a (a em graus) |
cosd(a) | Retorna o cosseno de a (a em graus) |
tand(a) | Retorna tangente de a (a em graus) |
acosd(a) | Retorna o arco cosseno de a (resultado em graus) |
asind(a) | Retorna o arco seno de a (resultado em graus) |
atand(a) | Retorna o arco tangente de a (resultado em graus) |
atan2d(y,x) | Retorna o arco tangente de y/x (resultado em graus) |
O objeto random
é usado para gerar números pseudo-aleatórios. É possível inicializar o gerador com a função seed
para obter a mesma sequência de números em cada execução, ou ao contrário, uma sequência diferente a cada vez.
Função | Description |
---|---|
random.next() |
Retorna um novo número aleatório entre 0 e 1 |
random.nextInt(a) |
Retorna um novo número inteiro aleatório entre 0 e a
|
random.seed(a) |
Redefine a sequência de números aleatórios usando o valor a ; Se você usar o mesmo valor de inicialização duas vezes, obterá a mesma sequência de números aleatórios. Se a == 0, o gerador de número aleatório é inicializado ... aleatoriamente e, portanto, não reproduzível |
Operação | Descrição |
---|---|
string1 + string2 |
O operador + pode ser usado para concatenar strings. |
string.length |
Campo que retém o comprimento da string. |
string.substring(i1,i2) |
Retorna a substring da string, iniciando no índice i1 e terminando no índice i2
|
string.startsWith(s) |
Retorna se a string inicia exatamente por s
|
string.endsWith(s) |
Retorna se a string termina exatamente por s
|
string.indexOf(s) |
Retorna o índice da primeira ocorrência de s na string, ou -1 se a string não contiver nenhuma ocorrência |
string.lastIndexOf(s) |
Retorna o índice da última ocorrência de s na string, ou -1 se a string não contiver nenhuma ocorrência |
string.replace(s1,s2) |
Retorna uma nova string em que a primeira ocorrência de s1 (se houver) é substituída por s2
|
string.toUpperCase() |
Retorna a string convertida para maiúsculas |
string.toLowerCase() |
Retorna a string convertida para minúsculas |
string.split(s) |
A função split divide a string em uma lista de substrings, procurando pela substring separadora fornecida como argumento e retorna uma lista |
Operação | Descrição |
---|---|
lista.length |
Retém a comprimento da lista (número de elementos na lista) |
lista.push(elemento) |
Adiciona um elemento ao fim da lista |
lista.insert(elemento) |
Insere um elemento no início da lista |
lista.insertAt(elemento, índice) |
Insere um elemento na lista no índice informado |
lista.indexOf(elemento) |
Retorna a posição do elemento na lista (0 para o primeiro elemento, 1 para o segundo elemento...). Retorna -1 quando o elemento não é encontrado na lista |
lista.contains(elemento) |
Retorna 1 (true) quando o elemento está na lista, ou 0 (false) quando o elemento não pode ser encontrado na lista |
lista.removeAt(índice) |
Remove da lista o elemento da posição índice
|
lista.removeElement(elemento) |
Remove da lista elemento , se o mesmo puder ser encontrado na lista |
lista1.concat(lista2) |
Retorna uma nova lista concatenando lista2 a lista1
|
Você pode ordenar os elementos de uma lista usando a função lista.sortList (compareFunction)
. A compareFunction
que você fornece tem que aceitar dois argumentos (que chamaremos de a
e b
) e deve retornar:
Valor de retorno | Quando |
---|---|
um número negativo | quando a for ordenado antes de b (a é menor que b ) |
zeroquando a e b tem posição igual em relação ao critério de comparação |
|
um número positivo | quando a for ordenado após b (a é maior que b ) |
O exemplo abaixo assume que a lista contém pontos, cada ponto tendo um campo de coordenada x
. Queremos classificar os pontos do menor valor de point.x para o maior valor de point.x:
compare = function(ponto1,ponto2)
return ponto1.x - ponto2.x
end
list.sortList(compare)
Perceba que você pode tornar o código acima mais curto:
list.sortList(function(ponto1, ponto2) ponto1.x - ponto2.x end)
Sempre que uma função de comparação não for fornecida, os elementos da lista serão classificados de acordo com a ordem alfabética.
Comentários em microScript podem ser adicionados após uma barra dupla: //
; tudo o que segue até a próxima quebra de linha é ignorado ao analisar o programa.
myFunction = ()
// Minhas notas sobre o funcionamento da função myFunction
end
Uma classe em uma linguagem de programação se refere a um tipo de projeto ou modelo para a criação de objetos. Uma classe define propriedades e funções padrão que constituem o estado e comportamento padrão de todos os objetos que serão criados a partir dela. Você pode criar instâncias de objeto derivadas de uma classe, que herdarão todas as propriedades da classe. O uso de classes e seus objetos derivados em um programa é chamado de programação orientada a objetos (POO) ou em inglês object-oriented programming (OOP).
Para ilustrar esses conceitos, veremos como você pode usar classes para gerenciar os inimigos em seu jogo:
Começaremos criando uma classe Enemy
que será compartilhada por todos os nossos objetos inimigos. Cada inimigo terá uma posição (na tela). Ele terá pontos de vida hp
, e se moverá a uma certa 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
No microScript, classes e objetos são conceitos muito semelhantes e quase podem ser usados de forma intercambiável. A definição da classe, portanto, termina com a palavra-chave end
. A primeira propriedade que definimos na classe acima é a função construtor. Esta função é chamada quando uma instância de objeto da classe é criada. Isso definirá a propriedade position do objeto. this
se refere à instância do objeto na qual a função será chamada, portanto, definir this.position
significa que o objeto define a posição da propriedade em si mesmo.
Vamos criar dois inimigos derivados da nossa classe:
enemy_1 = new Enemy(50)
enemy_2 = new Enemy(100)
O operador new
é usado para criar uma nova instância de objeto derivada de uma classe. O argumento que passamos aqui é voltado para a função construtora de nossa classe. Assim, criamos uma instância inimiga na posição 50 e outra instância inimiga na posição 100.
Ambos os inimigos compartilham a mesma velocidade ou pontos de vida (HP). No entanto, podemos escolher definir uma velocidade diferente para o segundo inimigo:
enemy_2.velocity = 2
Agora podemos fazer nossos inimigos se moverem chamando:
enemy_1.move()
enemy_2.move()
O segundo inimigo se moverá duas vezes mais rápido porque alteramos sua propriedade velocity
antes de chamar a função de movimento.
Podemos fazer uma classe herdar de outra classe. Por exemplo, se quisermos criar uma variação de nosso Enemy
, podemos fazer o seguinte:
Boss = class extends Enemy
constructor = function(position)
super(position)
hp = 50
end
move = function()
super()
hp += 1
end
end
Criamos uma nova classe Boss
ampliando a classe Enemy
. Nossa nova classe compartilha todas as propriedades do Inimigo, exceto que ela substitui algumas dessas propriedades por seus próprios valores. Chamar super (position)
no construtor de nossa nova classe garante que o construtor de nossa classe pai Enemy
também seja chamado.
Criamos um novo comportamento move
para nosso chefe, que substitui o comportamento padrão do Inimigo. Nesta nova função, chamamos super ()
para manter o comportamento padrão que foi definido na classe Enemy
; então incrementamos o valor de hp
, o que implica que nossos chefes irão recuperar pontos de saúde ao se moverem.
Podemos agora criar uma instância do nosso Boss
na posição 120:
the_final_boss = new Boss(120)
-
espaço de variáveis: quando uma função é chamada em um objeto (como
enemy_1.move()
), as variáveis referidas no corpo das funções chamadas são as propriedades do objeto. Por exemplo, no corpo da funçãomove
,position += 1
irá incrementar a propriedadeposition
do próprio objeto. -
Às vezes é necessário usar
this
para garantir que estamos nos referindo corretamente a uma propriedade do nosso objeto. É por isso que, no construtor de nossa classeEnemy
, usamosthis.position = position
, poisposition
também se refere ao argumento da função e, portanto, "mascara" a propriedade do nosso objeto. -
super()
pode ser usado em uma função anexada a um objeto ou classe, para invocar a função igualmente nomeada da classe pai.