Pages

domingo, 14 de agosto de 2016

O formato do SNC Completo

O formato do SNC


Introduction


O arquivo CNS de um jogador serve para dois propósitos:
Ele define as variáveis ​​de que o jogador, tais como a velocidade de caminhada, desenhando fator de escala, e assim por diante.
Ele contém os estados do jogador, que descrevem todos os movimentos que o jogador pode fazer. Unidos são os blocos de construção que você pode usar para criar simples, bem como movimentos complicados.
Como muitos outros arquivos de caracteres, o SNC é um arquivo de texto que pode ser editado em qualquer editor de texto.
No arquivo CNS, um ponto e vírgula (;) é considerado um caractere "comentário". Qualquer texto na mesma linha após a vírgula será ignorado pelo programa. O CNS é principalmente case-insensitive, ou seja, "MyName" é tratado da mesma forma "meunome" e "MyName". A única exceção é o gatilho de comando (abordados em detalhes na documentação do CMD).


Some terminology
Quando dizemos "grupo", queremos dizer qualquer bloco de linhas de texto que começa com algo que se parece com [nome do grupo], e termina antes do próximo grupo. Por exemplo, o grupo Foo consiste nas três primeiras linhas no seguinte:
[Foo]
linha1
linha2

[Grupo 2]
mais linhas

Dentro de um grupo, os parâmetros podem aparecer em qualquer ordem. Então,
[SomeGroup]
valor1 = 1234
valor2 = "Uma string"

é equivalente a:
[SomeGroup]
valor2 = "Uma string"
valor1 = 1234

Player Variables
Sem a documentação completa ainda. Veja chars / kfm / kfm.cns para comentários sobre cada variável.
Alguns importantes a serem observados:
Em [Size], você pode usar xscale e yscale para alterar a largura e altura de seu personagem. Isso poupa o trabalho de escalar cada um dos sprites.
Configure a velocidade do jogador em [Velocity]
Definir aceleração descendente do jogador - yaccel em [Movimento]

States
Animações e sons são as manifestações mais imediatamente visíveis de um personagem MUGEN, mas o verdadeiro "coração" da personagem é o seu arquivo CNS (s). O arquivo CNS, também conhecido como arquivo de "estados" do personagem, contém o código que realmente dá o caráter de sua funcionalidade - que lhe permite realizar movimentos quando ordenou, para bater seu oponente, ou para obedecer à lei da gravidade.

A estrutura de um ficheiro do SNC é simples. O código é organizado em grupos lógicos chamados [StateDef] s. [StateDef] blocos são numerados, e um personagem típico pode conter centenas deles. Dentro de cada um [StateDef] é um número de [Estado] blocos, também conhecidos como os controladores do Estado. Cada controlador de estado é um par gatilho de ação: especifica uma ação para o personagem de tomar, e as condições em que deve ser realizada essa ação.
A cada instante ("tick") de tempo de jogo, o personagem executa o código em algum [StateDef] bloco. Por exemplo, se o personagem está em pé à toa, então é normalmente executado no [StateDef 0] bloco. Para resumir, podemos dizer que o personagem está "em estado de 0". Em cada tick que o personagem está em estado de 0, ele irá avaliar os controladores de estado no [StateDef 0] bloco de cima para baixo, verificando as condições e tomar quaisquer ações que são especificadas. Se o personagem precisa mudar para algum outro [StateDef] bloco, digamos afirmar 417 porque ele está realizando um movimento, ele pode executar um controlador de estado ChangeState para fazer a troca. O personagem, então, iniciar a execução do código [StateDef 417], exatamente da mesma forma.
Cada personagem MUGEN, adicionalmente, tem três estados especiais, numeradas -1, -2 e -3. Estes são os únicos estados permitidos com números negativos. Estado -1 geralmente contém controladores estaduais que determinam regras de transição de estado com base na entrada do usuário (comandos). Estado -2 contém outros controladores estaduais que precisam ser verificados a cada tick. -3 Estado contém os controladores de estado que são verificados a cada tick a menos que o jogador está usando temporariamente os dados de estado de outro jogador (por exemplo, quando o jogador está sendo jogado).
Para colocá-lo todos juntos: para cada tique-taque do jogo-time, MUGEN faz uma única passagem por cada um dos estados especiais, de cima para baixo, em ordem crescente de número de estado (-3, -2, -1). Para cada controlador de estado encontrado, seus gatilhos do tipo condição são avaliados e, se eles estão satisfeitos, o controlador é executado. Em seguida, o processamento prossegue para o próximo controlador de estado no estado. Uma transição de estado (ChangeState) em qualquer um dos estados especiais actualizará número actual estado do jogador, e abortará processar o restante do estado. Depois de todos os controladores estaduais nos estados especial foram verificados, o estado atual do jogador é processado, novamente de cima para baixo. Se uma transição de estado é feita fora do estado atual, o resto dos controladores de estado (se houver) no estado atual são ignorados, eo processamento continua a partir do início do novo estado. Quando o fim da actual estado for atingido e nenhuma transição de estado é feita, suspende o processamento para este carrapato.
Há uma exceção para o cenário acima. Se o personagem é um personagem "ajudante", ou seja, gerado pelo controlador estado Helper, que o personagem não terá os estados especiais -3 e -2. O caráter auxiliar não terá o estado especial -1 ou, se não tiver a entrada de teclado ativada. (Isto é controlado pelo controlador de estado quando o auxiliar de caracteres é criado.)

Introduction to State
Programação estados é a parte mais difícil da criação de um personagem. Implica muito trabalho, testes e às vezes tentativa e erro. Nesta seção, vamos muitas vezes referem-se ao jogador que está sendo programado, e seu adversário também. Vamos chamar o jogador cujos estados estamos editando P1, P2 e seu oponente.
Não desanime se você não entender muito desse documento em sua primeira leitura. A melhor maneira de aprender sobre os estados é a primeira a brincar com os valores no sistema nervoso central de um personagem completo, e ver quais os efeitos que têm sobre ele ou ela. Não há nada a temer "ajustes" o SNC; MUGEN é projetado para detectar erros de sintaxe e relatá-los.
Incluído no pacote de distribuição MUGEN é um personagem chamado Kung Fu Man (KFM para breve.) Você pode encontrá-lo no diretório chars / kfm.
O arquivo CMD contém declarações de nomes de comandos ea definição de Estado -1, um estado especial que é usado para controlar a forma como o personagem responde à entrada do usuário. Consulte o documento CMD para mais informações.

Abaixo estão alguns conceitos que serão úteis para você saber.
Vida e poder
Barra de vida de um jogador é a barra amarela no topo da tela do seu lado da tela. Quando a barra de vida chega a zero, o jogador é nocauteado. Sua barra de energia é a barra azul, e que aumenta a cada ataque que ele dá ou tira. Quando a barra de energia atinge certos valores, que ele pode fazer super movimentos.

Control
Quando dizemos que um jogador "não tem controle", queremos dizer que ele está pronto para andar ou pular ou atacar. Um jogador que não tem o controle não vai responder à sua entrada (a partir do teclado ou joystick). Por exemplo, quando P1 está em seu estado suporte, ele tem o controle, e andar para a frente, se você pressionar o botão para a frente. Um jogador normalmente não terá controle quando ele está em um estado de ataque, caso contrário você pode simplesmente ir embora no meio de um soco.
Há uma exceção à regra, no entanto. Às vezes, você pode deixar o jogador responder a certos movimentos, mesmo que ele não tem controle. Isto é chamado um "movimento de interrupção", ou um "movimento cancelar". Consulte a documentação do CMD para mais detalhes.
Vamos freqüentemente se referem a "bandeira controle" do jogador. A "bandeira" é um valor que é verdadeiro, ou falso. Se dissermos bandeira controle do jogador é verdade, então isso significa que ele tem o controle.

Game-time and state-time
MUGEN mantém o controle do tempo que passou no jogo. Toda vez que o jogo é atualizado (o que inclui atualizar os jogadores, verificando colisões, e desenhar na tela), dizemos jogo-time aumentou em um. O tempo que um jogador tenha passado num estado é conhecido como o "tempo de estado". O tempo de estado começa em 0, no início de um estado, e aumenta em um carrapato para cada escala de tempo de jogo.

Position, velocity and acceleration
Aqueles de vocês com conhecimento básico de matemática deve compreender esses conceitos. M.U.G.E.N usa o seguinte sistema de coordenadas. Quanto maior a posição x, o mais certo é o jogador. A menos que a posição-x, o que é mais estreita para a esquerda. A posição y de zero é ao nível do solo. Como a posição y-do jogador se torna maior, ele se move para baixo. Por exemplo, uma posição-y negativo significa que ele está no ar. Da mesma forma, quando dizemos que um jogador tem positiva velocidade x, isso significa que ele está se movendo para a frente, e se ele como negativo-x velocidade, ele está se movendo para trás. Um jogador com positivo y-velocidade está se movendo para baixo, e um y-velocidade negativa significa que ele está se movendo para cima. A positivo aceleração x significa que o jogador de-velocity x está aumentando, uma aceleração x negativo significa que sua velocidade-x está diminuindo. O mesmo vale para y-aceleração.

Juggling
MUGEN permite a certos movimentos de "malabarismos", isto é, para acertar os oponentes que foram batidos no ar, ou está deitado no chão. O sistema de malabarismo funciona da seguinte maneira: cada pessoa começa com um determinado número de malabarismo "pontos" no primeiro hit que faz cair, geralmente 15.
Alguns rápida terminologia: quando dizemos que um jogador está "caindo", então quer dizer que ele não se recuperar o controle no ar, e vai cair no chão.
Se um jogador for atingido enquanto ele está na queda no ar ou deitado no chão, em seguida, seus malabarismos pontos irá diminuir por um valor dependendo do ataque. Quando um ataque requer mais pontos malabarismos que o adversário deixou, em seguida, o ataque vai perder. Qualquer movimento que faz com que o adversário a cair imediatamente subtrai seus malabarismos pontos no primeiro hit.
Por exemplo, um ataque que requer malabarismos 7 pontos poderia, teoricamente, ser usado para manipular o oponente duas vezes (supondo que você começou com 15 pontos), deixando o adversário com um ponto à esquerda. Subsequentes de tais ataques vão perder.
A razão para este sistema é para evitar manipular infinitas combinações no ar.

Basic Parts of a State
Nota: Esta seção assume que você tenha pelo menos navegado na documentação de arquivos do AIR, e compreender os conceitos de animação, como saber o significado das palavras e frases como ação e elemento de uma ação-chave.
Aqui está um pequeno exemplo para estado P1:

[Statedef 200]
type = S
física = S
movetype = I
ctrl = 0
anim = 200
velset = 0

[State 200, 1]
type = ChangeState
trigger1 = AnimTime = 0
valor = 0
ctrl = 1

Este estado reproduz a ação 200 da animação do P1, P1 e retorna ao seu estado de pé após a animação terminou. Neste caso, assume ação 200 tem uma looptime finito. Isto é, a ação 200 não tem quaisquer elementos com tempo igual a -1.
Neste ponto, você não precisa se preocupar com os detalhes. Vamos começar por saber o que um estado consiste.
Todos os estados devem ter uma única seção Statedef e uma ou mais seções do Estado.
Statedef contém as informações a partir de um estado, como que tipo de Estado é (em pé, agachamento, no ar) e que tipo de movimento que ele está fazendo (atacando, em marcha lenta.
Cada secção de estado é referido como um controlador de estado, ou um controlador para abreviar. Controladores de dizer ao programa o que fazer para P1, e quando fazê-lo. Existem muitos tipos de controladores, cada um com sua própria função. Por exemplo, existem controladores para alterar a posição de jogadores ou velocidade, definir os efeitos dos ataques, criar projéteis, alternar entre acções de animação, mudança de estados, e assim por diante. Cada controlador deve ter pelo menos um gatilho. Um gatilho é um evento que faz com que o controlador para ser ativado. Exemplos são: gatilho, no início do estado, o gatilho na extremidade da animação (como visto no Estado exemplo acima), o gatilho de um elemento de uma acção de animação, gatilho quando P2 está dentro de uma determinada gama de P1, e assim diante.

Details on StateDef
Cada estado deve começar com exatamente um grupo StateDef, também conhecido como uma seção Statedef. Um grupo StateDef deve ficar assim (colocar em um ou mais parâmetros, onde os pontos são):

[Statedef state_number]
. state_parameters.
Substitua state_number com o número do estado que você está programando. Com exceção dos números dos grupos especiais (ver Anexo A) que estão autorizados a usar qualquer número de estado que você escolher. Para evitar a escolha de um número de grupo especial, não escolha os números 0-199 e 5000-5999.
As linhas que se seguem deve incluir os seguintes parâmetros básicos:
type
movetype
physics
anim
Há também parâmetros opcionais adicionais que podem ser incluídos:
velset
ctrl
poweradd
Juggle
facep2
hitdefpersist
movehitpersist
hitcountpersist
sprpriority

Este é o tipo de estado de P1 naquele estado. Ele define se ele está de pé, agachando-se, no ar, ou deitado. Os valores correspondentes são de "S", "C", "A" e "L", respectivamente (sem as aspas). Para deixar o tipo inalterado em relação ao estado anterior, use um valor de "U". Se esta linha for omitida, assume o tipo é "S". Será mais comumente usar "S", "C" e "A". Por exemplo, um tipo de estado agachada iria requerer a linha:

type = C

O tipo é usado para determinar vários factores, o mais importante, como P1 irá reagir a ser atingido. Por exemplo, estar em uma "posição" do tipo de estado, P1 vai reagir como se estivesse de pé no chão. Se o tipo é "ar", então P1 iria reagir ao sucesso nesse sentido.

movetype

Este é o tipo de movimento P1 está fazendo: "A" para o ataque, "I" para idle e "H" para ser atingido. Para deixar o movetype inalterada desde o estado anterior, use um valor de "U". O valor é considerado como "I" se esta linha é omitida. "A" e "H" deve ser auto-explicativo. "I" é usado para os estados onde P1 é nem atacando, nem ser atingido. Por exemplo, um estado de ataque devem ter uma linha:

movetype = A

Você precisa especificar o movetype para que o programa vai saber como processar o Estado. Especificação incorreta do movetype pode causar P1 para agir de forma incorreta.

Physics

Você precisa especificar o que a física de usar naquele estado. Os valores válidos são "S" para a posição "C" para Crouch, "A" para o ar, e "N" para ninguém. Para deixar a física inalterada a partir do estado anterior, use um valor de "U". Se omitido, o valor de "N" é assumido. O tipo de física é utilizado para determinar se comporta como P1.

Por "S" física, P1 irá experimentar o atrito com o chão. O valor para o coeficiente de atrito é definido nas variáveis ​​Player.
Para "C" física, P1 vai sentir a fricção, assim como no estado "S".
Para "A" física, P1 vai acelerar para baixo, e se a sua posição-y é maior que 0 (ou seja, ele toca o solo), ele irá imediatamente para o estado de destino.
Se você usar "N" P1 não vai usar qualquer um desses física pré-programados.
Não confunda "física" com o estado de "tipo". Eles são geralmente os mesmos, mas você tem a escolha se você quer mais controle. Por exemplo, você pode optar por usar o "N" (não física) e especificar sua própria aceleração e detecção de pouso para um estado aéreo.

anim

Este parâmetro altera a ação de animação de P1. Especifique o número de acção como o valor. Se você não quer P1 para mudar de animação no início do estado, omita esse parâmetro.
Portanto, para ter um estado com o número 400, onde o jogador está fazendo um ataque agachado com Ação 400, os parâmetros típicos seriam:

[Statedef 400]
type = c
movetype = um
física = c
anim = 400
velset

Pode utilizar velset para definir a velocidade do P1, no início do estado. O formato é um número par, que representa a velocidade de x e y, respectivamente, a velocidade. Omitir essa linha vai deixar a velocidade do P1 inalterada. Por exemplo, a

velset = 4, -8

faz P1 começar a se mover na diagonal para cima e para frente.
Há uma exceção a isso. Mesmo se você tiver velset = 0, P2 atacando no canto vai empurrar P1 distância.
ctrl
Este parâmetro irá definir o controle de P1. Um valor igual a "0" define o sinalizador como falso, "1" define-o como verdadeiro. Se for omitido, bandeira do controle da P1 é deixado inalterado. Por exemplo, para dar o controle P1, use

ctrl = 1
poweradd

Quando incluído, o parâmetro poweradd acrescenta a barra de energia do jogador. O valor é um número, e pode ser positivo ou negativo. Este parâmetro é normalmente usado em movimentos de ataque, onde você quer que o jogador ganhar o poder apenas por realizar o ataque. Por exemplo, para adicionar 40 poder, tipo

poweradd = 40

fazer malabarismos
O parâmetro malabarismos só é útil para ataques. Ele especifica quantos pontos de malabarismo o movimento exige. Se omitido para um ataque, que o ataque vai fazer malabarismos se o estado atacando anterior malabarismos com sucesso. Você deve incluir o parâmetro de fazer malabarismos para todos os ataques. Se um ataque se estende por mais de um estado, inclua o parâmetro malabarismos apenas no primeiro estado desse ataque. Veja também malabarismo.

facep2

Ao incluir a linha facep2 = 1, o jogador será transformado, se necessário, para enfrentar o adversário no início do estado. facep2 tem o valor padrão de "0" se omitido.

hitdefpersist

Se definido como 1, qualquer HitDef que estão ativos no momento de uma transição de estado para este estado permanecerá ativo. Se definido como 0, o padrão, tais HitDef será desativado quando a transição de estado é feita.

movehitpersist

Se definido como 1, as informações hit movimento a partir do estado anterior (se o ataque acertar ou não atendidas, guardado, etc; ver "Move *" desencadeia no gatilho docs) serão transferidos para este estado. Se definido como 0 (o padrão), esta informação será reiniciado após a entrada neste Estado.

hitcountpersist

Se definido como 1, o contador de visitas (quantos hits esse ataque foi feito) será feita ao longo do estado anterior a este estado. Se definido como 0 (o padrão), o contador de visitas será reposto em transição de estado. Este parâmetro não afecta o contador de combinação que é exibida na tela. Veja o HitCount e documentação gatilho UniqHitCount para saber como verificar o contador de visitas.

sprpriority

Se esse parâmetro está presente, a prioridade camadas do sprite do jogador será definido para o valor especificado. Se for omitido, a prioridade do sprite será deixado inalterado. common1.cns (o arquivo CNS que é herdado por todos os jogadores) define a prioridade do sprite de pé ou agachado jogadores para ser 0, e pulando jogadores para ser 1. Para a maioria dos estados de ataque, você vai querer definir sprpriority = 2, para que o atacante aparece na frente.
Veja sprpriority na documentação sctrls para saber como alterar a prioridade do sprite usando um controlador.

Details on State Controllers
Controller Format
Todos os estados devem ter pelo menos um controlador de estado, caso contrário ele irá causar um erro. Grupo controlador do Estado têm o seguinte formato:

[State state_number, some_number]
type = controller_type
trigger1 = condição_exp
parameters> opcional <universal
<additional parâmetros dependendo de domínio>

O state_number deve ser o mesmo número do estado do StateDef. some_number pode ser qualquer número que você escolher, é o número que é informado quando um erro for encontrado, então você sabe que controlador precisa ser corrigido.
Os parâmetros opcionais universais (aplicáveis ​​a todos os controladores de estado) são os ignorehitpause e os parâmetros de persistência. Se ignorehitpause é definido como 1, MUGEN irá verificar este controlador estado mesmo se o personagem estiver em pausa por um hit. Caso contrário, este controlador estado não será verificada durante uma pausa sucesso. O padrão é 0, o que é recomendado para todas as situações, mas excepcional. Para obter uma explicação do parâmetro de persistência, consulte Persistência Trigger.
controller_type é o nome do controlador que você está usando. Cada tipo de controlador tem um efeito diferente, e requer parâmetros diferentes. Veja sctrls.txt para uma lista completa de controladores do Estado.
A ordem dos controladores é significativa. Controladores referidos primeiro são os verificados e, se necessário, em primeiro lugar activada.
Aqui é um exemplo de um controlador que proporciona o controlo P1 no início do estado (o mesmo efeito que colocar ctrl = 1 como um parâmetro no StateDef):

[State 300, 1]; Estado 300. 1 é apenas um número arbitrário.
type = CtrlSet; Muda a bandeira controle.
trigger1 = Time = 0
valor = 1

Neste exemplo, o tipo CtrlSet permite que você mude a bandeira controle de P1. A linha que lê trigger1 = Time = 0 significa que este controlador é ativado quando o tempo de estado é 0, ou seja, no início desse estado. O valor da linha = 1 diz que pretende definir o valor do sinalizador de controle para 1, o que significa verdade. Se queremos fazer P1 iniciar o estado sem controle, então só precisamos de mudar a última linha para o valor = 0.
Vejamos um outro exemplo. Este controlador avança P1 por 10 pixels por duas vezes: no segundo e terceiro elemento do seu actual Ação Animação. Não se preocupe se você não sabe quais parâmetros ir com quais tipos de controlador. Você pode aprender mais sobre eles a partir da documentação do controlador do Estado (sctrls).

[State 300, 2]
type = PosAdd; Adiciona à posição de P1
trigger1 = AnimElem = 2; Gatilho em segundo elemento.
trigger2 = AnimElem = 3; Gatilho em terceiro elemento.
x = 10

Como você pode ver acima, cada controlador deve ter pelo menos um gatilho. Um gatilho é uma condição que faz com que o controlador para ser ativado. Este exemplo tem dois gatilhos, e o controlador é ativada quando um ou outro é verdadeiro.

Triggers
Trigger logic

O primeiro gatilho deve ser sempre trigger1 e gatilhos trigger2 subsequentes devem ser, em seguida, trigger3 e assim por diante. A lógica para decidir se um controlador deve ser ativado é:
São todas as condições de trigger1 verdade? Se assim for, então sim, ativar o controlador.
Caso contrário, repita o teste para trigger2, e assim por diante, até que não haja mais gatilhos são encontrados.
Isto pode ser pensado como "OU" lógica.
Tenha cuidado; pular números fará com que alguns gatilhos para ser ignorado. Por exemplo, se você aciona trigger1, trigger2 e trigger4 sem trigger3, então trigger4 será ignorado.
Agora, se você quer mais do que uma condição para ser atendidas antes que o controlador está ativado? Aqui está um exemplo comumente usado para testar se um jogador no ar atingiu o chão. Os gatilhos usados ​​são os seguintes:
trigger1 = Vel Y> 0; True se Y-velocidade é> 0 (descendo)
trigger1 = Pos Y> 0; True se-position Y é> 0 (abaixo do solo)
Neste ponto, você pode ser confundido com o formato do gatilho. Não se preocupe com isso agora. Nós vamos chegar a isso em breve.
Como você pode ver acima, ambos os gatilhos têm o mesmo número. Quando vários disparos têm o mesmo número, ele implementa "E" lógica. Isto é, o controlador é activado, se cada um dos gatilhos com o mesmo número é verdadeiro, mas não se uma ou mais de entre eles é falsa.
Você pode combinar as duas idéias. Por exemplo:
trigger1 = Vel Y> 0; True se Y-velocidade é> 0 (descendo)
trigger1 = Pos Y> 0; True se-position Y é> 0 (abaixo do solo)
trigger2 = Time = 5; True se-time do estado é de 5
O controlador para este seria ativado se o jogador caiu no chão (y-y-velocidade e posição são ambos> 0) ou se seu tempo estado tinha 5 anos.

Aqui está um resumo:
Triggers com o mesmo número ativar o controlador somente se todas elas são verdadeiras.
Triggers com números diferentes ativar o controlador se houver um ou mais deles são verdadeiras.
O formato de um gatilho é:
gatilho? = Condição_exp
condição_exp é uma expressão aritmética a ser verificado para a igualdade a 0. Condição_exp Se for 0, então o gatilho é falsa. Se condição_exp é diferente de zero, em seguida, o gatilho é verdadeiro. O condição_exp é geralmente uma expressão de relação simples, como nos exemplos acima, mas pode ser tão simples ou tão complicada como requerido.
É possível a utilização de operadores lógicos entre expressões. Por exemplo, isso é equivalente ao exemplo anterior supra.
trigger1 = ((Vel Y> 0) && (Pos Y> 0)) | | Time = 5
Veja expressões para uma explicação detalhada de expressões aritméticas.
Um atalho útil que você pode usar é triggerall. Ele especifica uma condição que deve ser verdadeira para todos os gatilhos. Por exemplo, considere:
triggerall Vel = X = 0
trigger1 = Pos Y> -2
trigger2 = AnimElem = 3
trigger3 = Time = [2,9]
Para qualquer uma trigger1 para trigger3 a ser marcada, a condição triggerall deve ser verdade também. Neste caso, desde que a velocidade-x não é 0, então o controlador de estado não será activado. Você pode ter mais de uma condição triggerall se você precisar. Note-se que pelo menos um trigger1 deve estar presente, mesmo se você especificar triggerall.

Trigger Persistency
No caso em que você não quer que o gatilho para ativar cada vez que a condição é verdadeira, você vai precisar adicionar um parâmetro persistente. Vamos começar com um exemplo:

[State 310, 1]
type = PosAdd
trigger1 = Vel Y> 1
x = 10

Este controlador de estado avança P1 por 10 pixels para cada escala de tempo de jogo, onde P1 do y-velocidade é maior que 1. Ou seja, o controlador está sendo ativado sempre que a condição de disparo é verdade. Se queremos que o controlador a ser ativado apenas uma vez, teremos que adicionar uma linha:

[State 310, 1]
type = PosAdd
trigger1 = Vel Y> 1
persistent = 0; <- Adicionado essa linha
x = 10

persistente tem um valor padrão de 1, o que significa que o controlador é ativado toda vez que o gatilho é verdade. Definir persistente a 0 permite que o controlador a ser ativado apenas uma vez durante esse estado. Isso vale até P1 deixa naquele estado. Se P1 retorna ao estado que mais tarde, o controlador pode ser activado novamente.
O parâmetro persistente também pode ter diferentes valores 0 e 1:

[State 310, 1]
type = PosAdd
trigger1 = Vel Y> 1
persistente = 2; <- Modificado esta linha
x = 10

Neste caso, a definição persistente de 2 significa que o controlador será ativado uma vez em cada duas vezes o gatilho é verdade. Definindo persistente para o controlador 3 ativa cada terceiro tempo, e assim por diante.

Trigger redirection
Alguém pode querer verificar o statetime da meta do jogador, ou o pai do jogador (se o jogador é um auxiliar), etc Isso é possível utilizando o chamado redirecionamento gatilho. Expressões para ver mais detalhes.


Commonly-used controllers
O controlador nulo será útil para depuração. Um controlador nulo basicamente não faz nada. Você pode usá-lo para desligar temporariamente determinados controladores, em vez de comentar a seção inteira. Por exemplo, você pode querer desativar este:

[State 300, 1]; Controller, que acelera a frente P1
type = VelAdd
trigger1 = Tempo> = 0
x = 0,8

Basta comentar o tipo e colocar em null:

[State 300, 1]; Controller, que acelera a frente P1
type = null; VelAdd
trigger1 = Tempo> = 0
x = 0,8

Mais tarde, quando você quiser reativar o controlador, basta alterar o tipo de volta para o que costumava ser.
Agora vamos olhar para o exemplo:

[Statedef 200]
type = S
física = S
movetype = I
ctrl = 0
anim = 200
velset = 0

[State 200, 1]
type = ChangeState
trigger1 = AnimTime = 0
valor = 0
ctrl = 1

[State 200, 1] é um controlador ChangeState. Como o nome indica, ela muda número de estado de P1 (ou seja, o [StateDef] bloco a partir do qual P1 executa). O parâmetro de valor deve ter o número do estado para mudar. O parâmetro ctrl opcional pode ser definido bandeira do controle da P1 como ele muda de estado.
Agora vamos fazer deste um estado ataque. Antes de mais nada, a acção de animação precisa caixas de colisão de ataque. Uma rápida revisão da documentação AIR: Clsn1 é para o ataque e Clsn2 é o lugar onde o jogador pode ser atingido. Então P1 vai bater P2 se qualquer uma das caixas Clsn1 do P1 cruza-se com qualquer um dos Clsn2 caixas de P2.
Como exemplo, vamos supor que a ação de animação no arquivo AIR do P1 parecido com este:

[Comece ação 200]
200,0, 0,0, 3
200,1, 0,0, 4
200,2, 0,0, 4
200,3, 0,0, 3

Depois de definir as caixas delimitadoras, parece que:

[Comece ação 200]
Clsn2: 1
  Clsn2 [0] = -10,0, 10, -80
200,0, 0,0, 3
Clsn1: 1
  Clsn1 [0] = 10, -70, 40, -60
Clsn2: 2
  Clsn2 [0] = -10, 0, 10, -80
  Clsn2 [1] = 10, -70, 40, -60
200,1, 0,0, 4
Clsn2Default: 1; Use esta caixa para os dois últimos quadros
  Clsn2 [0] = -10,0, 10, -80
200,2, 0,0, 4
200,3, 0,0, 3

Como você pode ver, cada elemento tem uma caixa Clsn2 definido para ele (os dois últimos elementos estão usando as mesmas caixas). O segundo elemento é o único com uma caixa Clsn1.
Nota: Está tudo certo para definir Clsn1 caixas para quaisquer elementos em uma ação de animação, mas se você colocar uma caixa Clsn1 no primeiro elemento, o ataque será instantânea, e tornar-se bloqueado. Portanto, é recomendável que você defina Clsn1 boxes apenas para elementos após a primeira.
Agora estamos prontos para configurar o estado no SNC. Vamos explicar as mudanças abaixo.

[Statedef 200]
type = S
física = S
movetype = A; <- mudou de "I" para "A"
ctrl = 0
anim = 200
velset = 0
[State 200, 1]; <- Adicionado esse controlador estado
type = HitDef
trigger1 = AnimElem = 2
attr = S, NA
animtype = Luz
danos = 10
guardflag = MA
pausetime = 12,12
sparkxy = 0, -55
hitsound = 5,0
guardsound = 6,0
ground.type = alta
ground.slidetime = 12
ground.hittime = 15
ground.velocity = -5
air.velocity = -2,5, -3,5

[State 200, 2]
type = ChangeState
trigger1 = AnimTime = 0
valor = 0
ctrl = 1

O parâmetro movetype no StateDef está definido para uma de "ataque". Lembre-se de fazer isso para todos os estados de ataque. Como antes, as mudanças P1 de volta ao seu estado de pé após sua animação é longo.
Esse controlador HitDef parece um monstro! Não se preocupe, nós vamos passar por isso lentamente.

type = HitDef
trigger1 = AnimElem = 2

Isto especifica o tipo de controlador como HitDef, que significa "Definição Hit". Ela é desencadeada no segundo elemento de animação. Qualquer caixa Clsn2 a partir do momento que o gatilho foi ativado vai assumir essa definição atingido.
Se, por exemplo, você tinha uma Clsn1 tanto no segundo e terceiro elemento de animação, provocando uma HitDef no segundo elemento faz com que se aplica a ambos os elementos de animação. Então P1 vai bater no máximo uma vez: se o segundo elemento sucessos, o terceiro vai perder. Se o segundo elemento perde, o terceiro ainda pode bater. Para fazer o ataque atingido duas vezes, é necessário provocar um HitDef para cada um dos dois elementos.

attr = S, NA

Este é o atributo do ataque. Ele é usado para determinar se o ataque pode bater P2. Neste caso, é um ataque normal Permanente.
attr tem o formato attr = arg1, arg2, onde:
arg1 é ou S, C ou A. Semelhante ao statetype para o StateDef, este diz que se o ataque é um pé, agachado ou ataque aéreo.
arg2 é uma string de 2 caracteres. O primeiro personagem é ou N para "normal", S de "especial", ou H para "hiper" (ou "super", como é vulgarmente conhecido). O segundo personagem deve ser uma de "ataque" (um ataque hit normal), T para "jogar", ou P para o projétil.

animtype = Light

Isto refere-se ao tipo de animação que P2 irá para quando atingido pelo ataque. Escolha a partir de leve, médio, difícil ou para trás. Os três primeiros devem ser auto-explicativo. Voltar é a animação onde P2 é batido fora de seus pés.
danos = 10
Este é o dano que leva P2 quando bateu, e não faz nenhum dano, se guardado. Se mudamos a linha de danificar = 10, 1, então seria fazer um ponto de dano se guardado.

guardflag = MA

guardflag determina como P2 pode proteger do ataque. Aqui, pode ser guardado elevada (de pé), de baixo (agachamento) e no ar. O argumento deve ser uma seqüência de caracteres que inclui qualquer um dos seguintes: H para "alto", L para "baixo" ou A para o ar. M (médio) é equivalente a dizer HL.

pausetime = 12,12

Este é o tempo que cada jogador fará uma pausa no hit. O primeiro argumento é o momento de congelar P1, medido em game-ticks. O segundo é o tempo para fazer agitação P2 antes de recuo do hit.

sparkxy = 0, -55

Este é o lugar onde fazer o acerto / guarda faísca. Os argumentos devem estar na forma x, y. x é relativa para a frente da P2. Um x negativo faz com que uma faísca mais profundo dentro P2. y é relativo a P1. A y negativo faz com que uma faísca mais acima.

hitsound = 5,0

Este é o som para tocar no hit (de fight.snd). O fight.snd incluído permite que você escolha a partir de 5,0 (som hit luz) até 5,4 (pancada dolorosa). Para reproduzir um som a partir do arquivo SND do próprio jogador, antes do primeiro número com um S. Por exemplo, hitsound = S1, 0.

guardsound = 6,0

Este é o som para tocar em guarda (de fight.snd). Agora tudo o que temos é 6,0. Para reproduzir um som a partir do arquivo SND do próprio jogador, antes do primeiro número com um S.

ground.type = alta

Este é o tipo de ataque para ataques terrestres (que também padrões para ataques aéreos, se você não especificar um parâmetro air.type). Neste caso, é um ataque elevados. Escolha de alta para os ataques que fazem a cabeça de pressão P2 para trás, baixo para os ataques que parecem que bateu no estômago, de viagem para ataques baixos de varredura, ou Nenhum para não fazer nada para P2. Ataques de alto e baixo são os mesmos em P2 se o AnimType está de volta.

ground.slidetime = 12

Este é o tempo em game-ticks que o P2 vai deslizar para trás para depois de ser atingido (desta vez não inclui o pausetime para P2). Aplicável apenas aos golpes que mantém o P2 no chão.

ground.hittime = 15

Tempo que estadias P2 no estado hit depois de ser atingido. Aplicável apenas aos golpes que mantém o P2 no chão.

ground.velocity = -5

Initial-velocidade x dar P2 depois de ser atingido, se P2 está em um estado em pé ou agachado no chão. Você pode especificar uma velocidade y como o segundo argumento, se você quiser P2 para ser batido no ar, por exemplo. ground.velocity = -3, -2.

air.velocity = -2,5, -3,5

Velocidade inicial para dar P2 se P2 é atingido no ar.
Há mais coisas que você pode controlar em uma HitDef. Consulte a documentação sctrls para mais detalhes.

Common States (common1.cns)
Se você olhar para arquivo DEF de um jogador, você vai ver a linha:
stcommon = common1.cns; estados comum
Cada jogador compartilha alguns estados comuns, que são as partes básicas do motor de jogo. Estes estados comuns são encontrados em data/common1.cns. Alguns exemplos são os estados para correr e ser atropelado. A lista completa está disponível em Números especiais do Estado.
Se há um estado comum que você gostaria de substituir por um determinado jogador, tudo que você precisa fazer é um estado em que o CNS do jogador com o mesmo número que o que você gostaria de substituir. Então, quando o jogador muda para que determinado número de estado, ele vai entrar nesse novo estado, em vez de um em common1.cns.
Você deve se lembrar que quando substituindo certos estados que possuem propriedades especiais codificadas dentro de MUGEN, os novos estados que você faz ainda terá as mesmas propriedades especiais, como os que você cancelou. Por exemplo, o estado de funcionamento (estado 100) define a velocidade do jogador para qualquer valor que você especificou em suas variáveis ​​jogador. Se você substituir estado 100, o novo estado ainda terá a propriedade de definir a velocidade daquele jogador.

Um exemplo comum é substituir o estado de execução. O comportamento padrão do MUGEN para o estado de execução é ter o jogador continuar a avançar a uma velocidade constante, até que você solte a tecla de avanço. Nesse ponto, ele retorna ao estado de stand.
Agora, vamos dizer que queremos que o jogador (vamos chamá-lo P1) ao invés saltar para a frente, assim como o padrão duplo toque hop de volta. Você pode fazer um estado no CNS do P1:
, RUN_FWD (substituído ao tipo de traço)
[Statedef 100]
type = S; Correr é no chão
física = N; Vamos definir nossas próprias física
anim = 100; ação Anim 100
ctrl = 0; No controle da duração da corrida
[State 100, 1]; Para iniciar a frente arrojado
type = VelSet
trigger1 = Time = [0,5]
x = 6
[State 100, 2]; Friction após traço inicial
type = VelMul
trigger1 = Tempo> 5
x = 0,85

[State 100, 3];
type = ChangeState
trigger1 = AnimTime = 0
valor = 0
ctrl = 1

Aqui, assumimos que a acção 100 tem um looptime finito. A velocidade em run.fwd em [Velocity] das variáveis ​​jogador não é realmente ignorado, mas [Estado] 100,1 substituições que detalham definindo a velocidade-x para 6.

Special State Numbers
Se você não pretende substituir um estado comum, evite escolher os números estaduais na faixa de 0-199 e 5000-5999. Aqui está uma lista de estados em common1.cns.Number Descrição
0 Suporte
10 Suporte para agachar
11 Crouching
12 Crouch para ficar
20 Caminhada
40 Jump Start
45 Air começo do salto
50 Ir para cima
52 Ir terra
100 Corra para frente
105 Hop para trás
106 Hop trás (terra)
120 Guard (start)
130 guarda Stand (guarda)
131 Crouch guarda (guarda)
132 Air guarda (guarda)
140 Guard (final)
150 suporte hit guarda (agitação)
151 suporte hit guarda (batido para trás)
152 Crouch hit guarda (agitação)
153 Crouch hit guarda (batido para trás)
154 Air hit guarda (agitação)
155 Air hit guarda (bateu distância)
170 Lose (ao longo do tempo)
175 jogo Draw (ao longo do tempo)
190 Pré-intro
191 Intro (substituir esse estado para dar um caráter intro)
5000 Suporte obter-hit (agitação)
5001 stand-se bater (batido para trás)
5010 Crouch obter-hit (agitação)
5011 Crouch se-hit (batido para trás)
5020 Air obter-hit (agitação)
5030 air-hit (bateu distância)
5035 Air obter-hit (de transição)
5040 Air obter-hit (recuperando no ar, não caindo)
5050 Air obter-hit (queda)
5070 Tripped obter-hit (agitação)
5071 Tripped obter-hit (bateu distância)
5080 Downed obter-hit (agitação)
5081 Downed se-hit (batido para trás)
5100 Downed se-HIT (chão de queda)
5101 Downed se-hit (saltar fora do solo)
5110 Downed obter-hit (deitado)
5120 Downed obter-hit (levantando-se)
5150 Downed obter-hit (deitado derrotado)
5200 air-hit (queda de recuperação na terra; ainda caindo)
5201 Air obter-hit (recuperação queda no chão)
5210 Air obter-hit (recuperação queda no ar)
5500 animação tela Continuar
Inicializar 5900 (no início do ciclo)

Expressions
MUGEN suporta expressões aritméticas na maioria dos gatilhos e controladores do estado. Isto permite que o comportamento muito mais flexível personalizada do que seria possível apenas com valores fixos. Esta seção apresenta uma descrição dos conceitos de expressão e sintaxe.

Data types
MUGEN usa três tipos de dados: inteiros de 32 bits, flutuadores de 32 bits e um valor especial null, "bottom". Inteiros representam números inteiros entre -2 ^ 31 e 2 ^ 31-1, ou cerca de -2.000 a 2.000 milhões. Flutuadores são de precisão simples números de ponto flutuante. Isto é, eles são os números com uma "parte decimal," e cerca de 7 números significativos de precisão. Flutuadores podem representar pequenas frações ou números muito grandes.
Quando você escreve números em uma expressão, MUGEN deduz o tipo de dados a partir da presença de um ponto decimal. Assim, "7" é sempre um inteiro, por exemplo. Se você quisesse 7 como um float, em seguida, você deve escrever "7.0".
"Bottom" é um tipo de dados especial que zera qualquer expressão que aparece em (com algumas exceções muito limitadas). A sua presença indica algum tipo de situação de erro. Deve tentar código de tal maneira que a parte inferior não é produzido. Para mais detalhes, você pode ver a seção dedicada na parte inferior.
O comportamento das expressões aritméticas depende muito dos tipos de dados subjacentes usados ​​para representar números. Além disso, os controladores de estado pode esperar a sua entrada a ser dada como um certo tipo, e vai dar erros se o tipo errado é fornecido.
"Promoção de tipo" ocorre quando os valores de diferentes tipos de dados que precisam ser combinadas de alguma forma (por exemplo, através da adição). Geralmente, isto significa que um número inteiro será mudado para um flutuador, com a possível perda de precisão no processo. Nas seções a seguir, vamos notar quaisquer cenários de promoção do tipo relevantes.

Arithmetic Operators
Os operadores aritméticos permitem realizar operações básicas como adição, multiplicação, divisão, etc MUGEN tem uma selecção de operadores que deve ser familiar para a maioria dos programadores. Eles são como se segue:

+

Adiciona dois números. Se X e Y são ambos inteiros, em seguida, x + y é também um int. Se ambos forem flutuadores, em seguida, x + y é um flutuador. Se é um flutuador, então o outro é promovida a flutuar, e, em seguida, os dois flutuadores são adicionados.

-

A subtracção de números. Tipo de promoção funciona da mesma forma adição.

*

Multiplicação de dois números. Tipo de promoção funciona da mesma forma adição.

/

Divisão de dois números. Se X e Y são ambos inteiros, então x / y dá o quociente inteiro, isto é, o número de vezes que y vai uniformemente em x. Por exemplo, 7/2 = 3. Se X e Y são ambos flutuadores, então x / y retorna um flutuador. Nosso exemplo anterior seria 7.0/2.0 = 3.5. Se apenas um de x ou y é um flutuador, então o outro é promovido e divisão flutuador é executada. Divisão por 0 produz inferior.

%

O restante ou operador mod. Se X e Y são ambos inteiros, então x% y dá o restante quando x é dividido por y. Se um ou ambos são flutuadores, ou, se y for 0, então inferior é produzido.

**

O operador de exponenciação. Se x e y são ambos inteiros não negativos, então x ** y dá um int x representando elevado à potência de y. (Definimos 0 ** 0 = 1). No entanto, é muito fácil para transbordar o valor máximo possível para um int quando computação grandes potências. Nestes casos MAX_INT (a maior possível inteiro) será devolvido, e um aviso será gerada. Se um de x ou y é negativa ou é um flutuador, então ambos os argumentos são promovidos a flutuar e x ** y é calculado como uma exponenciação de números reais. Um exponenciação inválido como -1 ** 0,5 produzirá inferior.

!

NÃO operador lógico. ! X avalia a 0 (int) se x é diferente de zero e um (int) se x é zero.

&&

O operador lógico AND. x && y resulta em 1 (int) se x e y são ambos zero, e 0 (int) de outra forma.

| |

O operador lógico OR. x | | y resulta em 1 (Cont) Se um ou mais de X e Y é diferente de zero, e a 0 (int) em contrário.

^ ^

O operador XOR lógico. x ^ ^ y resulta em 1 (int) se exatamente um dos x e y é diferente de zero, e a 0 (int) em contrário.


~

O operador NOT bit a bit. ~ X inverte os bits do binário de x (complemento de dois) representação. Produz fundo, se x é um float.

&

O operador AND bit a bit. O bit enésima de x e y é definida se e somente se os bits enésima de ambos x e y estão definidos. Produz fundo, se x ou y é um float.


O operador OR bit a bit. O bit enésima de x | y é definida se e somente se o bit enésima de x ou de y (ou ambos) é definido. Retorna fundo, se x ou y é um float.

^

O operador XOR bit a bit. O bit enésima de x ^ y é definida se e somente se o bit enésima de exatamente um x e y está definido. Retorna fundo, se quer de x ou y é um float.

=

O operador de igualdade. Se X e Y são ambos inteiros ou ambos os flutuadores, x = y resulta em 1 (int) se x e y são iguais, e 0 em contrário. Se exatamente um x ou y é um float, então ambos são convertidos em carros alegóricos antes de testar a igualdade.


: =

O operador de atribuição. Um nome de variável unredirected (var (n) ou fvar (n) para valores adequados de n) deve aparecer no lado esquerdo. Se o lado da mão esquerda contém um variável número inteiro, então o lado da mão direita é truncado para um inteiro antes de atribuição. Se o lado da mão esquerda contém um flutuador variável, em seguida, o lado direito é convertido para flutuar, se necessário, antes de atribuição. Em ambos os casos, o valor da expressão é o valor que é atribuído a variável.

! =

O operador de desigualdade. Se x e y são ambos inteiros ou ambos carros alegóricos, x! = Y avalia a 1 (int) se x e y não são iguais, e 0 caso contrário. Se exatamente um x ou y é um float, então ambos são convertidos em carros alegóricos antes de testar a igualdade.

<

O operador menos-que. Se x e y são ambos inteiros ou ambos carros alegóricos, x <y avalia a 1 (int) se x <y, e 0 caso contrário. Se exatamente um x ou y é um float, então ambos são convertidos em carros alegóricos antes de testar a igualdade.

<=

Semelhante ao <, com a ressalva de que, se x = y, então x <= y retorna 1 (int).

>

O operador maior do que. Se x e y são ambos inteiros ou ambos carros alegóricos, x> y avalia a 1 (int) if x> y, e 0 (int) de outra forma. Se exatamente um x ou y é um float, então ambos são convertidos em carros alegóricos antes de testar a igualdade.

> =

Semelhante a>, com a ressalva de que, se x = y, então x> = y retorna 1 (int).

= [,]! = [,] = [,!) = [,) = (,]! = (,] = (,)! = (,)

Operadores de intervalo. Estes têm três argumentos, x, y, e z. Se qualquer um de x, y ou z é um flutuador, todos eles são convertidos para flutuantes. Após a conversão, se necessário, x = [Y, Z] é equivalente a (x> = y) && (x <= z). Da mesma forma, x = (y, z) é equivalente a (x> y) && (x <z). Os intervalos de semi-aberto tem o significado óbvio.
Os operadores de intervalo negada funcionam como segue: X = [Y, Z] é equivalente (após conversão, se necessário) para (x <y) | | (x> z!). x = (y, z) é equivalente a (x <= y) | | (x>! = z). Os intervalos de semi-aberto novamente tem o significado óbvio.
Você pode ver os operadores de intervalo como produzir os intervalos abertas, fechadas ou semi-aberto apropriados nos ints ou os carros alegóricos. O símbolo = significa adesão definida neste contexto.
Existem algumas restrições em intervalos onde podem ser colocados em uma expressão. Consulte a seção sobre a sintaxe para mais detalhes.

Precedence and associativity of operators
Se você considerar que uma expressão como 3 +2 * 5, o resultado é diferente, dependendo se você avaliar o * primeiro (rendimento 13) ou, se você avaliar o + primeiro (rendimento 25). Para ambigüidade expressões como esta, os operadores são atribuídos níveis de precedência distintos. Neste caso, a precedência de * é superior à precedência dos +, de modo que o * é avaliada em primeiro lugar, em seguida, a + é aplicado ao resultado. Portanto, a resposta correta é 13.
Se dois operadores compartilham a mesma precedência, então a expressão é avaliada da esquerda para a direita, exceto para os operadores unários eo operador de atribuição, que associam direita para a esquerda. Por exemplo, * e / share a mesma precedência, para 5,0 * 5/6 avalia a 25,0 / 6, que avalia a 4,166667. Por outro lado, o 5/6 * 5.0 avalia a 0 * 5.0, que avalia a 0,0. Por outro lado, porque os operadores unários associam direita para a esquerda - 0 é agrupado como - (0!), Que avalia a - (1), que, em seguida, avalia a -1.
Se parte de uma expressão é agrupado em parênteses (), depois que parte da expressão é avaliada em primeiro lugar. Por exemplo, na expressão (3 +2) * 5, a + é avaliada em primeiro lugar, dando 5 * 5, o qual, em seguida, avalia a 25. Se os parênteses estão aninhados, os parênteses mais internos são avaliadas primeiro.
Precedência do operador é basicamente o mesmo que em C. A lista completa de precedência do operador, do maior para o menor, é o seguinte: Operador (s) Precedência de Nível
! ~ - (Operadores unários) Maior
**
* /%
+ -
>> = << =
=! = Intervalos
: =
&
^
|
&&
^ ^
| | Menor

Os programadores são incentivados a parenthesize como necessário para manter a clareza. Caso contrário, erros devido a mal-entendidos sutil de precedência do operador são quase garantida.

Expression syntax
Basicamente, qualquer expressão aritmética normal é permitido. Além disso, uma vez que os operadores relacionais (>, <=, etc) são vistos como retornando inteiros, é possível operar em seus valores de retorno, dando algumas expressões de aparência incomum, como
1.0 = (2 = (1> 0) +! (0 <1))
A 1> 0 prazo avalia a 1, eo 0 <um prazo avalia a 0. Daí! (0 <1) avalia a 1, então a expressão simplifica para
1.0 = (2 = 1 + 1)
Uma vez que 2 = 1 + 1, a expressão nos parênteses avalia a 1, então a expressão simplifica ainda mais (após conversão de tipo) para
1,0 = 1,0

que avalia a 1 (int), uma vez que a igualdade se mantém.
A restrição notável na sintaxe da expressão é que os operadores de intervalo só estão autorizados a aparecer no lado mais à direita de uma expressão. Se parte de uma expressão está entre parênteses, essa parte é considerada uma subexpressão, e um intervalo é permitida a aparecer no lado direito da subexpressão. Assim, o que se segue é uma expressão bem formada, que avalia a 0:

(1 = [0,2]) = (0,1)
Mas o que se segue não é bem formado:
1 = [0,2] = (0,1)

Além disso, há outros que = ou! = Símbolos de operadores podem aparecer antes de um intervalo. Então, uma expressão como 5> [0,2], ou 4 + [1,4), não é permitido.
Na lista de parâmetros separados por vírgulas, como os argumentos para alguns gatilhos função do tipo ou parâmetros para controladores do Estado, cada expressão na lista é considerada uma subexpressão separado e, portanto, os intervalos podem aparecer no final dos subexpressions.

Condition- and function-type triggers
Por razões históricas, duas construções distintas são ambos chamados "gatilhos". O primeiro é o que poderia ser mais apropriadamente chamado de um tipo de condição de disparo, eo segundo é o que pode ser mais apropriadamente chamado de uma função do tipo gatilho. Por exemplo, no sistema nervoso central, um controlador de estado típica pode parecer

[State 1234, 5]
type = ChangeState
trigger1 = time = 0
valor = 0

Toda a linha "trigger1 = time = 0" é um tipo de condição de disparo. Se o "tempo = 0" expressão avaliada como um valor diferente de zero, então o controlador ChangeState é executado. Se o "tempo = 0" expressão é avaliada como zero, então o controlador ChangeState não é executado. Assim, se a condição é igual a zero ou diferente de zero afeta se o controlador é acionado.

Por outro lado, a palavra "tempo" que aparece na expressão é uma função do tipo de gatilho. Ele retorna um valor, ou seja, a quantidade de tempo que o jogador tenha sido no estado de 1234. Note-se que uma função do tipo gatilho não "gatilho" nada. Ele apenas dá um valor que pode ser executado dentro da expressão.
Para ilustrar ainda mais a diferença, vamos considerar um controlador de estado diferente:
[State 1234, 5]
type = VARSET
trigger1 = 1
v = 0
valor = tempo + 5

Note-se que o tipo de condição de disparo "trigger1 = 1" agora não contém nenhum tipo de função ativa dentro dele. Uma vez que a expressão "1" sempre avalia a 1, o controlador será acionado cada frame. Para determinar o valor a ser atribuído var0, a expressão "tempo + 5" é avaliada. O gatilho função do tipo "time" retorna statetime do jogador. Em seguida, é adicionado 5 e o resultado é armazenado na var0.
Uma lista completa de função do tipo disparadores podem ser encontrados em trigger.html.
Em geral, qual dos dois tipos de gatilho se quer dizer é claro a partir do contexto. Onde há uma certa ambiguidade, serão utilizados os termos "do tipo condição de gatilho" e "função do tipo gatilho".

Trigger redirection
No exemplo acima, o tempo de disparo retornado a statetime do jogador. Mas, às vezes, pode querer verificar o statetime da meta do jogador, ou o pai do jogador (se o jogador é um auxiliar), etc Isso pode ser feito precedendo o nome do gatilho por uma palavra-chave que indica cujas informações devem ser devolvidos. Este processo é conhecido como o redirecionamento do gatilho. Por exemplo, a
5 + (progenitor, tempo)
retorna 5 + statetime do pai do jogador.
A lista completa das palavras-chave de redirecionamento é o seguinte:


Parent
Redireciona o gatilho para o pai do jogador. (O jogador deve ser um ajudante.)

root
Redireciona o gatilho para a raiz.

Helper
Redireciona o gatilho para o primeiro ajudante encontrado. Veja o gatilho relacionado "NumHelper" na documentação do gatilho.

Helper (ID)
ID deve ser uma expressão bem formada que é avaliada como um inteiro positivo. O gatilho é então redirecionado para um ajudante com o número de identificação correspondente.

target
Redireciona o gatilho para o primeiro alvo encontrado.

target (ID)
ID deve ser uma expressão bem formada que é avaliada como um inteiro não negativo. O gatilho é então redirecionado para um alvo com o targetID correspondente. O targetID é especificado no parâmetro "ID" de um controlador HitDef.

partner
Redireciona o gatilho para o parceiro do jogador. Ajudantes normais e jogadores neutros não são considerados adversários. Veja o gatilho relacionado "numpartner" na documentação do gatilho.

enemy
Redireciona o gatilho para o primeiro adversário encontrado. Ajudantes normais e jogadores neutros não são considerados adversários. Veja o gatilho relacionado "numenemy" na documentação do gatilho.

enemy (n)
n deve ser uma expressão bem formada que é avaliada como um inteiro não negativo. O gatilho é redirecionado para o adversário n'th.

enemyNear
Redireciona o gatilho para o adversário mais próximo.

enemyNear (n)
n deve ser uma expressão bem formada que é avaliada como um inteiro não negativo. O gatilho é redirecionado para o adversário n'th-mais próxima.

playerid (ID)
n deve ser uma expressão bem formada que é avaliada como um inteiro não negativo. O gatilho é redirecionado para o jogador com identificação única igual a ID. Veja o "ID" e "PlayerExistID" dispara na documentação do gatilho.
Se o gatilho é redirecionado para um destino inválido (por exemplo, se for redirecionada para um ajudante quando não existe nenhuma), então inferior é devolvido.
Nota: redirecionamento recursivo (por exemplo, "root, alvo, tempo") não é suportado.

Bottom
Existem várias fontes de erro irrecuperável em expressões. Por exemplo, pode-se tentar dividir por 0, avaliar a raiz quadrada de um número negativo, ou tentar redirecionar um gatilho para um destino inexistente. Nestas situações, a parte inferior é utilizada como um meio para completar a avaliação da expressão normalmente. Se inferior aparece em qualquer lugar em uma expressão (com duas exceções a ser observado abaixo: ver Formas Especiais), então o valor de toda a expressão torna-se inferior. Por exemplo, considere a expressão:
5 + fvar (0) 0,5 **
Se fvar (0) fosse igual a -1, no momento presente foi avaliado, então a expressão se tornaria 5 + inferior, obtendo-se inferior.
-Tipo de condição gatilhos considerar baixo para ser 0. Assim, uma expressão que gera um erro nunca irá causar um gatilho para disparar. Assim, por exemplo, em
type = ChangeState
trigger1 = ajudante, statetype = A
valor = 0

o controlador ChangeState nunca seria executado se não ajudantes existiu, porque a expressão "ajudante, statetype = A" iria avaliar a fundo, que é 0.
Normalmente, um aviso é impresso para o console de depuração do MUGEN quando inferior é gerado. Isso ocorre porque a presença de fundo indica um possível erro ou ambiguidade na lógica. Por exemplo, no exemplo acima ChangeState, se não existem ajudantes, então o "ajudante, statetype = A" declaração é vácua, e não é claro se isto deve ser considerado como sendo verdadeiras ou falsas.

Formas Especiais
O IfElse e Cond desencadeia alça inferior de uma maneira especial. Ambos desencadeia assumir a forma:
<trigger_name> (<exp_cond>, <exp_true>, <exp_false>)
<exp_cond> é uma expressão de condição que, dependendo se for diferente de zero, que os controles de <exp_true> ou <exp_false> fica devolvidos. Se o fundo é produzido na expressão que não é retornado, então não se propaga para o resto da expressão. Por exemplo, considere o IfElse expressão (tempo> 0, 1.0/time, 2)). Se o tempo de> 0, então o valor da expressão é 1.0/time, que é um valor flutuante válido. Se o tempo = 0, então o valor da expressão é 2, mesmo que a ramificação não utilizada divide por 0 e, portanto, produz inferior.
No entanto, embora o gatilho IfElse acima nunca retorna fundo, ele ainda tem uma característica irritante: a divisão por 0 ainda gera um aviso para a saída de depuração. Isso ocorre porque IfElse avalia todos os seus argumentos, mesmo os não utilizados. Em contraste, Cond só vai avaliar os argumentos que ele realmente usa. Assim, se nós reescrevemos nossa expressão como Cond (tempo> 0, 1.0/time, 2), o argumento 1.0/time nunca se avaliado quando o tempo é 0 e, portanto, nenhum aviso será gerada.
Você pode se perguntar quando usar Cond contra IfElse. A resposta é que quase sempre você quer usar Cond, a menos que uma das <exp_true> ou <exp_false> tem um efeito colateral que você precisa. Em outras palavras, se você estiver fazendo uma atribuição de variável dentro de um dos ramos que sempre precisa ser executado, independentemente do valor da <exp_cond>, então você precisa usar IfElse. Caso contrário, você deve usar Cond, especialmente para fins de isolamento inferior.

Avoiding warnings
Várias condições de erro comuns, muitas vezes produzir uma enxurrada de avisos em caracteres. Aqui estão alguns dos cenários mais comuns e como evitá-los.

Coerção de carros alegóricos para ints (Coercion of floats to ints)
Se MUGEN espera um int em algum lugar (por exemplo, um número var), mas um float é fornecido, então MUGEN irá converter o int a um float. No entanto, ele vai reclamar, porque isso pode representar um erro de sua parte. Para se livrar do alerta, indica que você sabe o que está fazendo, fornecendo uma conversão explícita para int com floor () ou ceil ().

Metas de redirecionamento gatilho inexistentes (Goals redirection trigger nonexistent)
Se você redirecionar a um alvo que não existe, como um ajudante quando você não tem um, então inferior é produzido e um aviso é registrado. Isto é porque a expressão é logicamente ambígua. Você pode evitar o aviso de verificação de existência do alvo antes de redirecionar. Então,
trigger1 = helper (1234), o tempo de> 20
geraria um aviso se ajudante 1234 não existia, mas
trigger1 = numhelper (1234)> 0
trigger1 = helper (1234), o tempo de> 20
não o faria. Isso ocorre porque a primeira linha trigger1 faz avaliação a ser abortada antes de tentar o redirecionamento.

Alternativamente, você pode usar o gatilho Cond isolar código que pode potencialmente produzir um aviso. Suponha que nós queríamos uma expressão que dá vida helper (1234) 's, se existir, ou a vida de outra forma do jogador. Então podemos escrever
Cond (numhelper (1234)> 0, (helper (1234), a vida), a vida)
(Os parênteses extras em torno helper (1234), não são obrigados a vida, mas melhorar a legibilidade.)

Falta necessários animações / sprites  (Lack necessary animations / sprites)
Isto não é um problema de expressões. Adicione as animações / sprites!

Expressions in trigger arguments
A maioria dos gatilhos função do tipo ou tomar nenhum argumento ou ter argumentos em uma lista de parâmetros. Por exemplo, o tempo de disparo não tem argumentos, enquanto o gatilho ifelse recebe três argumentos
ifelse (exp1, exp2, exp3)
onde exp1, exp2 e exp3 são todas as expressões válidas. Neste tipo de situação, exp1, exp2, e todos são considerados exp3 subexpressions separadas, assim intervalos podem aparecer na extremidade mais à direita de cada um destes subexpressions. A ordem de avaliação das listas de parâmetros é da esquerda para a direita.
Devido à sintaxe irregular, alguns gatilhos antigos função do tipo não pode ter expressões como seus argumentos. Por este motivo, eles não podem ser integradas expressões na maneira padrão. Para gatilhos fora do padrão deste tipo, os gatilhos só podem aparecer com certos conjuntos de operadores e argumentos (que estão descritos no trigger.doc). Em particular, esses gatilhos não podem tomar expressões como seus argumentos. Por exemplo, a
trigger1 = AnimElem = (1 1)
é uma expressão válida.

Função do tipo gatilhos de estilo antigo aparecem apenas em "cláusulas" da forma "gatilho, operador relacional, o argumento". Essas cláusulas são tratados como uma única unidade (especificamente, um único gatilho nullary), para efeitos de avaliação da expressão. Isto significa, entre outras coisas, que o conceito de precedência do operador não é aplicável aos operadores que aparecem dentro de uma cláusula gatilho função do tipo de estilo antigo. Por exemplo, em
trigger1 = AnimElem = 5 + 4
a expressão é dividido em três unidades:
 AnimElem = 5 + 4
| __________ | | _ | | _ |
O "AnimElem = 5" unidade é tratado como o nome de um gatilho nullary, daí o operador + não tem precedência sobre a = aparecendo dentro do nome "AnimElem = 5". Em outras palavras, essa expressão significa algo como "Executar o gatilho chamado" AnimElem = 5 ', em seguida, adicione 4 ao resultado. "
Alguns função do tipo gatilhos de estilo antigo tem substitutos expressão capazes. Estes são como se segue:
AnimElem, substituído pelo AnimElemTime
TimeMod, substituído pelo operador%
ProjHit, ProjContact, ProjGuarded; substituído por ProjHitTime, ProjContactTime e ProjGuardedTime
Para a lista completa dos gatilhos irregulares, consulte trigger.html. Gatilhos irregulares são marcadas com ***.

Expressions for the controller parameters and state
Para a maior parte, o parâmetro para o StateDef ou um controlador de estado pode ser uma expressão. As exceções são os parâmetros que são dadas como strings. Por exemplo, os atributos de sucesso, guardflags, etc, não podem ser especificados como expressões. Além disso, os parâmetros ignorehitpause e persistente (em todos os controladores) são irregulares na medida em que eles não podem tirar expressões.
Parâmetros do controlador do Estado são avaliados no momento em que o controlador é acionado, e não são posteriormente reavaliado, a menos que o controlador é acionado novamente. Parâmetros que são dadas como listas separadas por vírgulas são avaliados da esquerda para a direita. Para alcançar a avaliação contínua de parâmetros do controlador, o controlador deve ser continuamente acionado.
No caso de certos controladores como HitDef, não é sempre aconselhável o uso contínuo de disparo, uma vez que este diminui o desempenho e também pode levar a um comportamento indesejável. Neste caso, o programador pode querer tentar atrasar o desencadeamento HitDef tanto tempo quanto possível, de forma a avaliar os parâmetros HitDef direita, antes de serem usados.

Organizing for efficiency
Manipulação de expressão não faz computadores modernos fiscais, de modo a legibilidade do seu código é mais importante que a micro-otimização de expressões. No entanto, após algumas boas práticas irá aumentar a eficiência sem prejudicar a clareza.
MUGEN avalia-tipo de condição gatilhos para um controlador de estado na seguinte ordem: Primeiro ele avalia triggeralls, de cima para baixo. Se algum dos triggeralls avalia a 0, o resto dos gatilhos são ignorados e avaliação prossegue para o próximo controlador. Se todos os triggeralls avaliar a zero, então o motor começa a avaliar trigger1 de, de cima para baixo. Se alguma destas avaliar a 0, então salta de avaliação para o primeiro trigger2, e assim por diante. Se todos os gatilhos em um bloco (além triggerall) avaliar a zero, então os parâmetros do controlador estaduais são avaliados eo controlador é acionado.
Em outras palavras, a avaliação lógica de gatilhos é curto-circuitado. No C-como notação, esta configuração pode ser denotado
triggerall, 1 && triggerall, 2 && ... && ((Trigger1, 1 && trigger1, 2
  && ...) | | (Trigger2, 1 && trigger2, 2 && ...) | | ... )
em que (por exemplo) trigger1, 2 indica a segunda linha trigger1; trigger2, 1 indica a primeira linha trigger2; etc A avaliação lógica deste grupo gatilho, então, seria um curto-circuito como em C.
Devido a este sistema, os ganhos de eficiência consideráveis ​​pode ser alcançado através da organização de expressões de modo que os gatilhos do tipo de condição são tão simples e tão poucos em número, quanto possível. A maior parte do "trabalho" pode ser transferida para os parâmetros do controlador do Estado, que são avaliados apenas uma vez no tempo de disparo, em vez de todos os quadros que o jogador está no estado. Por exemplo, a

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = potência <1000
valor = 3000

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = potência> = 1000
valor = 3001

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = potência> = 2000
valor = 3002

poderia ser mais compacta expressa como

[State -1]
type = ChangeState
trigger1 = command = "a"
valor = 3,000 + (power> = 1000) + (power> = 2000)

Você também pode ajudar o motor fora, colocando triggeralls que têm mais probabilidade de ser falso, na parte superior do bloco triggerall. Da mesma forma, o bloco deverá ser trigger1 o bloco mais provável provocar, mas dentro do bloco trigger1 si, os gatilhos que são mais propensos a avaliar a 0 deve ser colocado mais alto. Para os controladores do estado com muitos gatilhos que contenham condições duplicados, pode ser melhor para quebrar os controladores em dois blocos separados, cada um com seu próprio conjunto de triggeralls.
Se você tiver uma condição complexa que está sendo usado como a condição de disparo para muitos controladores estaduais consecutivos, você pode optar por salvar o valor da condição em uma variável, então use essa variável como um gatilho para os controladores subseqüentes.

Por exemplo, a trigger1 = (comando = "ABC" && comando = "holddown" && potência> = 1000!) | |
           (! Comando = "ABC" && comando = "holddown" && var (5)) | |
           ((Command = "abc" |! | Command = "holddown") && potência> = 2000)

pode ser escrita como (assumindo var (0) está disponível):
trigger1 = (var (0): = (comando = "ABC" && comando = "holddown") && poder> =
         1000) | | (VAR (0) && var (5)) | | (! Var (0) && poder> = 2000)
Aqui, você deve equilibrar o ganho de legibilidade de factoring fora subexpressões comuns contra a perda de legibilidade usando o operador: =.


0 comentários:

Postar um comentário

Mapa