Aula 1
Nessa aula, faremos um jogo de plataforma com a parte básica da movimentação, o jogador poderá apenas pular para cima (acredite, isso não é redundante) e andar para os lados (esquerda e direita).
Para criar um projeto, clique em New, digite o nome do seu projeto e clique em Create.
A janela principal do GameMaker Studio irá aparecer.
Agora, vamos começar criando o nosso primeiro sprite, mas antes você precisa saber o que é um sprite.
Sprite é a representação de um objeto no jogo, ele é composto por 1 ou mais imagens.
O primeiro sprite que iremos criar é o do jogador.
Siga os passos:
• Criando sprite do jogador
- Clique com o botão direito na pasta Sprites.
- Clique em Create Sprite.
- Uma nova janela aparecerá, mude o nome do sprite0 para spr_player e clique em Edit Sprite.
- Clique em File -> New, ou na folha em branco que aparece no topo.
- Deixe Width = 32 e Height = 32, aperte OK.
- Uma imagem será criada, dê um clique duplo nela para que possa editá-la.
- Desenhe um quadrado que ocupe a imagem toda (Você pode usar o balde de tinta e selecionar uma cor).
- Salve a imagem clicando no ✓ e o sprite clicando no ✓, em seguida, aperte em OK na janela do sprite.
• Criando o objeto do jogador
- Clique com o botão direito na pasta Objects.
- Clique em Create Object.
- Uma nova janela aparecerá, mude o nome do object0 para obj_player.
- Adicione o evento Step, para isso, clique em Add Event -> Step -> Step
Antes de escrevermos nosso primeiro código, você deve entender o que são eventos.
"Eventos são momentos do jogo em que as ações são realizadas com base no que foi programado."
Para ficar mais fácil, vamos ver alguns exemplos de eventos.
Create: É o evento executado no momento em que o objeto (instância de objeto, sendo mais preciso) é criado.
Step: É o evento executado pelo objeto a cada frame do jogo. Se o jogo roda a 60 quadros por segundo, esse evento será executado 60 vezes em um segundo.
Collision: É o evento executado quando o objeto colide com outro objeto.
Andar para os lados
Agora, vamos escrever o nosso primeiro código no evento Step.
Do lado direito da janela do obj_player, há várias abas na vertical, clique na aba control, e clique com botão direito na folha com a descrição Execute Code (fica logo abaixo da palavra Code).
Do lado direito da janela do obj_player, há várias abas na vertical, clique na aba control, e clique com botão direito na folha com a descrição Execute Code (fica logo abaixo da palavra Code).
Digite.
x = x + 4;
Esse código fará com que a cada frame, a variável x receba o seu valor acrescido de 4.
Esse código fará com que a cada frame, a variável x receba o seu valor acrescido de 4.
Em seguida, crie uma Room, de maneira análoga à criação do sprite e do objeto.
- Clique com o botão direito na pasta Rooms, clique em Create Room.
- Dentro da room, clique na aba objects, e adicione uma instância do obj_player clicando em qualquer lugar da room.
Salve a room e teste o jogo clicando no ícone da seta verde (►).
...Depois de testar
Você deve ter notado que o objeto do jogador se moveu para a direita até sumir da tela. Isso acontece porque no evento Step, nós colocamos para ele se mover 4 pixels para a direita a cada frame, mesmo sem apertar nenhuma tecla. Para fazer essa checagem, você precisa entender a estrutura condicional do if.
Basicamente, o if funciona da seguinte maneira.
if (condição){ // Se a condição for verdadeira/true
// Faça isso
}
// Faça isso
}
Colocando isso no código que escrevemos, temos:
if (keyboard_check(vk_right)){ // Se a seta para a direita está sendo pressionada
x = x + 4; // Ande 4 pixels para a direita
}
Como foi comentado no código, a função keyboard_check(key) retorna true se a key estiver sendo pressionada, e false caso contrário.
Testando o jogo novamente, você observa que o jogador se movimenta para a direita somente quando pressiona a seta para a direita.
Para fazê-lo se mover para a esquerda, basta escrever um código análogo para a seta para a esquerda:
if (keyboard_check(vk_left)){ // Se a seta para a esquerda está sendo pressionada
x = x - 4; // Ande 4 pixels para a esquerda
}
Teste o jogo. Apesar de ser um sistema de movimentação bem simples, você já consegue andar nas duas direções de acordo com as teclas pressionadas, em outra aula, veremos como acrescentar a aceleração no movimento.
Desafio: tente fazer a mesma coisa com a seta para cima e a seta para baixo (A seta para cima deve mover o jogador para cima e a seta para baixo deve mover o jogador para baixo).
if (keyboard_check(vk_right)){ // Se a seta para a direita está sendo pressionada
x = x + 4; // Ande 4 pixels para a direita
}
Como foi comentado no código, a função keyboard_check(key) retorna true se a key estiver sendo pressionada, e false caso contrário.
Testando o jogo novamente, você observa que o jogador se movimenta para a direita somente quando pressiona a seta para a direita.
Para fazê-lo se mover para a esquerda, basta escrever um código análogo para a seta para a esquerda:
if (keyboard_check(vk_left)){ // Se a seta para a esquerda está sendo pressionada
x = x - 4; // Ande 4 pixels para a esquerda
}
Teste o jogo. Apesar de ser um sistema de movimentação bem simples, você já consegue andar nas duas direções de acordo com as teclas pressionadas, em outra aula, veremos como acrescentar a aceleração no movimento.
Desafio: tente fazer a mesma coisa com a seta para cima e a seta para baixo (A seta para cima deve mover o jogador para cima e a seta para baixo deve mover o jogador para baixo).
Pulo
Para fazer o pulo, nós usaremos a variável vspeed, que é uma variável built-in, pois já tem um funcionamento pré-determinado pelo GameMaker.
A variável vspeed representa a quantidade de pixels que devem ser percorridos no eixo y (vertical) a cada frame. Note que o seu valor pode ser positivo, negativo ou nulo. De acordo com o plano cartesiano do GameMaker, a origem (0, 0) fica no canto superior esquerdo. Os valores de x crescem para a direita, mas os valores de y crescem para baixo, o que é diferente do convencional. Portanto, se o valor de vspeed for positivo, o objeto irá descer, e se for negativo, ele irá subir.
Dessa maneira, se você quiser fazer um objeto pular, deverá colocar um valor negativo (com sinal de -).
Acrescente o seguinte código no evento Step do obj_player.
if (keyboard_check(vk_space)){ // Se o espaço está sendo pressionado
vspeed = -5; // Altere a velocidade vertical para 5 pixels/frame para cima
}
Teste o projeto.
Observe que se você apertar espaço, o jogador irá para cima sem parar. No mundo real, isso não ocorreria, pois existe uma força chamada força gravitacional, que puxa o corpo para o centro da Terra com uma determinada aceleração g.
No GameMaker, também existe uma variável que representa a aceleração da gravidade, ela é chamada de gravity.
A gravidade também tem uma direção, que pode ser obtida e alterada. O nome da variável que representa essa direção é gravity_direction, que por padrão, inicia com o valor de 270, o ângulo para baixo (0 = direita, 90 = cima, 180 = esquerda, 270 = baixo). A gravidade altera a velocidade do objeto por meio de uma soma vetorial, mas isso não nos interessa, pois vamos considerar o caso mais básico, em que a gravidade possui sentido para baixo.
Para colocar gravidade no jogador, adicione o Create Event no obj_player e coloque:
gravity = 0.25; // Adiciona gravidade no jogador com o valor de 0.25 pixels/frame²
Teste o jogo.
Observe que agora o jogador começa caindo, mas você pode "pular no ar". Na verdade, esse efeito parece mais um voo, pois o jogador sobe enquanto você segura o espaço. Porém, ainda há um elemento fundamental faltando no nosso jogo. Sim, o chão!
vspeed = -5; // Altere a velocidade vertical para 5 pixels/frame para cima
}
Teste o projeto.
Observe que se você apertar espaço, o jogador irá para cima sem parar. No mundo real, isso não ocorreria, pois existe uma força chamada força gravitacional, que puxa o corpo para o centro da Terra com uma determinada aceleração g.
No GameMaker, também existe uma variável que representa a aceleração da gravidade, ela é chamada de gravity.
A gravidade também tem uma direção, que pode ser obtida e alterada. O nome da variável que representa essa direção é gravity_direction, que por padrão, inicia com o valor de 270, o ângulo para baixo (0 = direita, 90 = cima, 180 = esquerda, 270 = baixo). A gravidade altera a velocidade do objeto por meio de uma soma vetorial, mas isso não nos interessa, pois vamos considerar o caso mais básico, em que a gravidade possui sentido para baixo.
Para colocar gravidade no jogador, adicione o Create Event no obj_player e coloque:
gravity = 0.25; // Adiciona gravidade no jogador com o valor de 0.25 pixels/frame²
Teste o jogo.
Observe que agora o jogador começa caindo, mas você pode "pular no ar". Na verdade, esse efeito parece mais um voo, pois o jogador sobe enquanto você segura o espaço. Porém, ainda há um elemento fundamental faltando no nosso jogo. Sim, o chão!
Chão
Adicione um sprite para o chão da mesma maneira que fizemos para o jogador, chame-o de spr_floor. Pinte-o de qualquer cor, e salve-o.
Em seguida, crie o objeto do chão, renomeie-o para obj_floor, e marque a opção solid.
(Por enquanto, a regra para marcar solid é esta: marque como solid todos os objetos que representam o chão ou a parede e não se movem.)
Agora, vamos adicionar um evento de colisão do jogador com o chão.
Vá ao obj_player, clique em Add Event -> Collision -> obj_floor.
Com o fito de parar o jogador na vertical ao colidir com o chão, devemos alterar a variável vspeed para 0.
Adicione um código a esse evento, e coloque o seguinte script.
vspeed = 0;
Isso vai fazer o jogador parar na vertical quando colidir com o chão.
Antes de testar o código, adicione instâncias do chão na room, você pode usar o atalho Ctrl + Shift + Botão Esquerdo do Mouse para adicionar mais rápido.
Testando...
Testando...
Se você testar agora, vai notar 2 "bugs" no nosso jogo. O mais fácil de notar é que o jogador não consegue se movimentar quando está no chão. O segundo é que, um pouco antes de encostar no chão, o jogador para na vertical e depois começa a cair novamente, e esse processo se repete até não haver mais espaço entre ele e o chão.
Por que o jogador não consegue andar no chão?
Primeiramente, devemos esclarecer que quando o evento de colisão for executado com algum objeto marcado como solid, a instância voltará para a posição que estava no frame anterior (antes do evento Step).
Nesse contexto, suponha que o obj_player estava em uma posição (x, y), e no evento Step, movemo-lo para a direita, então ele tem uma nova posição (x + 4, y) até o momento. Outrossim, existe a gravidade, que acelera o obj_player para baixo, e fá-lo-á colidir com o obj_floor, no ponto (x + 4, y + vspeed), conseguintemente, o evento de colisão será executado, e por se tratar de um colisão com um objeto solid, o jogador voltará para a posição anterior (x, y) como se nada tivesse acontecido, e é isso que impede o jogador de se mover no chão.
Como corrigir?
Há diversas maneiras de corrigir esse problema, nessa aula, vou mostrar apenas uma.
Observe que, a causa do problema é o evento de colisão com o obj_floor, então basta impedir que esse evento seja executado depois do primeiro instante da colisão. E para impedir que ele seja executado, vamos analisar que fatores do jogo "ativam" esse evento. Como vimos na explicação do motivo de o jogador não conseguir andar no chão, a gravidade é a responsável por ativar o evento de colisão, então uma maneira simples de corrigir, seria alterar a gravidade para 0 no evento de colisão.
gravity = 0;
Isso vai fazer com que o jogador consiga andar no chão, mas ainda há 2 problemas.
1) Se pular, não cairá novamente, pois a gravidade foi alterada para 0.
2) Dependendo da altura, o jogador não caiu até encostar o mais próximo possível do chão.
Para corrigir o 2º problema, teremos que usar a função move_contact_solid(dir,maxdist).
Desse modo, podemos mover o jogador para baixo (dir = 270), com uma distância máxima qualquer, desde que seja maior do que vspeed.
Podemos acrescentar no código da colisão:
move_contact_solid(270, 10);
Se você testar agora, vai perceber que o segundo problema foi corrigido, e o primeiro?
Para corrigir o primeiro problema, usaremos a função place_free(x, y).
Com essa função, verificaremos se o jogador não está no chão para alterar a gravidade para 0.25.
No topo do código do evento Step, coloque:
if (place_free(x, y + 1)){ // Se o jogador estiver "no ar"
gravity = 0.25; // A gravidade fará efeito sobre ele
}
Teste o jogo e veja o resultado.
O problema foi corrigido, pois o jogador cai depois de "pular". Se o seu objetivo é fazer com que o jogador voe, então ele foi cumprido. Porém, se você quer que ele pule somente quando estiver no chão, teremos que usar novamente a função place_free(x, y) para verificar isso.
Substitua o código do pulo por:
if (!place_free(x, y + 1)){ // Se o jogador está no chão
if (keyboard_check_pressed(vk_space)){ // E o espaço foi pressionado
vspeed = -5; // Altere a velocidade vertical para 5 pixels/frame para cima
}
}
(Observação: a diferença da função keyboard_check() para a keyboard_check_pressed(), é que a última só retorna true no primeiro instante/frame em que pressionamos a tecla, diferentemente da função keyboard_check que retorna true até você soltar a tecla).
Se você tiver feito tudo que foi descrito acima, o seu jogo já deve estar funcionando como queríamos.
Até a próxima aula.
Por que o jogador não consegue andar no chão?
Primeiramente, devemos esclarecer que quando o evento de colisão for executado com algum objeto marcado como solid, a instância voltará para a posição que estava no frame anterior (antes do evento Step).
Nesse contexto, suponha que o obj_player estava em uma posição (x, y), e no evento Step, movemo-lo para a direita, então ele tem uma nova posição (x + 4, y) até o momento. Outrossim, existe a gravidade, que acelera o obj_player para baixo, e fá-lo-á colidir com o obj_floor, no ponto (x + 4, y + vspeed), conseguintemente, o evento de colisão será executado, e por se tratar de um colisão com um objeto solid, o jogador voltará para a posição anterior (x, y) como se nada tivesse acontecido, e é isso que impede o jogador de se mover no chão.
Como corrigir?
Há diversas maneiras de corrigir esse problema, nessa aula, vou mostrar apenas uma.
Observe que, a causa do problema é o evento de colisão com o obj_floor, então basta impedir que esse evento seja executado depois do primeiro instante da colisão. E para impedir que ele seja executado, vamos analisar que fatores do jogo "ativam" esse evento. Como vimos na explicação do motivo de o jogador não conseguir andar no chão, a gravidade é a responsável por ativar o evento de colisão, então uma maneira simples de corrigir, seria alterar a gravidade para 0 no evento de colisão.
gravity = 0;
Isso vai fazer com que o jogador consiga andar no chão, mas ainda há 2 problemas.
1) Se pular, não cairá novamente, pois a gravidade foi alterada para 0.
2) Dependendo da altura, o jogador não caiu até encostar o mais próximo possível do chão.
Para corrigir o 2º problema, teremos que usar a função move_contact_solid(dir,maxdist).
move_contact_solid(dir,maxdist)
Essa função basicamente move o objeto em uma determinada direção (dir em graus), até colidir com um objeto solid ou até percorrer uma distância maxdist (em outras palavras, se a instância não colidir com nenhum objeto solid, vai mover a instância até uma distância maxdist).Desse modo, podemos mover o jogador para baixo (dir = 270), com uma distância máxima qualquer, desde que seja maior do que vspeed.
Podemos acrescentar no código da colisão:
move_contact_solid(270, 10);
Se você testar agora, vai perceber que o segundo problema foi corrigido, e o primeiro?
Para corrigir o primeiro problema, usaremos a função place_free(x, y).
place_free(x, y)
Essa função simula o que aconteceria se colocássemos a instância na posição (x, y) dos parâmetros, e retorna true se não colidir com nenhum objeto solid, e false caso colida com algum objeto solid.Com essa função, verificaremos se o jogador não está no chão para alterar a gravidade para 0.25.
No topo do código do evento Step, coloque:
if (place_free(x, y + 1)){ // Se o jogador estiver "no ar"
gravity = 0.25; // A gravidade fará efeito sobre ele
}
Teste o jogo e veja o resultado.
O problema foi corrigido, pois o jogador cai depois de "pular". Se o seu objetivo é fazer com que o jogador voe, então ele foi cumprido. Porém, se você quer que ele pule somente quando estiver no chão, teremos que usar novamente a função place_free(x, y) para verificar isso.
Substitua o código do pulo por:
if (!place_free(x, y + 1)){ // Se o jogador está no chão
if (keyboard_check_pressed(vk_space)){ // E o espaço foi pressionado
vspeed = -5; // Altere a velocidade vertical para 5 pixels/frame para cima
}
}
(Observação: a diferença da função keyboard_check() para a keyboard_check_pressed(), é que a última só retorna true no primeiro instante/frame em que pressionamos a tecla, diferentemente da função keyboard_check que retorna true até você soltar a tecla).
Se você tiver feito tudo que foi descrito acima, o seu jogo já deve estar funcionando como queríamos.
Até a próxima aula.
Comentários
Postar um comentário