p5.js

Criando obstáculo do jogo com javascript e P5.play

No p5.js, o framecount (ou frameCount em código) é uma variável interna que conta o número de quadros (frames) que foram renderizados desde o início da execução do programa. Ele é útil para controlar ou sincronizar eventos ao longo do tempo em uma animação ou simulação.

Características do frameCount

No p5.js, o framecount (ou frameCount em código) é uma variável interna que conta o número de quadros (frames) que foram renderizados desde o início da execução do programa. Ele é útil para controlar ou sincronizar eventos ao longo do tempo em uma animação ou simulação.

  1. Incremento automático: O frameCount é incrementado automaticamente pelo p5.js a cada quadro renderizado.

  2. Começa em 0: Quando o programa inicia, o frameCount começa em 0 e aumenta em 1 a cada quadro.

  3. Taxa de quadros (frame rate): O valor do frameCount depende da taxa de quadros (frames por segundo, ou FPS) definida no programa. Por padrão, o p5.js tenta rodar a 60 FPS.

Explicando o jogo

Aqui está o jogo que usaremos como referência:

Passo 1: Configurando o ambiente

Antes de começarmos a programar, certifique-se de ter um ambiente de desenvolvimento configurado:

  • Um editor de código (VS Code)

  • Um navegador (Google Chrome)
  • Arquivo de template

Passo 2: Declaração de variáveis

Aqui, estamos declarando as variáveis que serão usadas para armazenar os sprites e suas imagens.

				
					// Personagem principal
var boy;

// Grupos de obstáculos e colecionáveis
var cashG, diamondsG, jwelleryG, swordGroup;

// Elementos do cenário
var path;

// Sistema de pontuação e estados
var treasureCollection = 0;
var gameState = "PLAY";

// Imagens do jogo
var pathImg, cashImg, diamondsImg, jwelleryImg, swordImg;

// Animação do personagem
var boyImg;

// Animação de fim de jogo
var endImg;
				
			

Passo 3: Função preload()

A função preload() é usada para carregar imagens e animações antes do jogo iniciar.

  • loadImage("Road.png"): Carrega a imagem da pista para ser usada como plano de fundo

  • loadAnimation("Runner-1.png","Runner-2.png"): Cria uma animação para o personagem usando uma sequência de imagens

  • loadImage("cash.png"): Carrega a imagem do item de dinheiro colecionável

  • loadImage("diamonds.png"): Carrega a imagem do item de diamante colecionável

  • loadImage("jwell.png"): Carrega a imagem do item de joia colecionável

  • loadImage("sword.png"): Carrega a imagem do obstáculo espada

  • loadAnimation("fimdeJogo.png"): Cria animação para a tela de fim de jogo

				
					function preload(){
cashImg = loadImage("cash.png");
diamondsImg = loadImage("diamonds.png"); 
jwelleryImg = loadImage("jwell.png");
swordImg = loadImage("sword.png");
endImg = loadAnimation("fimdeJogo.png");
}
				
			

Passo 4: Função setup()

A função setup() é executada apenas uma vez e configura o ambiente do jogo.

  • createCanvas(400,600): Cria um canvas de 400×600 pixels.

				
					function setup(){
  createCanvas(400,600);
 
				
			

Agora criamos o sprite do fundo da pista:

				
					  // Criando o fundo da pista
  path = createSprite(200,200);
  path.addImage(pathImg);
  path.velocityY = 4;
  path.scale = 1.2;
				
			
  • createSprite(200,200): Cria um sprite posicionado no centro da tela.
  • addImage(pathImg): Adiciona a imagem da pista ao sprite.
  • velocityY = 4: Faz com que a pista se mova para baixo.
  • scale = 1.2: Ajusta o tamanho da imagem.

Agora criamos o sprite do corredor:

				
					  // Criando o personagem principal
  boy = createSprite(180,340,30,30);
  boy.scale = 0.08;
  boy.addAnimation("JakeRunning", boyImg);
				
			
  • createSprite(180,340,30,30): Cria o sprite do personagem na posição inicial.
  • addAnimation("JakeRunning", boyImg): Adiciona a animação ao sprite.
  • scale = 0.08: Reduz o tamanho do sprite.

Criamos também os sprites das bordas:

				
					leftBoundary = createSprite(0,0,100,800);
leftBoundary.visible = false;

rightBoundary = createSprite(410,0,100,800);
rightBoundary.visible = false;
				
			
  • createSprite(0,0,100,800): Cria um sprite para a borda esquerda.
  • createSprite(410,0,100,800): Cria um sprite para a borda direita.
  • visible = false: Torna os sprites invisíveis para que não sejam vistos na tela, mas ainda funcionem como barreiras.

E criamos também os grupos dos sprites:

				
					  // Inicializa grupos
  cashG = new Group();
  diamondsG = new Group();
  jwelleryG = new Group();
  swordGroup = new Group();
  
  }
				
			
  • cashG = new Group(): cria o grupo das notas de dinheiro.
  • diamondsG = new Group(): cria o grupo dos diamantes.
  • jwelleryG = new Group(): cria o grupo das joias.
  • swordGroup = new Group(): cria o grupo das espadas.

Passo 5: Função draw()

A função draw() é chamada continuamente para atualizar a tela do jogo e manter a animação fluida.

  • background(0): Define o fundo como preto.
				
					function draw() {
  background(0);

				
			

Agora, precisamos garantir que o ao iniciar o jogo, quando o estado de jogo for “PLAY”, a função PLAY() seja chamada:

				
					  if(gameState === "PLAY"){
    PLAY();
  }
				
			
  • gameState === "PLAY": Executa a lógica principal do jogo

Quando o jogador perder, o estado de jogo será “END”, a função END() será chamada:

				
					  if(gameState === "END"){
    END();
  }
				
			
  • gameState === "END": Executa a rotina de fim de jogo

Desenhamos todos os sprites na tela:

				
					 drawSprites();

				
			
  • drawSprites(): Exibe todos os sprites criados na tela do jogo, garantindo que a animação seja atualizada a cada quadro.

Por fim, exibimos a pontuação na tela:

				
					  textSize(20);
  fill(255);
  text("Tesouro: "+ treasureCollection, 150, 30);
}
				
			
  • textSize(20): Define tamanho da fonte

  • fill(255): Cor branca para o texto

  • text(): Exibe a pontuação atual na posição (150,30)

Passo 6: Criando a função para gerar as notas de dinhero

A função createCash() é chamada continuamente para criar os objetos de dinheiro na tela do jogo.

  • frameCount % 200 == 0: Cria um novo objeto de dinheiro a cada 200 quadros

  • random(50, 350): Faz com que o dinheiro apareça em posições aleatórias no eixo X.

  • createSprite(random(50, 350),40, 10, 10): Cria o sprite na posição definida.

  • addImage(cashImg): Aplica a imagem do dinheiro ao sprite

  • scale=0.12: Define o tamanho do sprite.

  • velocityY = 3: Define a velocidade de queda.

  • lifetime = 150: Evita consumo excessivo de memória ao remover sprites antigos.

  • cashG.add(cash): Adiciona o objeto ao grupo de dinheiro para gerenciamento coletivo

				
					function createCash() {
  if (frameCount % 200 == 0) {
    var cash = createSprite(Math.round(random(50, 350)),40, 10, 10);
    cash.addImage(cashImg);
    cash.scale = 0.12;
    cash.velocityY = 3;
    cash.lifetime = 150;
    cashG.add(cash);
  }
}
				
			

Passo 7: Criando a função para gerar os diamantes

