Scripting Basics PT

From SA-MP Wiki

Jump to: navigation, search


Contents

Iniciando

O seguinte exemplo é o código mais básico que você pode escrever:

#include <a_samp>
 
main()
{
	print("Hello World!");
	return 1;
}

Vários aspectos serão abordados por vez, vamos começar pela primeira linha:

Include

#include <a_samp>

Isso basicamente lê o arquivo include da pasta pawno/includes/a_samp.inc incluindo-o para dentro do seu código, então tudo que tem dentro do arquivo, você pode usar. Outros includes que você pode usar são:

#include <core>
#include <float>
#include <string>
#include <file>
#include <time>
#include <datagram>
#include <a_players>
#include <a_vehicles>
#include <a_objects>
#include <a_sampdb>

Isso incluirá todos os outros arquivos da pasta, então por adicionar essa única linha, você tem acesso à todas as funções do SA:MP (Você lerá mais sobre funções depois).

Chamadas

A próxima parte mostra os dois lados da chamada de um arquivo. main() é o ponto de entrada de todo script, a primeira parte do código a ser chamada. print é uma função que irá escrever na janela do servidor. Tudo que isso vai fazer é carregar, escrever uma seqüência de caracteres (ou seja, imprimir "Olá mundo!"(sem as aspas) (uma tradição em todas as linguagens de programação)) para o console do servidor. O retorno:
return 1;

Retorna o valor (1) de volta ao lugar onde foi feita a chamada para dizer o que aconteceu (o valor exato que passou aqui não importa, mas em outros lugares faz toda a diferença). Você tem agora o seu script (muito básico). Se você selecionar Arquivo >> novo no PAWNO ele lhe dará um ponto inicial muito maior que todos os códigos vistos até agora (ver abaixo), incluindo as callbacks nativas (parte do código chamada em um determinado momento/acontecimento).

Declarações

As linhas do código a seguir, sempre tem um ';' (ponto e vírgula) no final, isso simplesmente denota o fim de uma declaação(uma declaração é um grupo de uma ou mais funções e operadores que juntos fazem algo, semelhante a uma frase em linguagem comum). Muitas pessoas colocam declarações separados pra cada função isso não é necessário, a seguinte declaração é válida:

main() 
{ 
     print("Hello World!");
     return 1; 
}

As brackets/chaves({}), juntam um grupo de funções que devem ser executadas em conjunto(como um parágrafo em linguagem commum).

main() 
print("Hello World!"); 
return 1;

Com a função acima você agora irá receber um erro porquê a declaração "return 1;" não está em grupo da função main. Os braços contém uma série de instruções em uma única instrução (denominado declaração composta) e funções têm uma simples declaração com elas. Sem os braços, return e print são declarações completamente distintas então como a print é uma função e return não, o código não pode se realizar.

Funções

Uma função é basicamente um pedaço de código que faz algo e pode ser dito para fazer esta coisa de outro lugar. Ele também pode passar dados sobre o que fez e voltar ao lugar que lhe disse para continuar(o lugar que a função foi "chamada").

Chamando

print("Olá Mundo!");

Como descrito em Iniciando, isso chama uma função chamada "print" (definida em a_samp.inc, por isso você precisa inclui-lo) e diz pra mostrar no console do servidor as palavras "Olá Mundo".

Uma função consiste no nome dela(e.g. print), que diz ao sistema qual pedaço de código que você deseja chamar, e uma lista de parâmetros, entre ()s após o nome da função, que passam de dados adicionais para a função de ajudá-la a ser executada. Se você não tem os parâmetros, você precisará de milhões de funções:
printa();
printaa();
printab();
printac();
etc...

As funções podem ter parâmetros como muitos como você gosta, de 0 (pode haver um limite máximo, mas é, pelo menos, 128):

printf("Olá Mundo!", 1, 2, 3, 4, 5, 6);

Não se preocupe com o que essa função faz, por agora, só que ela tem 7 parâmetros, separados por uma vírgula.

Definindo

Bem como ser chamar funções existentes você pode também criar e chamar as suas:

#include <a_samp>
 
main()
{
	return MinhaFuncao();
}
 
MinhaFuncao()
{
	print("Olá Mundo!");
	return 1;
}

Isso faz exatamente o mesmo que o código original, mas é arranjado de forma diferente. Quando main () é chamado, ou seja, quando o modo é iniciado (ele é chamado automaticamente) ele chama a nova função personalizada chamada MinhaFuncao(). Esta função imprime a mensagem no console do servidor, em seguida, retorna o número 1 do main (). main () recebe o valor retornado (1) e depois retorna para o próprio servidor (ou seja, o lugar que chamou principal em primeiro lugar). Como "return MinhaFuncao();" é uma declaração única que você poderia fazer:

#include <a_samp>
 
main() return MinhaFuncao();
 
MinhaFuncao()
{
	print("Olá Mundo!");
	return 1;
}

Mas a maioria das pessoas não fazem isso para maior clareza no código. Você também pode executar a função assim:

#include <a_samp>
 
main()
{
	MinhaFuncao();
	return 1;
}
 
MinhaFuncao()
{
	print("Olá Mundo!");
	return 1;
}

Parâmetros

Parâmetros são um tipo de variáveis que você não precisa declarar já que eles vêm de um lugar que chamou a função:

#include <a_samp>
 
main()
{
	return MinhaFuncao("Olá Mundo!");
}
 
MinhaFuncao(string[])
{
	print(string);
	return 1;
}

O código acima faz a mesma coisa que antes MinhaFuncao(), irá mostrar a(a) palavra(s) entre aspas no console. A chamada passa a string "Olá Mundo!" para a função MinhaFuncao, que tem uma variável chamada string. Os [] colchetes denotam string como arrayarrays será explicado depois). A função print é chamada recebendo o conteúdo da variável string, nós sabemos que é uma variável porquê não tem as aspas antes e depois do texto.

Variáveis

Uma variável é basicamente um pouco de memória. É onde os dados são armazenados e podem ser alterados, e lidos. Variáveis são uma ou mais células. Uma célula tem 32 bits (4 bytes) grandes e por padrão são assinadas com os valores: -2147483648 até 2147483647 (embora -2147483648 é pobremente definido em PAWN e dá resultados estranhos quando exibido. Uma variável feita pra armazenar mais que uma célula é chamada de array, strings sãoum tipo especialde arrays, onde cada célula armazena 1 caractere da string (ou 4 caracteres em packed strings mas elas nãoserão discutidas aqui.)

Declaração

Para criar uma variável você precisa declara-la:

new
	minhaVariavel;

Isso diz ao sistema que deverá ser criada uma variável chamada minhaVariavel, o valor inicial dessa variável será 0.

Ajustando

new
	minhaVariavel = 7;

Isso declara a variável e ajusta seu valor para 7, então imprimindo a variável o valor será 7. Para mostrar o valor de uma variável que não contenha uma string nós precisamos voltar ao printf() função mencionada antes, e fácil de usar.

new
	minhaVariavel = 7;
printf("%d", minhaVariavel);

De novo, por agora tudo que o código irá fazer é imprimir o valor da variável (i.e. 7 ao ponto) para o servidor.

new
	minhaVariavel = 7;
printf("%d", minhaVariavel);
minhaVariavel = 8;
printf("%d", minhaVariavel);

Esse código imrpimirá 7 depois ajustará o valor da variável para 8 e imprimieá 8, logicamente. Abaixo muitas outras coisas que você pode fazer com variáveis, e que são mais listados em outros lugares:

minhaVariavel = minhaVariavel + 4;

Ajusta o valor de minhaVariavel para o valor antigo e adciona mais 4 à ela. Isso também pode ser escrito assim:

minhaVariavel += 4;

Irá fazer a mesma coisa.

minhaVariavel -= 4;

Isso irá diminuir o valor dela por 4

minhaVariavel *= 4;

Isso irá atribuir à variavel o valor dela multiplicado por 4

minhaVariavel /= 4;

Isso irá atribuir à variavel o valor dela dividido por 4

Matrizes

Declaração

Uma matriz é uma variável em que você pode armazenar múltiplas peças do dado e acessálo- dinamicamente. Uma matriz é declarada com um tamanho definido em tempo de compilação que você precisa saber quantas peças de dados que você precisa para armazenar de antecedência, um bom exemplo disso é a matriz MAX_PLAYERS muito comum, isso terá um slot para cada jogador, possivelmente ligado , Assim você sabe os dados para um jogador não irá interferir com os dados para um outro jogador (mais sobre constantes mais tarde).
new
	Matriz[5];
Esse código irá declarar uma matriz com 5 slots grandes, então você pode armazenar 5 peças de data normal ao mesmo tempo. Uma coisa que você não pode fazer é o seguinte:
new
	minhaVariavel = 5,
	Matriz[minhaVariavel];

Esse código parece que ele irá criar uma matriz do tamanho de qualquer número que está armazenado em minhaVariavel (aqui 5, mas poderia ser qualquer coisa), mas você não pode fazer isso. Em Pawn a memória para as variáveis é atribuído quando você compilar o código, isso significa que as matrizes são sempre um tamanho, não é possível definir o tamanho para o que quiser quando quiser.

Accessando

Para ajustar um valor em uma matriz você precisa que parte da array você quer que seja armazenado o quê. Isso PODE ser feito com outra variável
new
	Matriz[5];
minhaVariavel[2] = 7;

Isso irá declarar uma matriz com 5 espaços e dar ao terceiro espaço o valor 7, as outras variáveis terão o valor 0 Esses serão os valores da array:

0, 0, 7, 0, 0

Por quê isto não é?

0, 7, 0, 0, 0 ?

Você está preocupado? Isso acontece porquê a contagem começa do 0, e não 1, como estamos habituados. Considere os seguintes dados:

2, 4, 6, 8

Se você percorrer a lista, em seguida, após o número 2, você já teve um número (o 2), isto significa que se você está contando os números com o tempo você chegar ao número 4 já está em um, você não está em um quando chegar a 2, o que você está em zero. Assim, o 2 está na posição zero e os 4 está na posição um, e assim segue-se que o 6 está na posição dois, que é onde a 7 no primeiro exemplo acima é. Segue abaixo a ordem do primeiro exemplo:

0 1 2 3 4
0 0 7 0 0

Há cinco slots, mas como você pode ver, e isso é muito importante, não há espaço CINCO, fazendo o seguinte pode falhar o servidor:

new
	Matriz[5];
Matriz[5] = 7;
Como mencionado sobre o índice da matriz(o indice é o espaço que você irá escrever) pode ser qualquer coisa, um número, uma variável que retorna um valor.
new
	Matriz[5],
	MeuIndice = 2;
Matriz[MeuIndice] = 7;

Tendo uma matriz e um índice você pode usar esse bloco, exatamente como se fosse qualquer outra variável:

Matriz[2] = Matriz[2] + 1;
Matriz[2] += 1;
Matriz[2]++;

Exemplo

Como mencionado acima sobre um tipo comum de matriz é a matriz MAX_PLAYERS. MAX_PLAYERS não é uma variável, é uma definição em constante que será explicada mais tarde, para aceitar um número constante que é igual ao número máximo de jogadores que um servidor pode conter (isso por padrão é 500, mesmo se você mudar o número do seu arquivo server.cfg). O código a seguir utiliza variáveis normais para armazenar dados para 4 jogadores e fazer algo com os jogadores em uma função (por causa da simplicidade, assumir MAX_PLAYERS é de 4 por enquanto):

new
	jogador0,
	jogador1,
	jogador2,
	jogador3;
 
AjustarValorDoJogador(jogador, valor)
{
	switch(jogador)
	{
	    case 0: jogador0 = valor; // isso é a mesma coisa que usar if(jogador == 0)
	    case 1: jogador1 = valor; // isso é a mesma coisa que usar if(jogador == 1)
	    case 2: jogador2 = valor; // isso é a mesma coisa que usar if(jogador == 2)
	    case 3: jogador3 = valor; // isso é a mesma coisa que usar if(jogador == 3)
	}
}

Consulte a seção sobre estruturas de controle para obter mais informações sobre o que está acontecendo por lá, nota-se que isso poderia ser feito como um interruptor, mas isso é menos clara para o exemplo e efetivamente seria o mesmo código de qualquer maneira.

Agora compare isso ao uso de uma matriz com um espaço para cada jogador, tendo em conta que um índice de array pode ser qualquer valor:

new
	jogadores[MAX_PLAYERS];
 
AjustarValorDoJogador(jogador, valor)
{
	jogadores[jogador] = valor;
}

O código acima cria uma variável global (veja esta seção no escopo) com um espaço pra cada jogador, então a função irá atribuir o que está no "valor" variável para o espaço do jogador. O primeiro exemplo foi grande, com apenas quatro jogadores, com 4 linhas por jogador, que é de 2000 linhas por 500 jogadores (se pode ser menor, mas ainda é muito), a segunda versão é uma única linha, não importa quantos jogadores você tem.

Strings

Uso básico

Uma string é um tipo especial de matriz, que é utilizado para armazenar vários caracteres para criar uma palavra ou frase ou texto de outro ser humano legível. Um caractere é um byte grande (embora haja estendido define onde um caractere é bytes múltiplos, mas estes não estão bem definidas no SA: MP) e por padrão um caractere pega uma célula (uma variável normal ou um espaço de matriz). Os caracteres são codificados em um sistema chamado ASCII, o caractere "A "é representado pelo número 65, dizendo que o sistema exibe uma série, dará 65, dizendo que o sistema exibe um caractere vai dar uma letra a. Obviamente é um único caractere, ocupando uma única célula de múltiplos caracteres (i.e. text) ocupará várias células, coleções de células, como acabei de explicar, são chamadas de matrizes.

strings em PAWN (e outras línguas) é o que é chamado de "encerrado NULL", isso significa que quando 0 é atingido, a cadeia de caracteres termina. Este não é o mesmo que o caractere "0", representado pelo número 48, este é o caractere nulo, representado pelo número 0. Isso significa que você pode ter uma matriz de seqüência de 20 grandes células, mas apenas ter uma seqüência de três caracteres se o quarto caractere é o caractere NULL, sinalizando o fim da cadeia. Você não pode no entanto ter uma seqüência de 20 caracteres, como o caractere NULL deve ser na seqüência, assim, em uma matriz de células 20 você pode ter uma seqüência de caracteres 19 e um caractere NULL de terminação.

new
	minhaString[15] = "Hello World!";

Esse código declara uma nova seqüência de caracteres com espaço suficiente para uma seqüência de 15 caracteres e define-se inicialmente para a seqüência de cinco caracteres "Hello World!", as aspas em torno do texto indicam que ele é uma string. Internamente, a matriz se parece com:

104 101 108 108 111 0 x x x x x x x x x x

O "x" não significa nada, neste exemplo, todos eles vão ser 0, mas como eles estão após o caractere nulo, não importa o que são, eles não afetarão a seqüência.

Strings podem ser manipulados como vetores normais, por exemplo:

new
	minhaString[16] = "Hello World!";
minhaString[1] = 97;

Vai mudar o caractere no espaço 1 para o caratcete representado pelo número 97 (uma minúscula "a "), resultando na seqüência de leitura "alô". Isso pode ser escrito muito mais legívelmente e fácil de editar como:

new
	minhaString[16] = "Hello World!";
minhaString[1] = 'a';

As aspas simples em torno do "a " significa que ele é um caractere, não uma seqüência, os caracteres não precisam ser NULL finalizado como eles estão sempre apenas uma célula longa, eles também podem ser usados de forma intercambiável com números, se você souber o que eles representam.

new
	minhaString[16] = "Hello World!";
minhaString[1] = '\0';

'\0' são dois caracteres, no entanto, o \ é um caractere especial, que modifica o próximo caractere, \0 significa NULL, o código é o mesmo que fazer:

new
	minhaString[16] = "Hello World!";
minhaString[1] = 0;

Mas isso NÃO é o mesmo que:

new
	myString[16] = "Hello World!";
myString[1] = '0';

A primeira e a segunda versão resultará na seqüência de ser simplesmente:

h

A terceira versão resultará na seqüência de ser simplesmente:

h0llo

Caractede de escape

Como mencionado brevemente uma barra invertida é um caractere especial, fazendo:

'\'

ou:

"\"

Vai dar um erro no compilador porque o \ modifica o próximo caractere assim aqueles constantes não serão encerrados corretamente, isso pode ser usado para criar caractere que normalmente não pode ser criado, por exemplo:


new
	minhaString[4] = "\"";

Esse código irá criar uma string que consiste de apenas criar uma aspa, normalmente aspas duplas sinalizam o fim de uma seqüência de escrita, mas a barra invertida faz com que as aspas duplas sejam escritas imediatamente após uma parte da string, e as aspas depois terminam a seqüência de caracteres em vez. Outros caracteres especiais são:

\0 Caractere NULL finaliza uma string.
\n saltar linha use \n para uma nova linha no Linux (também funciona no Windows)
\r retorno de procedimento Use \r\n para uma nova linha no Windows
\\ Backslash Used to put an actual backslash in a string
\' Aspa simples Usado para usar uma única barra como um caractere de aspas simples (uso: '\'')
\" Aspas duplas Usado pra colocar aspas duplas na string
\xNNN; Número hexadecimal Usado para definir o caractere ao caractere representada por um número hexadecimal especificado em lugar de NNN
\NNN; Número Usado para definir o caractere ao caractere representado pelo número especificado em lugar de NNN (ver \ 0)

Existem outros, mas esses são os principais.

Tags

Uma tag é uma peça adicional de informação sobre uma variável que define onde ela pode ser usada. Por exemplo:

new
    Float:a = 6.0;

O "Float" parte é a tag, isso define esta variável como float (número de não-inteiros) e determina onde ele pode ser usada.

native AjustarGravidade(Float:gravidade);

Isto significa que a função AjustarGravidade leva um único parâmetro que deve ser um float, por exemplo:

AjustarGravidade(6.0);
new
   Float:fGrav = 5.0;
AjustarGravidade(fGrav);

Isso vai definir a gravidade de 6 (6,0 como um float) a 5 (5.0 como um float). Usando a etiqueta errada no lugar errado, muitas vezes, gera um erro(tag mismatch):

AjustarGravidade(MinhaTag:7);

Isso vai tentar definir a gravidade a 7 com a tag "myTag", que não é claramente um "Float" isso é errado. Observe também que as tags são case sensitive(diferenciam maiúsculas de minúsculas).

Escopo

Escopo é o local onde uma variável pode ser usada. Há quatro âmbitos principais: locais, estáticas local, global e global estática. Todas as variáveis só podem ser usadas depois que eles são declarados por isso esta é a direita:

new
    var = 4;
printf("%d", var);

Isso é errado:

printf("%d", var);
new
    var = 4;

local

Uma variável local é declarada com um "new" dentro de uma função ou parte de uma função:

MyFunc()
{
    new
        var1 = 4;
    printf("%d", var1);
    {
        // como este é um nível mais baixo, var1 ainda existe
        new
            var2 = 8;
        printf("%d %d", var1, var2);
    }
    // como este é um nível mais alto, var2 não existe mais
}
// var1 não existe mais

As variáveis locais são de descanso a cada hora, por exemplo:

for (new i = 0; i < 3; i++)
{
    new
        j = 1;
    printf("%d", j);
    j++;
}

Irá imprimir:

1
1
1

j é criado, impresso, incrementado destruído em seguida, e em seguida.

local estática

Um local estático pode ser usado do mesmo modo que um local, mas não se esqueça que é o valor antigo, por exemplo:

MyFunc()
{
    static
        var1 = 4;
    printf("%d", var1);
    {
        // como este é um nível mais baixo, var1 ainda existe
        static
            var2 = 8;
        printf("%d %d", var1, var2);
    }
    // como este é um nível mais alto, var2 não existe mais
}
// var1 não existe mais

Esse código vai se comportar exatamente como o novo exemplo:

for (new i = 0; i < 3; i++)
{
    static
        j = 1;
    printf("%d", j);
    j++;
}

Irá imprimir

1
2
3

Como j é estático lembra o seu valor antigo.

global

As variáveis globais são declaradas fora de uma função e podem ser usadas em todas as funções:

new
    gMinhaVar = 4;
 
MyFunc()
{
    printf("%d", gMinhaVar);
}

Eles nunca são repostas ou perdidas.

global estática

Variáveis globais estáticas são como globais normais, mas só podem ser usadas no arquivo em que são declaradas:

File1:

static
    gsMinhaVar = 4;
 
MyFunc()
{
    printf("%d", gsMinhaVar);
}
 
#include "File2"

File2:

MinhaFunc2()
{
    / / Isto está errado pois gsMinhaVar não existe aqui
    printf("%d", gsMinhaVar);
}

static também pode ser aplicado à funções da mesma forma.

Controlando estruturas

Estruturas de controle determinam o fluxo do programa. Elas podem executar código ou não com base no conteúdo de variáveis, retornos de funções e outras coisas. Eles também podem fazer as coisas repetidamente, se necessário.

Plavras chave (keywords)

Main article: keywords
Personal tools