Qualidade
Nome: Bugs e dúvidas comuns
Blogueiro: Saim
Descrissao: Existem algumas perguntas que são feitas e refeitas aqui na comunidade.
Estou elaborando uma lista dos bugs mais comuns e das soluções mais
comuns. Se você tiver algum bug que te aconteça em 9 de 10 jogos que
você cria, comente e eu tentarei acrescentar uma solução genérica,
colocando seu bug na lista.
Versao: Lite e Pro
Foto(s): [explicaçao]
Tutorial:
Meu personagem fica preso
O
primeiro bug da maioria dos desenvolvedores. O persongem (obj_player ou
não) anda até uma parede e depois não sai mais. Não importa a força com
que o jogador aperte o teclado, o personagem travou!
Normalmente
isso é um problema de sobreposição de masks. Seu personagem está
entrando alguns pixels no chão/parede. Pode acontecer por dezenas de
motivos.
Você programa a velocidade pra ser zero caso o objeto colida
com um bloco, então se eles se sobreporem, o natural é que a velocidade
seja sempre zero.
Um motivo comum é o uso de sprites irregulares
como a mask acompanhando o personagem. Daí, num image_index ele está ok,
no outro está alguns pixels dentro do bloco.
Outro motivo é código mal elaborado, que não impede a sobreposição.
Nem
sempre é possível enxergar essa sobreposição a olho nu. Além de ser
apenas alguns pixels, a mask pode ser diferente da sprite. Nesses casos é
bem difícil determinar o problema.
solução
Crie uma variável só pra debugar. Sempre que houver uma colisão, esa variável deve ter o valor true e sempre que não houver, false. Daí você pode usar alguma função de draw pra verificar o valor dessa variável ou simplesmente o debug mode.
Se
for verificado que a colisão realmente tornou-se constante enquanto o
objeto está travado, não restam mais dúvidas quanto à causa do bug. Daí,
parta para a análise dos códigos, das sprites, das masks. Use uma lupa.
Meu sprite não aparece
Você faz o jogo direitinho, se esforça e, na hora que vai rodar, alguns objetos que deveriam estar lá, simplesmente não estão.
Existem algumas causas principais pra isso:
1 - Existe algo no draw event. O game maker usa um draw event "default", que apenas desenha o personagem. Eu diria que ele contém "draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, imgae_angle, c_white, 1);". Se você coloca QUALQUER coisa no seu próprio draw event, esse evento-padrão é ignorado.
2
- Não existe a instância. Acontece. Você acha que criou uma instância,
mas ela não foi criada ou foi eliminada sem que você se desse conta.
3 - A instância não está na tela. Ela existe, está sendo desenhada, mas está fora do seu campo de visão.
solução
Em todos os casos, verificar o draw event
ou mesmo alterá-lo até encontrar o problema pode ser uma boa. Pra
checar se a instância existe, mande desenhar algo numa posição que você
SABE que vai aparecer. Como sempre, o modo debug também pode ser útil,
se você procurar por termos como "x", "y", "instance_number".
Uma vez determinado qual é o problema, não é difícil corrigir.
Meu jogo trava
No
meio do jogo, mesmo sem tocar em nada, o personagem para de obedecer
aos comandos. Você tenta fechar a janela do jogo pra procurar o bug e
ela não fecha, você tem que abrir o gerenciador de tarefas.
A causa
desse bug é (até onde eu sei) única: existe um laço (ou loop) que não
encontra a condição de ser finalizado. Porque esse loop não está
conseguindo se encerrar, aí a história é outra. Existem dezenas,
centenas, talvez até milhares de motivos pra isso. Cada loop, um motivo.
Alguns motivos comuns:
- Erro de digitação: for (i = 0; i < 10; j += 1){
- Erro de lógica: i = 0; while(i < 10){ /* código */ }; Note que não foi colocado o "i += ..." no código
- Erro de lógica2: for (i = 0; i < 10; i += 1){ /* código */; i -=1 }; Note que no final do loop, i volta pro valor inicial
solução
Não sei se existe uma solução padrão pra esses casos. O que eu costumo fazer é:
-
Tentar descobrir em que evento o jogo está travando, o que pode dar uma
dica de qual loop está com problemas. Se for no início do jogo (quando
normalmente existem muitos loops), talvez seja melhor ir direto pra
segunda abordagem.
- Tentar isolar o problema eliminando os loops, um
por um, não importa o quanto o jogo fique bugado até que se descubra o
problema. Não é uma boa solução (porque uma variável usada num loop pode
estar sendo definida em outro), mas em muitos casos pode ajudar.
Assim
que se descobre qual loop causa o erro, fica viável (ou menos inviável)
isolá-lo e testar o comportamento das variáveis, iteração por iterção
(ou volta por volta). Algumas vezes pode ser útil usar show_message ou show_debug_message dentro desses loops, já que muitas vezes eles usam variáveis var.
"Unexpected error"
No
meio do jogo, essa mensagem enigmática: "unexpected error ocurred while
running the game", ou "ocorreu um erro inesperado ao rodar o jogo". Aí,
lascou. Afinal, existe algum programador que espera um erro?
O que
isso quer dizer é que o game maker verificou todas as funções e scripts e
um deles não está funcionando apesar do número e tipos de argumentos
estarem corretos. Você comeu mosca em algum ponto.
solução
Se
a quantidade e o tipo de argumentos estão corretos, o erro só pode
estar no valor deles. Eu constantemente recebo esse erro por trocar a
ordem dos argumentos de algumas funções. Por exemplo, você pode trocar o
sprite pela surface em "sprite_add_from_surface". Verifique
quais funções você está usando sem ter muito hábito de usar. Experimente
não usar uma ou outra função (no caso, por exemplo, você pode usar uma
sprite sem sub-imagens) até que o problema pare de acontecer. Quando o
problema parar de acontecer, eis a função que está com problemas. Cheque
o manual, veja o que significa cada argumento, altere o que estiver
errado.
Como manter alguma informação?
Ao
mudar de room ou reiniciar a room, todas aquelas variáveis que você se
esforçou pra mudar, como vidas, score, e outras menos comuns, todas elas
voltam pro valor inicial.
Muitas vezes isso é esperado e desejado. Algumas vezes, não.
A
causa mais comum desse problema é que o valor dessas variáveis é
definido no create event do objeto. Como na programação da room o game
maker foi informado pra criar os objetos, ele roda todos os create
event, o que reinicia a variável.
solução
Há várias soluções. Pra cada jogo, uma solução. As que eu sugiro tentar são:
-
Se for uma variável global, você pode definí-la em alguma room do
começo do jogo, ao invés de usar um objeto que será reinicializado.
Pode-se usar, também, um objeto persistente que é criado numa room da
inicialização do programa.
- Se o problema é que a room está sendo
reiniciada, não reinicie a room. O personagem "morrer" não implica,
necessariamente no comando instance_destroy() nem no room_restart().
Você pode usar um evento especial (como a colisão com o inimigo ou o
final de uma animação de morte) pra fazer o personagem reaparecer na
posição inicial, com a tela acompanhando e tudo.
Creditos: Saim
Nenhum comentário:
Postar um comentário