A função createDiamonds() é chamada continuamente para criar os diamantes na tela do jogo.

  • frameCount % 320 == 0: Cria um novo diamante a cada 320 quadros

  • random(50, 350): Faz com que o dinheiro apareça em posições aleatórias no eixo X.

  • createSprite(random(50, 350),40, 10, 10): Cria o sprite na posição definida.

  • addImage(diamondsImg): Aplica a imagem do diamante

  • scale=0.03: Define o tamanho do sprite.

  • velocityY = 3: Define a velocidade de queda.

  • lifetime = 150: Evita consumo excessivo de memória ao remover sprites antigos.

  • diamondsG.add(diamonds): Adiciona ao grupo de diamantes para controle coletivo

				
					function createDiamonds() {
  if (frameCount % 320 == 0) {
    var diamonds = createSprite(Math.round(random(50, 350)),40, 10, 10);
    diamonds.addImage(diamondsImg);
    diamonds.scale = 0.03;
    diamonds.velocityY = 3;
    diamonds.lifetime = 150;
    diamondsG.add(diamonds);
  }
}
				
			

Passo 8: Criando a função para gerar as joias

A função createJwellery() é chamada continuamente para criar as joias na tela do jogo.

  • frameCount % 320 == 0: Cria um novo diamante a cada 320 quadros

  • random(50, 350): Faz com que o dinheiro apareça em posições aleatórias no eixo X.

  • createSprite(random(50, 350),40, 10, 10): Cria o sprite na posição definida.

  • addImage(jwelleryImg): Aplica a imagem da joia

  • scale=0.13: Define o tamanho do sprite.

  • velocityY = 3: Define a velocidade de queda.

  • lifetime = 150: Evita consumo excessivo de memória ao remover sprites antigos.

  • jwelleryG.add(jwellery): Adiciona ao grupo de joias para gerenciamento

				
					function createJwellery() {
  if (frameCount % 410 == 0) {
    var jwellery = createSprite(Math.round(random(50, 350)),40, 10, 10);
    jwellery.addImage(jwelleryImg);
    jwellery.scale = 0.13;
    jwellery.velocityY = 3;
    jwellery.lifetime = 150;
    jwelleryG.add(jwellery);
  }
}
				
			

Passo 9: Criando a função para gerar as espadas

A função createSword() é chamada continuamente para criar as joias na tela do jogo.

  • frameCount % 530 == 0: Cria uma nova espada a cada 530 quadros

  • random(50, 350): Faz com que o dinheiro apareça em posições aleatórias no eixo X.

  • createSprite(random(50, 350),40, 10, 10): Cria o sprite na posição definida.

  • addImage(swordImg): Aplica a imagem da espada

  • scale=0.1: Define o tamanho do sprite.

  • velocityY = 3: Define a velocidade de queda.

  • lifetime = 150: Evita consumo excessivo de memória ao remover sprites antigos.

  • swordGroup.add(sword): Adiciona ao grupo de espadas para controle coletivo

				
					function createSword(){
  if (frameCount % 530 == 0) {
    var sword = createSprite(Math.round(random(50, 350)),40, 10, 10);
    sword.addImage(swordImg);
    sword.scale = 0.1;
    sword.velocityY = 3;
    sword.lifetime = 150;
    swordGroup.add(sword);
  }
}
				
			

Passo 10: Função PLAY()

A função PLAY() contém toda a lógica do jogo quando o estado está ativo.

				
					function PLAY(){
  boy.x = World.mouseX;
				
			
  • boy.x = World.mouseX: Faz o personagem principal seguir horizontalmente a posição do mouse.

Agora, precisamos garantir que o fundo volte ao início quando sair da tela:

				
					  if(path.y > 400 ){
    path.y = height / 2;
  }
				
			
  • if(path.y > 400): Verifica se o sprite do caminho saiu da tela.
  • path.y = height / 2;: Reposiciona o caminho para criar um efeito infinito.

Adicionando colisão do corredor nas bordas:

				
					 boy.collide(leftBoundary);
 boy.collide(rightBoundary);
				
			
  • boy.collide(leftBoundary): Verifica a colisão do corredor com a borda da esquerda.
  • boy.collide(rightBoundary): Verifica a colisão do corredor com a borda da direita.

Chama as funções que criam os diferentes tipos de objetos:

				
					  createCash();
  createDiamonds();
  createJwellery();
  createSword();
				
			
  • createCash(): cria as notas de dinheiro.
  • createDiamonds(): cria os diamantes.
  • createJwellery(): cria as joais.
  • createSword(): cria as espadas.

Coletando as notas de dinheiro:

				
					if (cashG.isTouching(boy)) {
  cashG.destroyEach();
  treasureCollection = treasureCollection + 50;
}
				
			
  • if(cashG.isTouching(boy)): Verifica se o personagem (boy) tocou algum objeto do grupo de dinheiro (cashG).

  • cashG.destroyEach(): Remove os sprites de dinheiro que colidiram com o personagem.

  • treasureCollection = treasureCollection + 50: Adiciona 50 pontos ao contador de tesouro.

Coletando os diamantes:

				
					if (diamondsG.isTouching(boy)) {
  diamondsG.destroyEach();
  treasureCollection = treasureCollection + 100;
}
				
			
  • if(diamondsG.isTouching(boy)): Verifica se o personagem tocou algum diamante (diamondsG).

  • diamondsG.destroyEach(): Remove os diamantes coletados.

  • treasureCollection = treasureCollection + 100: Adiciona 100 pontos (valor maior que dinheiro).

Coletando as joias:

				
					if (jwelleryG.isTouching(boy)) {
  jwelleryG.destroyEach();
  treasureCollection = treasureCollection + 150;
}
				
			
  • if(jwelleryG.isTouching(boy)): Verifica se o personagem tocou alguma joia (jwelleryG).

  • jwelleryG.destroyEach(): Remove as joias coletadas.

  • treasureCollection = treasureCollection + 150: Adiciona 150 pontos (item mais valioso).

Detectando a colisão com as espadas:

				
					if (swordGroup.isTouching(boy)) {
  gameState = "END";
}
				
			
  • if(swordGroup.isTouching(boy)): Verifica se o personagem tocou alguma espada (swordGroup).

  • gameState = "END": Encerra o jogo, mudando seu estado para “END”.

Passo 11: Função END()

A função END() contém toda a lógica do jogo quando está no fim.

				
					function END() {
				
			

Agora, precisamos criar a animação e nova posição do jogador quando perder o jogo:

				
					  boy.addAnimation("SahilRunning", endImg);
  boy.x = 200;
  boy.y = 300;
  boy.scale = 0.6;
				
			
  • boy.addAnimation("SahilRunning", endImg): Define uma nova animação para o jogador.

  • boy.x = 200 e boy.y = 300: Reposiciona o personagem nas coordenadas x=200 e y=300 na tela.

  • boy.scale = 0.6: Redimensiona o personagem.

Destruindo os grupos de objetos:

				
					  cashG.destroyEach();
  diamondsG.destroyEach();
  jwelleryG.destroyEach();
  swordGroup.destroyEach();
				
			
  • cashG.destroyEach(): Remove todos os sprites de dinheiro (cashG) da tela.

  • diamondsG.destroyEach(): Remove todos os diamantes (diamondsG) da tela.

  • jwelleryG.destroyEach(): Remove todas as joias (jwelleryG) da tela.

  • swordGroup.destroyEach(): Remove todas as espadas (swordGroup) da tela.

Agora, precisamos garantir que o fundo volte ao início quando sair da tela:

				
					  if(path.y > 400 ){
    path.y = height / 2;
  }
				
			
  • if(path.y > 400): Verifica se o sprite do caminho saiu da tela.
  • path.y = height / 2;: Reposiciona o caminho para criar um efeito infinito.

Por fim, retirando a velocidade dos objetos:

				
					  cashG.setVelocityYEach(0);
  diamondsG.setVelocityYEach(0);
  jwelleryG.setVelocityYEach(0);
  swordGroup.setVelocityYEach(0);
				
			
  • cashG.setVelocityYEach(0): Define a velocidade vertical (Y) dos objetos de dinheiro como 0 (para evitar que continuem se movendo após o fim do jogo).

  • diamondsG.setVelocityYEach(0): Faz o mesmo para os diamantes.

  • jwelleryG.setVelocityYEach(0): Paralisa as joias.

  • swordGroup.setVelocityYEach(0):Paralisa as espadas.

Posts Similares

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *