Introdução ao Phaser para desenvolvimento de jogos
Phaser é uma estrutura para a criação de videogames 2D. Ele usa HTML5 Canvas para exibir o jogo e JavaScript para executá-lo. A vantagem de usar o Phaser em vez do JavaScript básico é que ele possui uma extensa biblioteca que completa muito da física dos videogames, permitindo que você se concentre no design do jogo em si.
Phaser reduz o tempo de desenvolvimento e facilita o fluxo de trabalho. Vamos aprender como criar um jogo básico com Phaser.
Por que desenvolver com Phaser?
Phaser é semelhante a outras linguagens de programação visual, pois o programa é baseado em atualizações em loop. O Phaser tem três estágios principais: pré-carregamento, criação e atualização.
No pré-carregamento, os ativos do jogo são carregados e disponibilizados para o jogo.
Criar inicializa o jogo e todos os elementos iniciais do jogo. Cada uma dessas funções é executada uma vez quando o jogo é iniciado.
A atualização, por outro lado, é executada em um loop durante todo o jogo. É o burro de carga que atualiza os elementos do jogo para torná-lo interativo.
Configure seu sistema para desenvolver jogos com Phaser
Apesar de o Phaser ser executado em HTML e JavaScript, os jogos, na verdade, são executados no lado do servidor, não no lado do cliente. Isso significa que você precisará executar o jogo em seu host local . A execução do lado do servidor do jogo permite que o jogo acesse arquivos e ativos adicionais fora do programa. Eu recomendo usar o XAMPP para configurar um host local se você ainda não tiver uma configuração.
O código abaixo o ajudará a começar a trabalhar. Ele configura um ambiente de jogo básico.
<html>
<head>
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
</head>
<body>
<script>
var config = {
type: Phaser.AUTO,
backgroundColor: 0xCCFFFF,
width: 600,
height: 600,
physics: {
default: 'arcade'
},
scene: {
preload: preload,
create: create
}
};
var gamePiece;
var game = new Phaser.Game(config);
function preload(){
this.load.image('gamePiece', 'img/gamePiece.png');
}
function create(){
gamePiece = this.physics.add.sprite(270, 450, 'gamePiece');
}
</script>
</body>
</html>
Para ser executado, o jogo exigirá uma imagem PNG chamada "gamePiece" salva em uma pasta "img" em seu host local. Para simplificar, este exemplo usa um quadrado laranja 60xgame de60px. Seu jogo deve ser semelhante a este:
Se você encontrar um problema, use o depurador do seu navegador para descobrir o que deu errado. Perder até mesmo um único caractere pode causar estragos, mas geralmente, seu depurador detectará esses pequenos erros.
Explicando o código de configuração
Até agora, o jogo não faz nada. Mas já cobrimos muito terreno! Vamos examinar o código com mais detalhes.
Para que um jogo Phaser seja executado, você precisa importar a biblioteca Phaser. Fazemos isso na linha 3. Neste exemplo, vinculamos ao código-fonte, mas você pode baixá-lo em seu host local e fazer referência ao arquivo também.
Muito do código até agora configura o ambiente do jogo, que a variável config armazena. Em nosso exemplo, estamos configurando um jogo de phaser com um fundo azul (CCFFFF em código de cor hexadecimal) de 600 por 600 pixels. Por enquanto, a física do jogo foi definida como arcade , mas Phaser oferece física diferente.
Finalmente, a cena diz ao programa para executar a função de pré – carregamento antes do jogo começar e a função de criação para iniciar o jogo. Todas essas informações são passadas para o objeto de jogo denominado jogo .
A próxima seção do código é onde o jogo realmente toma forma. A função de pré-carregamento é onde você deseja inicializar qualquer coisa necessária para executar o jogo. No nosso caso, pré-carregamos a imagem da nossa peça do jogo. O primeiro parâmetro de .image nomeia nossa imagem e o segundo diz ao programa onde encontrar a imagem.
A imagem gamePiece foi adicionada ao jogo na função de criação. A linha 29 diz que estamos adicionando a imagem gamePiece como um sprite 270px à esquerda e 450px abaixo do canto superior esquerdo da nossa área de jogo.
Fazendo nosso jogo se mover
Até agora, isso dificilmente pode ser chamado de jogo. Por um lado, não podemos mover nossa peça do jogo. Para poder mudar as coisas em nosso jogo, teremos que adicionar uma função de atualização. Também teremos que ajustar a cena na variável de configuração para dizer ao jogo qual função será executada quando atualizarmos o jogo.
Adicionar uma função de atualização
Nova cena na configuração:
scene: {
preload: preload,
create: create,
update: update
}
Em seguida, adicione uma função de atualização abaixo da função de criação:
function update(){
}
Obtendo entradas importantes
Para permitir que o jogador controle a peça do jogo com as setas do teclado, teremos que adicionar uma variável para rastrear quais teclas o jogador está pressionando. Declare uma variável chamada keyInputs abaixo de onde declaramos gamePieces. Declará-lo ali permitirá que todas as funções acessem a nova variável.
var gamePiece;
var keyInputs;
A variável keyInput deve ser inicializada quando o jogo é criado na função de criação.
function create(){
gamePiece = this.physics.add.sprite(270, 450, 'gamePiece');
keyInputs = this.input.keyboard.createCursorKeys();
}
Agora, na função de atualização, podemos verificar se o jogador está pressionando uma tecla de seta e, se estiver, mover nossa peça do jogo de acordo. No exemplo abaixo, a peça do jogo é movida 2px, mas você pode torná-la um número maior ou menor. Mover a peça 1px por vez pareceu um pouco lento.
function update(){
if(keyInputs.left.isDown){
gamePiece.x = gamePiece.x - 2;
}
if(keyInputs.right.isDown){
gamePiece.x = gamePiece.x + 2;
}
if(keyInputs.up.isDown){
gamePiece.y = gamePiece.y - 2;
}
if(keyInputs.down.isDown){
gamePiece.y = gamePiece.y + 2;
}
}
O jogo agora tem um personagem móvel! Mas para realmente ser um jogo, precisamos de um objetivo. Vamos adicionar alguns obstáculos. Evitar obstáculos era a base de muitos jogos da era dos 8 bits.
Adicionando Obstáculos ao Jogo
Este exemplo de código usa dois sprites de obstáculo chamados obstáculo1 e obstáculo 2. obstáculo1 é um quadrado azul e obstáculo2 é verde. Cada imagem precisará ser pré-carregada assim como o sprite da peça de jogo.
function preload(){
this.load.image('gamePiece', 'img/gamePiece.png');
this.load.image('obstacle1', 'img/obstacle1.png');
this.load.image('obstacle2', 'img/obstacle2.png');
}
Então, cada sprite de obstáculo precisará ser inicializado na função de criação, assim como a peça de jogo.
function create(){
gamePiece = this.physics.add.sprite(270, 450, 'gamePiece');
keyInputs = this.input.keyboard.createCursorKeys();
obstacle1 = this.physics.add.sprite(200, 0, 'obstacle1');
obstacle2 = this.physics.add.sprite(0, 200, 'obstacle2');
}
Fazendo o movimento dos obstáculos
Para mover as peças desta vez, não queremos usar a entrada do jogador. Em vez disso, vamos mover uma peça de cima para baixo e a outra da esquerda para a direita. Para fazer isso, adicione o seguinte código à função de atualização:
obstacle1.y = obstacle1.y + 4;
if(obstacle1.y > 600){
obstacle1.y = 0;
obstacle1.x = Phaser.Math.Between(0, 600);
}
obstacle2.x = obstacle2.x + 4;
if(obstacle2.x > 600){
obstacle2.x = 0;
obstacle2.y = Phaser.Math.Between(0, 600);
}
O código acima moverá obstacle1 para baixo na tela e obstacle2 pela área de jogo 4px cada quadro. Uma vez que um quadrado está fora da tela, ele é movido de volta para o lado oposto em um novo local aleatório. Isso garantirá que sempre haja um novo obstáculo para o jogador.
Detectando Colisões
Mas ainda não terminamos. Você deve ter notado que nosso jogador pode passar direto pelos obstáculos. Precisamos fazer o jogo detectar quando o jogador atinge um obstáculo e terminar o jogo.
A biblioteca de física Phaser possui um detector de colisor. Tudo o que precisamos fazer é inicializá-lo na função de criação.
this.physics.add.collider(gamePiece, obstacle1, function(gamePiece, obstacle1){
gamePiece.destroy();
obstacle.destroy();
obstacle2.destroy();
});
this.physics.add.collider(gamePiece, obstacle2, function(gamePiece, obstacle2){
gamePiece.destroy();
obstacle.destroy();
obstacle2.destroy();
});
O método do colisor requer três parâmetros. Os primeiros dois parâmetros identificam quais objetos estão colidindo. Acima, temos dois aceleradores configurados. O primeiro detecta quando a peça de jogo colide com o obstáculo1 e o segundo colisor está procurando colisões entre a peça de jogo e o obstáculo2.
O terceiro parâmetro informa ao colisor o que fazer quando detecta uma colisão. Neste exemplo, existe uma função. Se houver uma colisão, todos os elementos do jogo serão destruídos; isso interrompe o jogo. Agora o jogador terminará o jogo se bater em um obstáculo.
Experimente o desenvolvimento de jogos com Phaser
Este jogo pode ser melhorado e mais complexo de muitas maneiras diferentes. Nós criamos apenas um jogador, mas um segundo personagem jogável pode ser adicionado e controlado com os controles "awsd". Da mesma forma, você pode experimentar adicionar mais obstáculos e variar a velocidade de seus movimentos.
Esta introdução o ajudará a começar, mas ainda há muito mais a aprender. A grande vantagem do Phaser é que grande parte da física do jogo é feita para você. É uma ótima maneira fácil de começar a projetar jogos 2D. Continue a construir neste código e refinar seu jogo.
Se você encontrar algum erro, o depurador do navegador é uma ótima maneira de descobrir o problema.