Entrar
Últimos assuntos
» player não consegue andarpor lovn7 Qui 21 Nov 2024, 13:33
» É possível fazer istó no game maker
por William Lima Qui 21 Nov 2024, 10:56
» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por Lua Sáb 16 Nov 2024, 20:22
» (Resolvido) Cenario longo x Texture Pages
por josuedemoraes Sáb 16 Nov 2024, 15:31
» Kids' band
por Adilson Lucindo Santos Sex 15 Nov 2024, 12:23
» (RESOLVIDO) Engasgos-Troca de Sprites/animações
por josuedemoraes Ter 12 Nov 2024, 01:49
» Block Room - DEMO
por Joton Qua 06 Nov 2024, 22:58
» Game Infinito vertical (subindo)
por macmilam Sáb 26 Out 2024, 12:36
» Retorno da GMBR!!!
por Dancity Ter 22 Out 2024, 16:36
» Máquina de estados
por aminaro Qui 10 Out 2024, 13:33
» como faço pra um objeto colidir com o outro e diminuir a vida do player ?
por josuedemoraes Qui 03 Out 2024, 16:51
» RESOLVIDO: Colisão com objetos moveis
por josuedemoraes Qua 02 Out 2024, 20:28
» Crypt of the Blood Moon
por divin sphere Qua 11 Set 2024, 18:18
» como fazer um objeto seguir?
por divin sphere Dom 18 Ago 2024, 18:08
» Procuro de alguém para Modelar/Texturizar/Animar objetos 3D
por un00brn Dom 11 Ago 2024, 11:10
» Destruição de cenário (estilo DD Tank)
por CoronelZeg Sex 09 Ago 2024, 17:16
» RESOLVIDO-Como destruir uma instancia especifica de um objeto
por josuedemoraes Ter 23 Jul 2024, 00:40
» Automatizar a coleta de id
por GabrielXavier Seg 22 Jul 2024, 18:01
» Preciso de ajuda para concluir um pequeno projeto
por lmoura Qui 27 Jun 2024, 15:45
» ANGULO ACOMPANHAR O OBJETO
por Klinton Rodrigues Qui 27 Jun 2024, 08:34
» Musica reinicia quando sala reinicia
por GabrielXavier Ter 18 Jun 2024, 07:28
» como fazer uma copia de gd
por generico_cube Sex 14 Jun 2024, 15:48
» Square Adventure
por guilherme551 Ter 11 Jun 2024, 09:54
» como posso definir limite de uma variavel
por GabrielXavier Sex 07 Jun 2024, 14:14
» [Resolvido] Dúvida, colisão única de objeto
por vdm842 Sex 24 maio 2024, 09:50
[Tutorial] Máquina de estados finitos
+6
Kabeção
MatheusReis
Markituh
dharrison
vinians
saim
10 participantes
Página 1 de 1
[Tutorial] Máquina de estados finitos
Nome: Máquina de estados Finitos (Finite State Machines)
Descrição: Pretendo traduzir, aqui, um tutorial que uso com freqüência e notei que não tem correlato aqui na comunidade. O tutorial não é meu, só estou traduzindo. Créditos devem ir para o Ace, de outra comunidade.
O original pode ser encontrado aqui (pode ser necessário cadastrar).
Tenho muitos comentários a fazer, porém o tutorial é extenso e cheio de suspense antes da apresentação do script, então pode ficar chato ler uma introdução antes da introdução original.
Embora o tutorial não seja meu, me disponho a esclarecer qualquer dúvida com relação a ele.
Nível de dificuldade: intermediário/avançado
Requerimentos: Uso GM8, deve funcionar em GM7. Lite (apesar do exemplo no final requerer pro).
Desenvolvimento:
Introdução à máquina de estados finitos:
O que é uma “máquina de estados finitos”, você pergunta?
Bem, é exatamente o que parece. Uma “máquina” (ou sistema) que permite que algo “exista” num estado “finito” (singular).
Provavelmente, você está se perguntando qual a utilidade disso.A verdade é que serve pra tudo! Na verdade, muitos, se não TODOS os jogos desenvolvidos profissionalmente por grandes estúdios usam essas máquinas. Por quê? Porque são simples, modulares e muito eficientes de se usar para programadores de jogos profissionais e novatos.
Designers de jogos vêm de todos os cantos do mundo e, mesmo aqueles com experiência em programação tendem a não conhecer todos os aspectos do hardware e/ou linguagem que estão usando no projeto atual, então o design mais acurado é tipicamente deixado para os programadores, não para o designer. Então como traduzir “eu quero que esse cara ande 3 pixels e pule quando chegar perto de uma parede e fique lá, numa pose bacana se ele conseguir ou fique triste quando aterrissar” para um programador bitolado cujos olhos estão velados pelas intrincações da programação?
Máquina de estados Finitos.
Quer dizer, você diz ao programador exatamente o que deve acontecer enquanto em cada estado de uma ação geral (normalmente arbritária) e explica exatamente como cada estado deve se relacionar com o outro. Em suma, sem um pseudocódigo desse tipo, a explicação cai em ouvidos moucos.
Na verdade, com o game maker, nós somos normalmente o designer e o programador ao mesmo tempo. Entretanto, nós ainda temos que fazer nossos jogos sob o ponto de vista do designer, quer nós saibamos como programar tudo ou não. E essa é a beleza das MEF. Elas permitem a um artista fazer o trabalho de um programador com pouco a nenhum conhecimento de programação. Entretanto, com Game Meker, nós simplesmente colocamos um pouco de código num estado que serve de parte de uma máquina de estados finitos e isso funciona! Porque o Game Maker faz o trabalho de programação por nós e nós damos a ele o pseudocódigo (mais ou menos) com GML para fazê-lo entender o que nós queremos.
A diferença entre usar a Máquina de estados finitos e usar o velho método com declarações “IF” surge quando você percebe que se tornou o “programador” ao invés do designer em algum ponto. E, quando você tenta voltar a ser o designer, fica muito difícil devido às diferenças nos pensamentos envolvidos. O método do designer é criativo, enquanto o método do programador é técnico e eficiente. Você acaba digitando, linha por linha, um design que quer criar. Mas, por mais que criatividade seja ótima, raramente é eficiente. Enquanto o método “linha-por-linha” possa ser criativo a princípio e te permite ver resultados imediatos, ele não é eficiente. A falta de eficiência cresce exponencialmente a cada linha que você acrescenta, eventualmente levando a códigos misteriosos com bugs invisíveis (de tão complexos que eles ficam) e tornando-se tão ineficiente ao rodar se você continuar programando assim que acabará tirando sua possibilidade até de CRIAR. Você termina tentando ser “programador” e “designer” ao mesmo tempo e acaba falhando em ambos simplesmente porque não usou a vantagens de nunehum. Aí, você experimenta aquela (tão) familiar experiência de jogo abandonado e eu, pelo menos, estou REALMENTE cansado de ver isso. Tantos projetos fantásticos indo pro lixo por causa disso! Estou aqui para fazer o meu melhor para prevenir que isso aconteça contigo!
Se levar esse artigo a sério, você não irá querer de programar seus jogos. Afinal, o foco é fazer jogos com facilidade! E, em Game Maker, isso não é difícil de jeito nenhum! Tudo que você precisa é de um bom e funcional método de programação. E isso, meus bons leitores, é o que vou ensinar agora mesmo! Continuemos com o show!
Vamos falar sobre estados:
Contrariamente ao conhecimento popular, um estado é simplesmente “como” um objeto ou entidade existe. Quer dizer, simplesmente mudar uma variável para estado=”algo” e checar isso com uma declaração “if” NÃO é como um estado funciona.
Infelizmente, jogos ainda são programados dessa forma com Game Maker. Sempre foram e provavelmente sempre serão. Infelizmente, isso deixa seu jogo MUITO MUITO complicado quando você tem muitos tipos de estado e muitos tipos de física que podem mudar ou não mudar dependendo de como está aquilo que você chamou de “estado” do seu objeto. Por isso as pessoas, às vezes, precisam de muitos objetos para fazer coisas complexas quando essas ações poderiam ser feitas com muito mais facilidade (e eficiência!) com um único objeto numa máquina de estados.
Como expliquei antes, um estado é “como” um objeto existe. Quer dizer, ele normalmente tem um certo sprite e um certo tipo de física apicado a ele enquanto está naquele estado. Entretanto, um objeto típico não existe sempre num estado. É aí que a “máquina de estados finitos” vem a calhar. Ela permite que um objeto transite entre esses estados. Em suma, ela permite que um objeto exista de várias formas diferentes, mas de uma só forma de cada vez. Cada estado pode transitar por vários outros estados ou apenas para um outro e então permanecer assim, pelo tempo que quiser, existindo assim das formas que quiser. Isso permite um fluxo orgânico para a programação do objeto que o Game Maker, por alguma razão, simplesmente não traz consigo.
Um exemplo do OUTRO método:
Irei programar, agora, um objeto que tem alguns mutuamente excludentes falsos “estados”, como os chamarei de agora pra frente. Seu comportamento é ficar parado por 10 steps, mostrando um sprite de espera, depois mostra um sprite de preparação por mais 5 steps, então anda 3 pixels enquanto mostra um sprite de caminhar e, se ele bate numa parede, mostra um sprite de pancada e volta 3 pixels, caso contrário, fica numa posição de vitória por mais 10 steps e faz tudo de novo. Pra evitar o uso de alarmes, farei tudo no evento step e assumirei que todas as variáveis usadas foram inicializadas no create event (mais trabalho, por sinal). “Ah, mas isso é mole”, você diz? Bem, vejamos quão fácil é... (e, cá pra nós, se você é novo em GML, sinta-se livre pra ignorar esse código, apenas repare no tamanho e complexidade).
Nossa, que trem feio! Imagine se eu fosse incluir pro cara OUTROS comportamentos, como caminhar e pular do modo normal, ou ser acertado por um inimigo? Tudo o que queríamos era fazer o sujeito caminhar um pouco e rebater se desse de cara com uma parede ou ficar numa pose vitoriosa se não batesse. Aposto que você pensou que “fácil desenvolvimento de jogos” fosse a filosofia de nosso amado game maker. Por que diabos uma coisinha dessas ficou tão difícil?? Imagine só, programar um moderno jogo de lutas desse jeito!
Bem, estou aqui pra te dizer que não é o game maker que é muito difícil, mas você simplesmente não está usando ele com todas as suas capacidades, ainda. Na verdade, programar algo assim pode facilmente ser MUITO MENOS demorado e, por conseqüência, muito menos susceptível a erros, quando usada uma simples, mas infinitamente útil, técnica conhecida como “máquina de estados finitos”.
Como efeito colateral, seu código pode até se tornar algo que bons programadores chamam de “modular”.
O que é essa criatura, “modular”, você pergunta? Bem, é simplesmente dizer que, diferente do código anterior, nada é duramente codificado(1). Seu código pode ser reusado em outros lugares. Programe o comportamento de um inimigo através de estados, por exemplo, e simplesmente adicione sprites, entrada de controles ou entrada de IA num estado de inicialização a seu gosto para permitir controlar o comportamento e simplesmente inicializar os sprites usados numa base de objeto-por-jogo, talvez no create event.
Criar um jogo complexo não tem que ser difícil! Basta você pensar em termos modulares. Ou seja, em nosso caso, cada estado (ou parte de um estado) deve ser observado como um comportamento e, como tal, esses podem ser facilmente reutilizados. Mas eu provavelmente tenho que te ensinar, primeiro, como programar esses comportamentos, certo? Então vamos lá!
USANDO a máquina de estados finitos:
Ok, agora a diversão! Vou te mostrar algo MUITO mais fácil! Entretanto, antes de CRIAR nossos comportamentos, precisamos aprender a USÁ-LOS. Entretanto, para usá-los, você precisa de um script para a “máquina de estados finitos”. Ele entra no step event com outro índice de script passado como argumento que será nosso primeiro estado. Ele tem a forma:
Primeiramente, antes de intrar na programação de nossos estados, você precisará saber alguns comandos básicos e variáveis locais para poder usar o script st_maquina. Eles devem ser definidos como constantes, se você tiver problemas em usá-los em conjunto com as variáveis. Eu mostro depois, pra evitar confusão.
Vamos começar com os comandos:
estado_continua
estado_repete
estado_proximo
estado_proximo_agora
Eles têm a forma “return(tipo_de_transição)” onde tipo_de_transição é um dos quatro tipos de transição entre estados. Eles são todos que você vai precisar, não importa o que faça num estado. O terceiro é um pouco especial, então voltaremos a ele num minuto.
estado_continua simplesmente continua num estado em que já estamos, no próximo step (ele roda o código do script atual de novo, mas permite ao game maker continuar fazendo o resto das coisas que ele tem que fazer nesse step). Por outro lado, estado_repete vai continuar repetindo esse estado constantemente até que se mande parar, efetivamente fazendo dele o equivalente ao loop “while”. Durante esse tempo, nada mais acontece fora do script, então seu jogo pode congelar se você não sair em algum ponto.
estado_proximo e estado_proximo_agora são um pouco diferentes dos outros dois porque eles requerem a declaração de uma variável antes que eles possam ser chamados. Essa variável, embora possa parecer confusa a princípio, simplesmente recebe o índice do script a ser chamado para ser o próximo estado e, portanto, será chamada de “proximo_estado”.
Quando transitando de um estado para outro, você simplesmente escreve:
Finalmente vou mostrar as variáveis. Diferente das constantes que retornamos, essas podem ser mudadas.
tempo_no_estado
proximo_estado
indice_do_estado
A primeira é incrivelmente útil. Ela cresce em uma unidade a cada step, enquanto você permanecer nele, mas se você mudar de estado, ela magicamente se reseta também. Porém, se você quiser algo ocorrendo em intervalos, você pode fazer acontecer e resetar a variável manualmente toda vez que ela chegar num determinado valor. Isso não terá impacto algum no funcionamento da maquina de estados, então use e abuse.
Como já foi explicado o que “proximo_estado” faz, só queria lembrar de criar uma constante a ser usada nos valores de transição se você tender a confundir proximo_estado e “estado_proximo”. Isso facilitará algumas coisas.
Finalmente, indice_do_estado é uma especial. Eu deixei pro final porque quero que você esqueça que ela existe. Na verdade, ela é bem útil... nas mãos de quem sabe o que está fazendo.
Essa é uma forma alternativa de programar transições entre estados. Você pode mudar um estado diretamente usando essa variável. Pode ser útil se você quiser sair de um estado instantaneamente se o usuário aperta uma tecla, por exemplo, e você quer usar os eventos do game maker. De outra forma, você simplesmente declarará “proximo_estado” naquele evento-chave e usar um script que roda algum código e usa “return(proximo_estado)” a cada step se você ainda quiser usar transições e os eventos de entrada do game maker. Entretanto, tenho certeza que será mais fácil usar os códigos de entrada universais enquanto dentro de um estado de modo a checar por todos pressionamentos de botão a menos que você queira usar códigos complicados(2) para determinar que botões um jogador pode usar (o que, na minha opinião, não é uma boa idéia).
De qualquer forma, se você não entendeu o último parágrafo, sinta-se livre para relê-lo até entender ou esquecer que essa última variável sequer existe e se livrar de algumas dores de cabeça. Ela só existe para pessoas que querem muita flexibilidade de programação, como eu.
Por último, tem os argumentos. É sempre útil usar argumentos entre os estados, porém eu não faço muito uso deles, pessoalmente. Se for necessário, eles estão definitivamente lá. Apresentam-se da forma:
arg0
arg1
arg2
Essas são variáveis que podem ser declaradas e des-declaradas à vontade. Eu não as retorno a zero, então você terá que fazer isso manualmente após passá-las a outro script. Apenas garanta que você as ajeitou antes de passá-las. De outra forma, elas sempre serão ou zero ou o valor que você as declarou.
O método “máquina de estados finitos”:
Finalmente, vamos mostrar o que aprendemos a fazer algumas transições. POR FAVOR, seja mais fácil que da última vez! Eu não quero programar daquele jeito NUNCA MAIS.
Relembrando: o comportamento era ficar num estado de espera por 10 steps, mostrando um sprite “parado”, ficar mais 5 steps mostrando um sprite “preparado”, depois mover 3 pixels enquanto mostra um sprite caminhando e então, se bater numa parede, mostrar um sprite de pancada e voltar 3 pixels e, se não bater, ficar numa pose de vitória por 10 steps e começar de novo.
Precisaremos de apenas 4 estados: st_parado, st_caminhando, st_batido e st_vitoria. Então vamos precisar de 4 scripts. Depois, definimos nosso estado default no script st_maquina como st_parado.
No primeiro script, st_parado, colocamos esse código:
E está pronto! O sujeito vai ficar parado um pouco, entrar num estado de preparação, andar e, se bater numa parede, vai retroceder um pouco, senão, vai fazer uma pose de vitória e começar tudo de novo.
Comentários finais:
Game Maker é uma ferramenta espetacular e parece ter sido desenvolvida com suporte à Máquina de Estados Finitos, embora nunca realmente diga isso. Eu peço urgência para que você aprenda e use bem essa ferramenta, porque, quer você acredite ou não, é o método mais eficiente. Afinal, você sempre pode programar um estado de inicialização de sprite e simplesmente exportar seus scripts de comportamento, permitindo que eles sejam partilhados com outras pessoas de forma que eles os usem em seus jogos! O melhor de tudo é que qualquer outro personagem, inimigo ou aliado, poderia usar a mesma máquina de estados para preparar seus sprites, mas comportar-se diferentemente usando um sistema de transição via entrada de dados, seja por botões ou por alguma IA complicada que emule esses botões.
Por mais estranhos e inúteis que esses estados sejam, meu exemplo ilustra quão rápida e facilmente uma complicada série de ações poderia ser facilitada com uma máquina de estados finitos sem um monte de declarações “IF”. É muito simples programar desse jeito e isso faz programar personagens complicados uma baba.
Aqui eu termino a tradução. Ainda havia mais um parágrafo com link para uma engine que usa essa state machine. No exemplo, havia um jogo do mario, do megaman e outro que não me lembro. Não vou postar re-fazer o exemplo porque é muita coisa pra traduzir. No lugar disso, deixo (acima) o link para o post original, caso você tenha interesse.
Agora, o script que faz tudo o que foi dito acima possível!!!
Criei um exemplo que mostra algumas transições (acabei não pensando numa situação para usar o estado_repete). Por favor, ignorem os possíveis erros de programação e os gráficos, uns "roubados", outros terríveis, e concentrem-se em entender como a máquina funciona.
Eu poderia ter usado menos estados e menos variáveis, bem como códigos mais simples, mas queria mostrar justamente como a máquina torna possível fazer muita coisa, digitar muita coisa, sem enlouquecer.
Aqui o link pra download
Descrição: Pretendo traduzir, aqui, um tutorial que uso com freqüência e notei que não tem correlato aqui na comunidade. O tutorial não é meu, só estou traduzindo. Créditos devem ir para o Ace, de outra comunidade.
O original pode ser encontrado aqui (pode ser necessário cadastrar).
Tenho muitos comentários a fazer, porém o tutorial é extenso e cheio de suspense antes da apresentação do script, então pode ficar chato ler uma introdução antes da introdução original.
Embora o tutorial não seja meu, me disponho a esclarecer qualquer dúvida com relação a ele.
Nível de dificuldade: intermediário/avançado
Requerimentos: Uso GM8, deve funcionar em GM7. Lite (apesar do exemplo no final requerer pro).
Desenvolvimento:
Introdução à máquina de estados finitos:
O que é uma “máquina de estados finitos”, você pergunta?
Bem, é exatamente o que parece. Uma “máquina” (ou sistema) que permite que algo “exista” num estado “finito” (singular).
Provavelmente, você está se perguntando qual a utilidade disso.A verdade é que serve pra tudo! Na verdade, muitos, se não TODOS os jogos desenvolvidos profissionalmente por grandes estúdios usam essas máquinas. Por quê? Porque são simples, modulares e muito eficientes de se usar para programadores de jogos profissionais e novatos.
Designers de jogos vêm de todos os cantos do mundo e, mesmo aqueles com experiência em programação tendem a não conhecer todos os aspectos do hardware e/ou linguagem que estão usando no projeto atual, então o design mais acurado é tipicamente deixado para os programadores, não para o designer. Então como traduzir “eu quero que esse cara ande 3 pixels e pule quando chegar perto de uma parede e fique lá, numa pose bacana se ele conseguir ou fique triste quando aterrissar” para um programador bitolado cujos olhos estão velados pelas intrincações da programação?
Máquina de estados Finitos.
Quer dizer, você diz ao programador exatamente o que deve acontecer enquanto em cada estado de uma ação geral (normalmente arbritária) e explica exatamente como cada estado deve se relacionar com o outro. Em suma, sem um pseudocódigo desse tipo, a explicação cai em ouvidos moucos.
Na verdade, com o game maker, nós somos normalmente o designer e o programador ao mesmo tempo. Entretanto, nós ainda temos que fazer nossos jogos sob o ponto de vista do designer, quer nós saibamos como programar tudo ou não. E essa é a beleza das MEF. Elas permitem a um artista fazer o trabalho de um programador com pouco a nenhum conhecimento de programação. Entretanto, com Game Meker, nós simplesmente colocamos um pouco de código num estado que serve de parte de uma máquina de estados finitos e isso funciona! Porque o Game Maker faz o trabalho de programação por nós e nós damos a ele o pseudocódigo (mais ou menos) com GML para fazê-lo entender o que nós queremos.
A diferença entre usar a Máquina de estados finitos e usar o velho método com declarações “IF” surge quando você percebe que se tornou o “programador” ao invés do designer em algum ponto. E, quando você tenta voltar a ser o designer, fica muito difícil devido às diferenças nos pensamentos envolvidos. O método do designer é criativo, enquanto o método do programador é técnico e eficiente. Você acaba digitando, linha por linha, um design que quer criar. Mas, por mais que criatividade seja ótima, raramente é eficiente. Enquanto o método “linha-por-linha” possa ser criativo a princípio e te permite ver resultados imediatos, ele não é eficiente. A falta de eficiência cresce exponencialmente a cada linha que você acrescenta, eventualmente levando a códigos misteriosos com bugs invisíveis (de tão complexos que eles ficam) e tornando-se tão ineficiente ao rodar se você continuar programando assim que acabará tirando sua possibilidade até de CRIAR. Você termina tentando ser “programador” e “designer” ao mesmo tempo e acaba falhando em ambos simplesmente porque não usou a vantagens de nunehum. Aí, você experimenta aquela (tão) familiar experiência de jogo abandonado e eu, pelo menos, estou REALMENTE cansado de ver isso. Tantos projetos fantásticos indo pro lixo por causa disso! Estou aqui para fazer o meu melhor para prevenir que isso aconteça contigo!
Se levar esse artigo a sério, você não irá querer de programar seus jogos. Afinal, o foco é fazer jogos com facilidade! E, em Game Maker, isso não é difícil de jeito nenhum! Tudo que você precisa é de um bom e funcional método de programação. E isso, meus bons leitores, é o que vou ensinar agora mesmo! Continuemos com o show!
Vamos falar sobre estados:
Contrariamente ao conhecimento popular, um estado é simplesmente “como” um objeto ou entidade existe. Quer dizer, simplesmente mudar uma variável para estado=”algo” e checar isso com uma declaração “if” NÃO é como um estado funciona.
Infelizmente, jogos ainda são programados dessa forma com Game Maker. Sempre foram e provavelmente sempre serão. Infelizmente, isso deixa seu jogo MUITO MUITO complicado quando você tem muitos tipos de estado e muitos tipos de física que podem mudar ou não mudar dependendo de como está aquilo que você chamou de “estado” do seu objeto. Por isso as pessoas, às vezes, precisam de muitos objetos para fazer coisas complexas quando essas ações poderiam ser feitas com muito mais facilidade (e eficiência!) com um único objeto numa máquina de estados.
Como expliquei antes, um estado é “como” um objeto existe. Quer dizer, ele normalmente tem um certo sprite e um certo tipo de física apicado a ele enquanto está naquele estado. Entretanto, um objeto típico não existe sempre num estado. É aí que a “máquina de estados finitos” vem a calhar. Ela permite que um objeto transite entre esses estados. Em suma, ela permite que um objeto exista de várias formas diferentes, mas de uma só forma de cada vez. Cada estado pode transitar por vários outros estados ou apenas para um outro e então permanecer assim, pelo tempo que quiser, existindo assim das formas que quiser. Isso permite um fluxo orgânico para a programação do objeto que o Game Maker, por alguma razão, simplesmente não traz consigo.
Um exemplo do OUTRO método:
Irei programar, agora, um objeto que tem alguns mutuamente excludentes falsos “estados”, como os chamarei de agora pra frente. Seu comportamento é ficar parado por 10 steps, mostrando um sprite de espera, depois mostra um sprite de preparação por mais 5 steps, então anda 3 pixels enquanto mostra um sprite de caminhar e, se ele bate numa parede, mostra um sprite de pancada e volta 3 pixels, caso contrário, fica numa posição de vitória por mais 10 steps e faz tudo de novo. Pra evitar o uso de alarmes, farei tudo no evento step e assumirei que todas as variáveis usadas foram inicializadas no create event (mais trabalho, por sinal). “Ah, mas isso é mole”, você diz? Bem, vejamos quão fácil é... (e, cá pra nós, se você é novo em GML, sinta-se livre pra ignorar esse código, apenas repare no tamanho e complexidade).
- Código:
if estado=="parado" and espera!=10 {
espera += 1
sprite_index = spr_parado
}
if estado=="parado" and espera==10 {
sprite_index = spr_preparado
estado="preparado"
espera = 0
}
if estado=="preparado" and espera<5 {
espera += 1
}
if estado="preparado" and espera==5 {
sprite_index = spr_caminhando
estado = "caminhando"
espera = 0
}
if estado=="caminhando" and espera< 3 and place_meeting(x,y,obj_parede)=false {
x += 1
}
if estado=="caminhando" and espera< 3 and place_meeting(x,y,obj_parede)=true {
sprite_index = spr_pancada
estado = "batido"
espera = 0
}
if estado=="batido" and espera<3 {
x -= 1
espera += 1
}
if estado=="batido" and espera==3 {
sprite_index = spr_parado
estado = "parado"
espera = 0
}
if estado=="caminhando" and espera==3 {
sprite_index = spr_vitoria
estado = "vitoria"
espera = 0
}
if estado=="vitoria" and espera<10 {
espera += 1
}
if estado=="vitoria" and espera==10 {
sprite_index = spr_parado
estado = "parado"
espera = 0
}
Nossa, que trem feio! Imagine se eu fosse incluir pro cara OUTROS comportamentos, como caminhar e pular do modo normal, ou ser acertado por um inimigo? Tudo o que queríamos era fazer o sujeito caminhar um pouco e rebater se desse de cara com uma parede ou ficar numa pose vitoriosa se não batesse. Aposto que você pensou que “fácil desenvolvimento de jogos” fosse a filosofia de nosso amado game maker. Por que diabos uma coisinha dessas ficou tão difícil?? Imagine só, programar um moderno jogo de lutas desse jeito!
Bem, estou aqui pra te dizer que não é o game maker que é muito difícil, mas você simplesmente não está usando ele com todas as suas capacidades, ainda. Na verdade, programar algo assim pode facilmente ser MUITO MENOS demorado e, por conseqüência, muito menos susceptível a erros, quando usada uma simples, mas infinitamente útil, técnica conhecida como “máquina de estados finitos”.
Como efeito colateral, seu código pode até se tornar algo que bons programadores chamam de “modular”.
O que é essa criatura, “modular”, você pergunta? Bem, é simplesmente dizer que, diferente do código anterior, nada é duramente codificado(1). Seu código pode ser reusado em outros lugares. Programe o comportamento de um inimigo através de estados, por exemplo, e simplesmente adicione sprites, entrada de controles ou entrada de IA num estado de inicialização a seu gosto para permitir controlar o comportamento e simplesmente inicializar os sprites usados numa base de objeto-por-jogo, talvez no create event.
Criar um jogo complexo não tem que ser difícil! Basta você pensar em termos modulares. Ou seja, em nosso caso, cada estado (ou parte de um estado) deve ser observado como um comportamento e, como tal, esses podem ser facilmente reutilizados. Mas eu provavelmente tenho que te ensinar, primeiro, como programar esses comportamentos, certo? Então vamos lá!
USANDO a máquina de estados finitos:
Ok, agora a diversão! Vou te mostrar algo MUITO mais fácil! Entretanto, antes de CRIAR nossos comportamentos, precisamos aprender a USÁ-LOS. Entretanto, para usá-los, você precisa de um script para a “máquina de estados finitos”. Ele entra no step event com outro índice de script passado como argumento que será nosso primeiro estado. Ele tem a forma:
- Código:
st_maquina(st_default)
Primeiramente, antes de intrar na programação de nossos estados, você precisará saber alguns comandos básicos e variáveis locais para poder usar o script st_maquina. Eles devem ser definidos como constantes, se você tiver problemas em usá-los em conjunto com as variáveis. Eu mostro depois, pra evitar confusão.
Vamos começar com os comandos:
estado_continua
estado_repete
estado_proximo
estado_proximo_agora
Eles têm a forma “return(tipo_de_transição)” onde tipo_de_transição é um dos quatro tipos de transição entre estados. Eles são todos que você vai precisar, não importa o que faça num estado. O terceiro é um pouco especial, então voltaremos a ele num minuto.
estado_continua simplesmente continua num estado em que já estamos, no próximo step (ele roda o código do script atual de novo, mas permite ao game maker continuar fazendo o resto das coisas que ele tem que fazer nesse step). Por outro lado, estado_repete vai continuar repetindo esse estado constantemente até que se mande parar, efetivamente fazendo dele o equivalente ao loop “while”. Durante esse tempo, nada mais acontece fora do script, então seu jogo pode congelar se você não sair em algum ponto.
estado_proximo e estado_proximo_agora são um pouco diferentes dos outros dois porque eles requerem a declaração de uma variável antes que eles possam ser chamados. Essa variável, embora possa parecer confusa a princípio, simplesmente recebe o índice do script a ser chamado para ser o próximo estado e, portanto, será chamada de “proximo_estado”.
Quando transitando de um estado para outro, você simplesmente escreve:
- Código:
proximo_estado=st_qualquer_coisa
return(proximo_estado)
Finalmente vou mostrar as variáveis. Diferente das constantes que retornamos, essas podem ser mudadas.
tempo_no_estado
proximo_estado
indice_do_estado
A primeira é incrivelmente útil. Ela cresce em uma unidade a cada step, enquanto você permanecer nele, mas se você mudar de estado, ela magicamente se reseta também. Porém, se você quiser algo ocorrendo em intervalos, você pode fazer acontecer e resetar a variável manualmente toda vez que ela chegar num determinado valor. Isso não terá impacto algum no funcionamento da maquina de estados, então use e abuse.
Como já foi explicado o que “proximo_estado” faz, só queria lembrar de criar uma constante a ser usada nos valores de transição se você tender a confundir proximo_estado e “estado_proximo”. Isso facilitará algumas coisas.
Finalmente, indice_do_estado é uma especial. Eu deixei pro final porque quero que você esqueça que ela existe. Na verdade, ela é bem útil... nas mãos de quem sabe o que está fazendo.
Essa é uma forma alternativa de programar transições entre estados. Você pode mudar um estado diretamente usando essa variável. Pode ser útil se você quiser sair de um estado instantaneamente se o usuário aperta uma tecla, por exemplo, e você quer usar os eventos do game maker. De outra forma, você simplesmente declarará “proximo_estado” naquele evento-chave e usar um script que roda algum código e usa “return(proximo_estado)” a cada step se você ainda quiser usar transições e os eventos de entrada do game maker. Entretanto, tenho certeza que será mais fácil usar os códigos de entrada universais enquanto dentro de um estado de modo a checar por todos pressionamentos de botão a menos que você queira usar códigos complicados(2) para determinar que botões um jogador pode usar (o que, na minha opinião, não é uma boa idéia).
De qualquer forma, se você não entendeu o último parágrafo, sinta-se livre para relê-lo até entender ou esquecer que essa última variável sequer existe e se livrar de algumas dores de cabeça. Ela só existe para pessoas que querem muita flexibilidade de programação, como eu.
Por último, tem os argumentos. É sempre útil usar argumentos entre os estados, porém eu não faço muito uso deles, pessoalmente. Se for necessário, eles estão definitivamente lá. Apresentam-se da forma:
arg0
arg1
arg2
Essas são variáveis que podem ser declaradas e des-declaradas à vontade. Eu não as retorno a zero, então você terá que fazer isso manualmente após passá-las a outro script. Apenas garanta que você as ajeitou antes de passá-las. De outra forma, elas sempre serão ou zero ou o valor que você as declarou.
O método “máquina de estados finitos”:
Finalmente, vamos mostrar o que aprendemos a fazer algumas transições. POR FAVOR, seja mais fácil que da última vez! Eu não quero programar daquele jeito NUNCA MAIS.
Relembrando: o comportamento era ficar num estado de espera por 10 steps, mostrando um sprite “parado”, ficar mais 5 steps mostrando um sprite “preparado”, depois mover 3 pixels enquanto mostra um sprite caminhando e então, se bater numa parede, mostrar um sprite de pancada e voltar 3 pixels e, se não bater, ficar numa pose de vitória por 10 steps e começar de novo.
Precisaremos de apenas 4 estados: st_parado, st_caminhando, st_batido e st_vitoria. Então vamos precisar de 4 scripts. Depois, definimos nosso estado default no script st_maquina como st_parado.
No primeiro script, st_parado, colocamos esse código:
- Código:
if (tempo_no_estado == 0 && sprite_index!=spr_preparado)
sprite_index = spr_parado; //define nosso sprite parado
if (tempo_no_estado = 10 and sprite_index!=spr_preparado) {
sprite_index = spr_preparado; //define nosso sprite preparado
tempo_no_estado = 0;
}
if (tempo_no_estado = 5 && sprite_index==spr_preparado) {
proximo_estado = st_caminhando;
return(estado_proximo); //abandona o atual estado, indo para st_caminhando
}
return(estado_continua); //se não aconteceu nada, permanecer aqui
- Código:
if (tempo_no_estado = 0) then sprite_index = spr_caminhando;
if (place_meeting(x+1,y,obj_parede)=true) {
proximo_estado = st_batido; //se batemos em algo,
return(estado_proximo_agora); //nós abandonamos esse estado
}
if (tempo_no_estado < 3) then x+=1; //se ainda estamos nesse estado, vamos em frente e nos movemos
if (tempo_no_estado = 3) { //porém, se terminamos de nos mover, vencemos
proximo_estado = st_vitoria;
return(estado_proximo)
}
//mas, se ainda estivermos caminhando, continuamos tentando caminhar no próximo passo
return(estado_continua);
- Código:
x -= 1;
if (tempo_no_estado < 3) then sprite_index = spr_pancada //sprite de levar a pancada
else {
proximo_estado = st_parado; //ou de ficar parado, se já voltamos o suficiente
return(estado_proximo);
}
return(estado_continua) //senão, simplesmente ficamos aqui por mais alguns steps.
- Código:
sprite_index = spr_vitoria; //muda o sprite para esse estado
if (tempo_no_estado==10) { //se já é hora de parar de fazer pose,
proximo_estado = st_parado;
return(estado_proximo_agora); //nós voltamos ao estado de ficar parado NESSE step
}
return(estado_continua); //se ainda estamos posando, continuamos com a pose.
E está pronto! O sujeito vai ficar parado um pouco, entrar num estado de preparação, andar e, se bater numa parede, vai retroceder um pouco, senão, vai fazer uma pose de vitória e começar tudo de novo.
Comentários finais:
Game Maker é uma ferramenta espetacular e parece ter sido desenvolvida com suporte à Máquina de Estados Finitos, embora nunca realmente diga isso. Eu peço urgência para que você aprenda e use bem essa ferramenta, porque, quer você acredite ou não, é o método mais eficiente. Afinal, você sempre pode programar um estado de inicialização de sprite e simplesmente exportar seus scripts de comportamento, permitindo que eles sejam partilhados com outras pessoas de forma que eles os usem em seus jogos! O melhor de tudo é que qualquer outro personagem, inimigo ou aliado, poderia usar a mesma máquina de estados para preparar seus sprites, mas comportar-se diferentemente usando um sistema de transição via entrada de dados, seja por botões ou por alguma IA complicada que emule esses botões.
Por mais estranhos e inúteis que esses estados sejam, meu exemplo ilustra quão rápida e facilmente uma complicada série de ações poderia ser facilitada com uma máquina de estados finitos sem um monte de declarações “IF”. É muito simples programar desse jeito e isso faz programar personagens complicados uma baba.
(1) hard-coded. Não consegui pensar em tradução adequada.(2) Mais uma vez, hard-code
Aqui eu termino a tradução. Ainda havia mais um parágrafo com link para uma engine que usa essa state machine. No exemplo, havia um jogo do mario, do megaman e outro que não me lembro. Não vou postar re-fazer o exemplo porque é muita coisa pra traduzir. No lugar disso, deixo (acima) o link para o post original, caso você tenha interesse.
Agora, o script que faz tudo o que foi dito acima possível!!!
- Código:
//maquina_de_estados(st_default);
//Chame esse script no evento step para usar a máquina de estados finitos
//[Introdução]
// Máquinas de estado finite são um aforma simples de programar objetos porque
// cada estado é, em essência, um momento no tempo para o objeto. É COMO
// o objeto existe, por assim dizer, (ou se comporta) naquele momento, enquanto em um estado.
// Já que pode haver apenas um estado por vez, cada estado é independente dos outros,
// então apenas a transição entre eles importa. Isso dá uma imensa flexibilidade na
// programação de comportamentos dos objetos, simplesmente porque, não importa
// como eles se comportem, a máquina de estados flui.
// Contanto que você controle esse fluxo, não importa o que ele contenha. Você só precisa
// saber o que está acontecendo agora e onde ele estará quando acabar (se é que estará em
// algum lugar).
//[Notas]
// Um st_script deve detalhar como um objeto está se comportando em um dado ponto do tempo,
// então programe livremente enquanto em um estado. Use input_check() para checar
// a quanto tempo os botões estão sendo apertados durante um estado para saber se o
// estado deve se alterar. Além disso, use a variável “tempo_no_estado” para checar o comprimento
// de tempo (o número de steps) que o objeto está naquele estado.
// Use "proximo_estado = st_script" para indicar qual é o próximo estado. SEMPRE
// retorne (return()) um valor para indicar COMO será a transição para o outro estado (ou se
// quiser apenas repetir o atual). Mude de estado retornando “estado_proximo”
// OU, para entrar num estado no mesmo step, retorne “estado_proximo_agora”
// As ações retornadas e args são o coração de qualquer máquina de estados finitos,
// então use e abuse!!!
//Inicialização
if variable_local_exists("indice_do_estado")==0 {
indice_do_estado = argument0 //estado default state a ser executado (NÃO mude isso diretamente!)
proximo_estado = argument0 //próximo estado a ser executado (use ISSO para mudar estados) tempo_no_estado = 0 //tempo em que estivemos no estado atual
//Argumentos
if variable_local_exists('arg0')=0 arg0 = 0 //Use essas variáveis se quiser passar argumentos para os scritps
if variable_local_exists('arg1')=0 arg1 = 0 //Elas serão limpas apenas quando você mudar para um novo estado
if variable_local_exists('arg2')=0 arg2 = 0
if variable_local_exists('arg3')=0 arg3 = 0
if variable_local_exists('arg4')=0 arg4 = 0
if variable_local_exists('arg5')=0 arg5 = 0
if variable_local_exists('arg6')=0 arg6 = 0
if variable_local_exists('arg7')=0 arg7 = 0
limpa_argumentos = 0 //Mude essa variável para 1 antes de mudar de estado para limpar os args para 0
//Retorna ações (Essas variáveis já são consideradas como definidas como sonstantes nessa máquina)
// estado_proximo_agora = 3 //executa o próximo estado nesse step
// estado_proximo = 0 //execute o próximo estado no próximo step
// estado_continua = 1 //continues nesse estado no próximoa step
// estado_repete = 2 //repete esse estado AINDA NESSE step
}
//Vamos limpar os argumentos
if limpa_argumentos = 1 {
arg0 = 0
arg1 = 0
arg2 = 0
arg3 = 0
arg4 = 0
arg5 = 0
arg6 = 0
arg7 = 0
limpa_argumentos = 0
}
//Processa Transições entre Estados
var prxm;
prxm = script_execute(indice_do_estado,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7)
while(prxm == estado_repete) { //repete estado mas não vai para o próximo step
//Vamos limpar os argumentos, se necessário
if limpa_argumentos = 1 {
arg0 = 0
arg1 = 0
arg2 = 0
arg3 = 0
arg4 = 0
arg5 = 0
arg6 = 0
arg7 = 0
limpa_argumentos = 0
}
prxm = script_execute(indice_do_estado,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
tempo_no_estado += 1;
}
while(prxm == estado_proximo_agora) { //vai para o próximo estado nesse step
indice_do_estado = proximo_estado;
tempo_no_estado = 0;
prxm = script_execute(indice_do_estado,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7)
if prxm = estado_repete
{script_execute(maquina_de_estados); exit;}
//Vamos limpar os argumentos, se necessário
if limpa_argumentos = 1 {
arg0 = 0
arg1 = 0
arg2 = 0
arg3 = 0
arg4 = 0
arg5 = 0
arg6 = 0
arg7 = 0
limpa_argumentos = 0
}
}
if(prxm == estado_proximo) { //muda de estado no próximo step
indice_do_estado = proximo_estado;
tempo_no_estado = 0;
//Vamos limpar os argumentos, se necessário
if limpa_argumentos = 1 {
arg0 = 0
arg1 = 0
arg2 = 0
arg3 = 0
arg4 = 0
arg5 = 0
arg6 = 0
arg7 = 0
limpa_argumentos = 0
}
}
if(prxm == estado_continua) { //Continua nesse estado no próximo step
tempo_no_estado += 1;
}
Criei um exemplo que mostra algumas transições (acabei não pensando numa situação para usar o estado_repete). Por favor, ignorem os possíveis erros de programação e os gráficos, uns "roubados", outros terríveis, e concentrem-se em entender como a máquina funciona.
Eu poderia ter usado menos estados e menos variáveis, bem como códigos mais simples, mas queria mostrar justamente como a máquina torna possível fazer muita coisa, digitar muita coisa, sem enlouquecer.
Aqui o link pra download
Última edição por dharrison em Dom 08 Jan 2017, 01:53, editado 7 vez(es) (Motivo da edição : acréscimo de exemplo)
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Otimo tutorial amigo, uso muito essas máquinas de estado em meus games, inclusive estou usando uma agora no jogo do campeonato. Vai ajudar muita gente que não conhece.
Re: [Tutorial] Máquina de estados finitos
mto legal, eu não conhecia ainda esses métodos
vai ajudar muito, mas tbm parece ser bem complicado (a principio)
vou baixar as engines, mas se vc puder fazer um mini tudo ensinando como usar e criar os estados passo a passo (só um aprofundamento) seria bom tbm
abração cara
parabens pelo tuto
esse merece ser Fixo xD
vai ajudar muito, mas tbm parece ser bem complicado (a principio)
vou baixar as engines, mas se vc puder fazer um mini tudo ensinando como usar e criar os estados passo a passo (só um aprofundamento) seria bom tbm
abração cara
parabens pelo tuto
esse merece ser Fixo xD
dharrison- Games Ranking :
Notas recebidas : A - B
Data de inscrição : 04/02/2009
Reputação : 120
Número de Mensagens : 1363
Prêmios :
x 0 x 9 x 0
x 0 x 1 x 0
x 0 x 0 x 1
Plataformas :- Game Maker 8.0 ou 8.1
- Game Maker Studio 2.0
- C#
Re: [Tutorial] Máquina de estados finitos
dharrison, vou tentar dar uma finalizada num jogo que uso a máquina pra fazer uma IA pra lá de complexa (mas que abandonei porque estava complexa demais e encheu :oops: ), mas não tem mistério não.
Você cria um script que vale pra um step. Esse script pode ser repetido indefinidamente (usando estado_continua) ou, dependendo da situação, chamar outro script (definindo proximo_estado e usando estado_proximo).
Isso te leva a evitar (mas não te proíbe) o uso de algumas built-in's, como speed, por exemplo, porque o próximo estado pode exigir que o objeto esteja parado.
O truque é definir exatamente o que você quer que aconteça (atuando como designer) ANTES de começar a programar (atuando como programador). Esse foi o pecado que me levou a abandonar meu jogo, eu fui tendo idéias à medida que programava, o que me levava a re-desenhar todos os... sei lá... 20 scripts várias e várias vezes.
Você cria um script que vale pra um step. Esse script pode ser repetido indefinidamente (usando estado_continua) ou, dependendo da situação, chamar outro script (definindo proximo_estado e usando estado_proximo).
Isso te leva a evitar (mas não te proíbe) o uso de algumas built-in's, como speed, por exemplo, porque o próximo estado pode exigir que o objeto esteja parado.
O truque é definir exatamente o que você quer que aconteça (atuando como designer) ANTES de começar a programar (atuando como programador). Esse foi o pecado que me levou a abandonar meu jogo, eu fui tendo idéias à medida que programava, o que me levava a re-desenhar todos os... sei lá... 20 scripts várias e várias vezes.
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Opa saim, ótimo sistema! Estou tentando fazê-lo aqui no meu PC, mas estou com certos problemas " Você comentou no script para usar input_check, o que seria exatamente essa função? Não há como fazer por Keyboard Check ou Keyboard Press? E outra coisa, qual é o conteúdo do script st_default? "
Markituh- Games Ranking :
Data de inscrição : 11/10/2009
Reputação : 106
Número de Mensagens : 2184
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Markituh, vou te confessar que não faço idéia do que é essa função. Eu realmente só traduzi o que vi na outra comunidade.
Me parece que é exatamente o que você sugeriu, acrescentando os mouse_checks e os inputs do joystick.
Eu ainda estou devendo o exemplo, né? Agora devo ter mais tempo, o exemplo não deve demorar muito.
Me parece que é exatamente o que você sugeriu, acrescentando os mouse_checks e os inputs do joystick.
Eu ainda estou devendo o exemplo, né? Agora devo ter mais tempo, o exemplo não deve demorar muito.
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Ah, firmeza. Tá dando altos erros com Unknow variable aqui, no meio dessa bagaça toda não sei diferenciar os scripts de constantes Talvez com o seu exemplo fique melhor a compreensão. E... Não me recordo de ter sugerido algo ._. Só perguntei se não podia usar o evento Keyboard Check ou Keyboard Press, tinha que ser esse aí. Input_check deve ser algum script postado na GMC, é bom dar uma procurada e mostrar pro pessoal.
Aguardando o exemplo, planejo usar a MEF para fazer um jogo super ultra incrível, que ganhará nota A e talz
Aguardando o exemplo, planejo usar a MEF para fazer um jogo super ultra incrível, que ganhará nota A e talz
Markituh- Games Ranking :
Data de inscrição : 11/10/2009
Reputação : 106
Número de Mensagens : 2184
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
As variáveis que provavelmente deram como "unknown" são aquelas de transição: estado_proximo_agora, estado_proximo , estado_continua e estado_repete (que acabo de perceber que não traduzi os comentários...). Se forem essas, você pode escolher declará-las como variáveis locais no create do objeto que usa a MEF ou declará-las como globais no global game settings, usando os valores sugeridos (0, 1, 2, 3) ou o que você preferir. Eu levei algum tempo pra entender como elas funcionam, então suponho que outras pessoas também possam ter dificuldades nesse aspecto.
A tradução de "input_check" é "checagem de entrada". As entradas são exatamente os key_checks, button_checks, etc, por isso acho que trata-se realmente do que você mencionou (não sugeriu ^_^ ). Ou seja, input_check seria um termo que abrange todas as formas de checar entradas do usuário.
Sem chance de ser algum script da GMC. Se fosse, o script obrigatoriamente estaria incluído no exemplo, o que não é o caso.
Particularmente, eu uso a MEF só pra quando o objeto é mais complexo, ou seja, ele requer mudança de estados pra ser programado. Aqueles inimigos que andam de um lado pra outro dispensam a ferramenta, enquanto um player, que pula, anda, corre, come cogumelos, ganha poderes temporários, etc, pode ser programado com muito mais facilidade.
Ela tem uma desvantagem que não mencionei: ela usa scripts. Qual o problema nisso? Scripts declaram 8 variáveis a cada vez que são chamados (mesmo que você não use todos os argumentos, eles SÃO declarados como "0"). Chamar muitos scripts em cada step pode deixar o jogo lento. Um único objeto dificilmente causará problemas, mas se você fizer um jogo com ninjas inimigos super-astutos, faça poucos ninjas de cada vez.
A tradução de "input_check" é "checagem de entrada". As entradas são exatamente os key_checks, button_checks, etc, por isso acho que trata-se realmente do que você mencionou (não sugeriu ^_^ ). Ou seja, input_check seria um termo que abrange todas as formas de checar entradas do usuário.
Sem chance de ser algum script da GMC. Se fosse, o script obrigatoriamente estaria incluído no exemplo, o que não é o caso.
Particularmente, eu uso a MEF só pra quando o objeto é mais complexo, ou seja, ele requer mudança de estados pra ser programado. Aqueles inimigos que andam de um lado pra outro dispensam a ferramenta, enquanto um player, que pula, anda, corre, come cogumelos, ganha poderes temporários, etc, pode ser programado com muito mais facilidade.
Ela tem uma desvantagem que não mencionei: ela usa scripts. Qual o problema nisso? Scripts declaram 8 variáveis a cada vez que são chamados (mesmo que você não use todos os argumentos, eles SÃO declarados como "0"). Chamar muitos scripts em cada step pode deixar o jogo lento. Um único objeto dificilmente causará problemas, mas se você fizer um jogo com ninjas inimigos super-astutos, faça poucos ninjas de cada vez.
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Muito bom mesmo.
Eu uso em todos os meus jogos, é minha parte favorita do grande sistema de engrenagens do Game Maker
Parabens pelo Tuto
Eu uso em todos os meus jogos, é minha parte favorita do grande sistema de engrenagens do Game Maker
Parabens pelo Tuto
Re: [Tutorial] Máquina de estados finitos
Assim como programação modular é programar as partes de um programa de forma que funcionem separadamente (como a máquina de estados) hard-coded é o oposto onde tudo é misturado e é difícil de se codificar, ou seja, interpretar.
Eu sempre uso constantes para os nomes dos estados, é uma forma mais otimizada:
O mesmo autor desse tutorial tem uma engine muita boa sobre movimentação irregular.
É bem mais extensa mas é algo bem útil de se aprender como as máquinas de estado.
Eu sempre uso constantes para os nomes dos estados, é uma forma mais otimizada:
- Código:
// Constantes
parar = 0;
correr = 1;
pular = 2;
- Código:
estado = estado mod ultimo_estado+1;
O mesmo autor desse tutorial tem uma engine muita boa sobre movimentação irregular.
É bem mais extensa mas é algo bem útil de se aprender como as máquinas de estado.
Re: [Tutorial] Máquina de estados finitos
Adicionado um exemplozinho comentado no final do tópico original.
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Opa, então o st_default definia as variáveis, certo... Tentei achar no st_pula_sobe alguma forma de limitar o quanto o player pula, mas isso não é importante. O ruim é que constantes só são permitidas na versão Pro, que pena, apesar de eu ter achado uma forma de definir constantes com a Lite Mas assim, há pouca chance dessa forma funcionar, seria defini-las num editor hexadecimal, mas para isso teria que saber o ponto EXATO para inserir as constantes, sem falar no cuidado total com as endstrings. Saim, teria como explicar uma maneira de fazer isso usando variáveis comuns? Pretendo programar um projeto com esse sistema, e como também pretendo postar na Yoyogames, terei sérios problemas se estiver usando um crack.
Markituh- Games Ranking :
Data de inscrição : 11/10/2009
Reputação : 106
Número de Mensagens : 2184
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Markituh, o que eu fiz com pro foi definir as constantes estado_proximo_agora, estado_proximo , estado_continua e estado_repete como "user-defined constants". Pra contornar isso, você pode fazê-las globais através de algum outro objeto ou mesmo declará-las no create do obj_player.
Não entendi sua idéia, mas me parece que essas opções que descrevi são mais simples (não sei porque não fiz o exemplo assim, vou mudar e atualizar)
Edit: Pronto. Agora, a menos que haja alguma função pro durante os estados (acho que não tem), o exemplo roda em lite.
Pra limitar o quanto o player pula, você pode definir algum argumento (arg0-7) como "y-altura" logo antes de passar para o "st_pula_sobe" e proibir o "y" de ser menor que o argumento. Só que, aí, seria bom de lembrar de limpar os agumentos SEMPRE que sair desse estado. Outra forma visualmente mais agradável seria calcular a velocidade inicial, a gravidade e o tempo de "pulo longo" de modo a atingir o teto desejado.
Não entendi sua idéia, mas me parece que essas opções que descrevi são mais simples (não sei porque não fiz o exemplo assim, vou mudar e atualizar)
Edit: Pronto. Agora, a menos que haja alguma função pro durante os estados (acho que não tem), o exemplo roda em lite.
Pra limitar o quanto o player pula, você pode definir algum argumento (arg0-7) como "y-altura" logo antes de passar para o "st_pula_sobe" e proibir o "y" de ser menor que o argumento. Só que, aí, seria bom de lembrar de limpar os agumentos SEMPRE que sair desse estado. Outra forma visualmente mais agradável seria calcular a velocidade inicial, a gravidade e o tempo de "pulo longo" de modo a atingir o teto desejado.
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Bom, as constantes funcionam, mas não tem como definí-las na Lite. Uma forma seria eu fazer meu projeto a partir do seu exemplo, já que as constantes estão declaradas no arquivo .gmk, mas não seria tão legal... Vou passar um tempo estudando esse sistema, quem sabe meu jogo não fica legal? Gostaria de te perguntar algo, irei mandar uma MP.
Markituh- Games Ranking :
Data de inscrição : 11/10/2009
Reputação : 106
Número de Mensagens : 2184
Prêmios :
x 0 x 1 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Kabeção escreveu:Eu sempre uso constantes para os nomes dos estados, é uma forma mais otimizada:Assim posso mudar os estados facilmente na hora de testes por exemplo apenas acrescentando +1 ou impedir que outros estados que não existam sejam definidos apenas fazendo isso:
- Código:
// Constantes
parar = 0;
correr = 1;
pular = 2;Usar strings abre muito espaço para erros.
- Código:
estado = estado mod ultimo_estado+1;
Essa máquina apresentada aqui também não usa strings, mas scripts, que já são armazenados como variáveis por natureza, então eu acabo fazendo (mais ou menos) a mesma coisa. Só que, com essa máquina, não é recomendável mudar os estados dessa forma, por vários motivos:
- se você eliminou algum script durante a programação, o valor das variáveis não será sequencial, causando erros.
- mudar o estado manualmente requer conhecimento da máquina a fim de evitar problemas com os argumentos (arg0-7) e o tempo_no_estado.
- você perde a flexibilidade que as mudanças aqui apresentadas oferecem (estado_repete, estado_proximo_agora)
Fora isso, o fato dos scripts serem variáveis pode causar um erro um pouco mais grave se você definir ainda outros valores a eles. Por exemplo, suponha que o jogo declare (automaticamente) que o estado st_default vale 1. Depois, ao atribuir novos valores aos estados, você declare (manualmenmte) que é o st_atirando que vale 1. Ao chamar o estado que vale "1", qual dos dois será chamado? Sinceramente, não sei.
saim- Games Ranking :
Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios :
x 1 x 6 x 0
x 1 x 0 x 3
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Entendo, está usando diretamente o id dos scripts para identifica-los e não seu nome propriamente dito.saim escreveu:Kabeção escreveu:Eu sempre uso constantes para os nomes dos estados, é uma forma mais otimizada:Assim posso mudar os estados facilmente na hora de testes por exemplo apenas acrescentando +1 ou impedir que outros estados que não existam sejam definidos apenas fazendo isso:
- Código:
// Constantes
parar = 0;
correr = 1;
pular = 2;Usar strings abre muito espaço para erros.
- Código:
estado = estado mod ultimo_estado+1;
Essa máquina apresentada aqui também não usa strings, mas scripts, que já são armazenados como variáveis por natureza, então eu acabo fazendo (mais ou menos) a mesma coisa. Só que, com essa máquina, não é recomendável mudar os estados dessa forma, por vários motivos:
- se você eliminou algum script durante a programação, o valor das variáveis não será sequencial, causando erros.
- mudar o estado manualmente requer conhecimento da máquina a fim de evitar problemas com os argumentos (arg0-7) e o tempo_no_estado.
- você perde a flexibilidade que as mudanças aqui apresentadas oferecem (estado_repete, estado_proximo_agora)
Fora isso, o fato dos scripts serem variáveis pode causar um erro um pouco mais grave se você definir ainda outros valores a eles. Por exemplo, suponha que o jogo declare (automaticamente) que o estado st_default vale 1. Depois, ao atribuir novos valores aos estados, você declare (manualmenmte) que é o st_atirando que vale 1. Ao chamar o estado que vale "1", qual dos dois será chamado? Sinceramente, não sei.
Mas para tudo isso eu costumava usar outro método como ds_grid que facilitava na hora de criar um padrão sendo que cada estado tinha os valores certos e assim usar apenas um script para executa-los ou simplesmente variáveis também mas não concentradas em scripts.
Parando para pensar agora, usar um script para cada estado é realmente o melhor método e o mais funcional já que eles não só definem variáveis mas também, como você disse, definem muitos outras coisas como o próximo estado, já executam as ações (como mover, lançar magia e etc) e ainda da para tratar imprevistos como quebra da ação, mudança repentina e coisa e tal.
Hehe, acabei de aprender um novo conceito para melhorar o sistema de meus projetos!
Não tinha percebido isso quando li o original, vlw!
Re: [Tutorial] Máquina de estados finitos
Praticamente obrigatorio o uso disso em jogos de luta.
O controle sobre as ação é muito otimizado mas a programação, no inicio do projeto, é bem extensa e não é algo que pode ser usado por qualquer um sem experiencia.
O controle sobre as ação é muito otimizado mas a programação, no inicio do projeto, é bem extensa e não é algo que pode ser usado por qualquer um sem experiencia.
DS Santos- Data de inscrição : 19/05/2010
Reputação : 2
Número de Mensagens : 98
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Muito bom Mas tem como fazer cenarios aleatorios?
anth201- Data de inscrição : 21/05/2013
Reputação : 0
Número de Mensagens : 17
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
tenho pouca noçao de game maker encontrei barreiras na maquina de estados tipo eu coloco num estado do personagem caminhar para frente ele entra no estado la dentro do estado de caminhar tem parado=false e no estado parado eu tenho o codigo para pular meu personagem sempre anda e se eu apertar pulo ele pula eu quero q ele pula somente parado e nao to conseguindo fazer isso
glaysonmestre- Data de inscrição : 01/01/2013
Reputação : 1
Número de Mensagens : 195
Prêmios :
x 0 x 0 x 0
x 0 x 0 x 0
x 0 x 0 x 0
Re: [Tutorial] Máquina de estados finitos
Poste seu código para vermos.
Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.
Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.
Aprenda a calcular a velocidade de suas animações
Entre para o Clube do Inglês:
Tópicos semelhantes
» Movimentação com máquina de estados finitos
» ajuda com scripts de estados finitos
» Máquina de estados
» duvida maquina de estados
» Exemplo Máquina de Estados
» ajuda com scripts de estados finitos
» Máquina de estados
» duvida maquina de estados
» Exemplo Máquina de Estados
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos