O que estamos codificando
Aqui está a demonstração finalizada, para você ter uma ideia do que estamos criando:
<
div data-content-block-type=”Wysi” id=”iomw”>
Comece com a IU
Começaremos criando a interface. Este será um design minimalista com o saldo (quanto crédito há para jogar) e três rolos.
O contêiner geral vem primeiro, então adicione um
elemento em seu arquivo html.
<
div class=”rouge-syntax-highlight”>
1 |
|
2 |
|
3 |
|
Em um novo
adicione um
pelo título e por um
para exibir o saldo.
1 |
|
2 |
|
3 |
|
4 |
|
Provavelmente a parte mais importante do jogo de caça-níqueis são os rolos. Os rolos são as posições verticais em um slot que gira quando o jogo começa. Adicione um
elemento para conter as bobinas.
<
div class=”rouge-syntax-highlight”>
1 |
|
2 |
|
3 |
|
O contêiner terá três rolos, cada rolo contendo três símbolos. Usaremos emojis para eles, então use o que quiser:
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
Por último, precisaremos do botão para iniciar o jogo e de uma mensagem de BOA SORTE exibida com um
marcação.
1 |
|
2 |
|
3 |
|
4 |
|
Estilizando o jogo de caça-níqueis
Com a estrutura completa, vamos estilizá-la. Para o título estiloso precisaremos de uma fonte personalizada do Google Fonts, além de outra para as mensagens.
![caça-níqueis clássicos](https://i0.wp.com/cms-assets.tutsplus.com/cdn-cgi/image/width%3D850/uploads/users/30/posts/108974/image-upload/classic.jpg?ssl=1)
![caça-níqueis clássicos](https://i0.wp.com/cms-assets.tutsplus.com/cdn-cgi/image/width%3D630/uploads/users/30/posts/108974/image-upload/classic.jpg?ssl=1)
![caça-níqueis clássicos](https://i0.wp.com/cms-assets.tutsplus.com/cdn-cgi/image/width%3D360/uploads/users/30/posts/108974/image-upload/classic.jpg?ssl=1)
No seu arquivo CSS, adicione isto no topo.
1 |
import url("https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap"); |
2 |
@import url('https://fonts.googleapis.com/css2?family=Ultra&display=swap'); |
Em seguida, use flex para alinhar tudo ao centro, horizontal e verticalmente. Além disso, adicione a fonte universal e uma cor de fundo.
1 |
body { |
2 |
background: #121212; |
3 |
display: flex; |
4 |
justify-content: center; |
5 |
align-items: center; |
6 |
height: 100vh; |
7 |
font-family: "DM Mono", monospace; |
8 |
}
|
Adicione esses estilos adicionais para garantir que o conteúdo do cabeçalho tenha o estilo adequado e todo o conteúdo esteja alinhado.
1 |
.slot-machine { |
2 |
text-align: center; |
3 |
}
|
4 |
.header { |
5 |
margin-bottom: 20px; |
6 |
padding: 10px; |
7 |
}
|
8 |
.header h1 { |
9 |
font-family: "Ultra", serif; |
10 |
font-size: 6em; |
11 |
line-height: .9; |
12 |
margin: 0; |
13 |
color: #ebb701; |
14 |
max-width: 10ch; |
15 |
}
|
16 |
.header p { |
17 |
font-size: 1.2em; |
18 |
margin-top: 10px; |
19 |
color: white; |
20 |
}
|
Até agora temos isto:
![](https://i0.wp.com/cms-assets.tutsplus.com/cdn-cgi/image/width%3D850/uploads/users/1885/posts/108974/image-upload/slots_1_.png?ssl=1)
![](https://i0.wp.com/cms-assets.tutsplus.com/cdn-cgi/image/width%3D630/uploads/users/1885/posts/108974/image-upload/slots_1_.png?ssl=1)
![](https://i0.wp.com/cms-assets.tutsplus.com/cdn-cgi/image/width%3D360/uploads/users/1885/posts/108974/image-upload/slots_1_.png?ssl=1)
O próximo passo é adicionar estilos aos rolos para formar três colunas:
1 |
.reels-container { |
2 |
display: flex; |
3 |
justify-content: center; |
4 |
align-items: center; |
5 |
height: 60%; |
6 |
}
|
7 |
.reel { |
8 |
display: block; |
9 |
width: 130px; |
10 |
height: 210px; |
11 |
background-color: #3a3a3a; |
12 |
border-radius: 15px; |
13 |
overflow: hidden; |
14 |
margin: 0 10px; |
15 |
box-shadow: 0px 14px 15px -5px rgba(0,0,0,0.3) inset, |
16 |
1px -14px 15px -5px rgba(0,0,0,0.3) inset; |
17 |
border: 2px solid rgba(255,255,255,0.2); |
18 |
position: relative; |
19 |
}
|
Nos estilos acima, adicionamos display:flex
no contêiner de bobinas que garante que as bobinas estejam alinhadas por colunas. Além disso, para centralizar as bobinas, usamos justify-content: center;
e align-items: center;
.
Para cada bobina, temos largura e altura personalizadas e algumas outras propriedades, como box-shadow,
background-color,
e border-radius
para torná-lo mais atraente.
Também adicionamos alguns margin
para garantir que as bobinas estejam espaçadas no contêiner.
Os símbolos terão os seguintes estilos.
1 |
.symbol { |
2 |
font-size: 3em; |
3 |
height: 1.5em; |
4 |
opacity: 0.6; |
5 |
}
|
Por último, adicione estes estilos para o botão SPIN e o elemento que contém a mensagem BOA SORTE.
1 |
.controls .btn { |
2 |
margin: 3em 0 1em 0; |
3 |
}
|
4 |
.controls .message { |
5 |
font-size: 1.5em; |
6 |
color: #ebb701; |
7 |
}
|
Obtenha os elementos com o DOM
Obtenha todos os elementos DOM que precisarão de manipulação. No topo do seu arquivo JS, adicione este código.
1 |
const reels = document.querySelectorAll(".reel"); |
2 |
const spinButton = document.querySelector(".spin_btn"); |
3 |
const messageDisplay = document.querySelector(".message"); |
4 |
const reelSound = document.getElementById("reelSound"); |
5 |
const winSound = document.getElementById("winSound"); |
A probabilidade de ganhar ao jogar numa slot machine pode ser muito baixa. Para aumentar as chances de ganhar, vamos criar uma série de estados de rolo parecidos com este:
1 |
deixar reelStates = [ |
2 |
[" |
3 |
[" |
4 |
[" |
5 |
];
|
No array, você pode ver que alguns símbolos aparecem mais que outros, isso é intencional para aumentar a probabilidade de vitória. Cada vez que um jogador quiser jogar este jogo, terá um saldo inicial de $ 1000 e sempre que girar a slot machine será deduzido do seu saldo um valor de $ 10.
Defina essas variáveis iniciais.
1 |
let spinning = false; |
2 |
let balance = 1000; |
3 |
let betAmount = 10; |
Também adicionamos uma variável spinning
que controlará se o jogo está girando ou não. O valor inicial será definido como falso (ou seja, não girando).
Para atualizar o saldo restante, crie uma função chamada updateBalanceDisplay()
e adicione o código abaixo. Esta função será chamada após cada giro.
1 |
function updateBalanceDisplay() { |
2 |
const balanceDisplay = document.querySelector(".balance"); |
3 |
balanceDisplay.textContent = `Balance: $${balance}`; |
4 |
}
|
Para fazer uma aposta ou girar o jogo, primeiro precisamos verificar se o saldo é adequado, ou seja, o saldo deve ser maior que o valor da aposta. Se o saldo for superior ao valor da aposta, o jogador terá a oportunidade de continuar jogando. Caso contrário, exibiremos a mensagem “Saldo insuficiente para fazer uma aposta!”.
Crie uma função chamada placeBet()
e adicione este código:
1 |
function placeBet() { |
2 |
if (balance >= betAmount) { |
3 |
balance -= betAmount; |
4 |
updateBalanceDisplay(); |
5 |
|
6 |
} else { |
7 |
alert("Not enough balance to place a bet!"); |
8 |
}
|
9 |
}
|
Anexe um ouvinte de evento ao botão giratório, para que quando o usuário clicar no botão, ele acione o placeBet()
função. O placeBet()
A função atualizará o equilíbrio e gerenciará a lógica de rotação e vitória.
Por enquanto, o placeBet()
atualiza apenas o saldo, atualizaremos o resto da lógica mais tarde.
Gire as bobinas
A característica mais importante da slot machine é a capacidade de girar os rolos. Atualmente, temos três colunas com cada coluna contendo 3 símbolos. A lógica de rotação envolverá a injeção de novos símbolos em cada rolo, quando a rotação começar. Uma vitória será determinada combinando três símbolos na mesma linha.
Para determinar o ciclo de rotação, ou seja, quantas vezes a bobina girará antes de parar, usaremos esta fórmula.
1 |
const spinCount = 10 + Math.floor(Math.random() * 5); |
Crie uma nova função chamada spinReel
e adicione a fórmula no topo da função. Esta função levará o reel
e index
como parâmetros.
1 |
function spinReel(reel, index) { |
2 |
const spinCount = 10 + Math.floor(Math.random() * 5); |
3 |
|
4 |
}
|
Para determinar o ponto de partida, partimos de 0. Este valor aumentará em 1 até o valor de spinCount
é alcançado. Inicialize o valor inicial usando currentSpin
e defina-o como 0. Este valor aumentará a cada giro até chegarmos ao valor de spinCount
.
1 |
function spinReel(reel, index) { |
2 |
const spinCount = 10 + Math.floor(Math.random() * 5); |
3 |
let currentSpin = 0; |
4 |
}
|
Para garantir que os rolos girem em intervalos diferentes, usaremos o setInterval()
função, que executa uma função especificada repetidamente após um determinado intervalo de tempo.
Para obter um efeito giratório, obteremos cada array de realStates
(uma matriz dimensional) e troque as posições dos elementos. Ao mesmo tempo, os elementos serão adicionados ao DOM, criando assim uma ilusão giratória.
Crie uma função chamada spinReel
adicione o spinCount
variável, inicializar currentSpin
para 0 e crie um intervalo que será executado a cada 50 milissegundos.
1 |
function spinReel(reel, index) { |
2 |
const spinCount = 10 + Math.floor(Math.random() * 5); |
3 |
let currentSpin = 0; |
4 |
console.log(spinCount); |
5 |
const interval = setInterval(() => {}, 50 + index * 50); |
6 |
}
|
Cada matriz no reelStates
array contém 6 símbolos. Para criar a ilusão de girar, pegaremos o último item do array e o moveremos para o início (ou seja, giraremos o último elemento para a frente).
Após alterar a ordem dos símbolos na matriz, eles serão adicionados ao DOM para efetuar a rotação. Essa mudança repentina na posição dos símbolos criará o efeito visual de rotação.
Atualize o código dentro do setInterval()
funcionar conforme mostrado abaixo.
1 |
const interval = setInterval(() => { |
2 |
console.log(reelStates[index]); |
3 |
reelStates[0].unshift(reelStates[0].pop()); |
4 |
reel.innerHTML = ""; |
5 |
reelStates[index].forEach((symbol) => { |
6 |
const symbolDiv = document.createElement("div"); |
7 |
symbolDiv.classList.add("symbol"); |
8 |
symbolDiv.textContent = symbol; |
9 |
reel.appendChild(symbolDiv); |
10 |
});
|
11 |
currentSpin++; |
12 |
|
13 |
}, 50 + index * 50); |
14 |
}
|
Vamos detalhar o código acima: Por exemplo, para índice =0:
-
reelstates[index].pop()
remove o último elemento do primeiro array ( [“”, “
”, “
”, “
”, “
”, “
”] ) e o retorna. O último elemento neste caso é “
. Agora reelStates[index] tem apenas 5 itens.
-
reelStates[index].unshift()
adiciona o elemento retornado (“) de volta ao array no início do array. Este processo de remoção e adição de elementos ao array ocorrerá a cada 50 milissegundos mais um valor escalonado adicional com base no índice do rolo.
- Após a atualização de cada array, também atualizamos o DOM para simular o efeito giratório. Em seguida, incrementamos o valor do giro criando um giro infinito.
Em algum momento, precisamos parar a rotação para que aconteça uma vitória ou uma derrota. Para fazer isso, verificaremos se o valor do giro atual é maior ou igual à contagem de giros e, em caso afirmativo, limparemos o intervalo. Limpar o intervalo significa que os rolos irão parar de girar.
Atualize o código da seguinte maneira:
1 |
function spinReel(reel, index) { |
2 |
const spinCount = 10 + Math.floor(Math.random() * 5); |
3 |
let currentSpin = 0; |
4 |
console.log(spinCount); |
5 |
const interval = setInterval(() => { |
6 |
reelStates[index].unshift(reelStates[index].pop()); |
7 |
reel.innerHTML = ""; |
8 |
reelStates[index].forEach((symbol) => { |
9 |
const symbolDiv = document.createElement("div"); |
10 |
symbolDiv.classList.add("symbol"); |
11 |
symbolDiv.textContent = symbol; |
12 |
reel.appendChild(symbolDiv); |
13 |
});
|
14 |
currentSpin++; |
15 |
if (currentSpin >= spinCount) { |
16 |
clearInterval(interval); |
17 |
if (index === reels.length - 1) { |
18 |
spinning = false; |
19 |
|
20 |
|
21 |
}
|
22 |
}
|
23 |
}, 50 + index * 50); |
24 |
}
|
O spinReel()
a função funcionará apenas para uma bobina. Em vez de invocar a função três vezes, crie uma função chamada spinReels
que irá girar todos os rolos.
1 |
function spinReels() { |
2 |
if (spinning) return; |
3 |
spinning = true; |
4 |
reelSound.play(); |
5 |
messageDisplay.textContent = "Spinning........."; |
6 |
reels.forEach((reel, index) => { |
7 |
spinReel(reel, index); |
8 |
});
|
9 |
}
|
Nesta função, primeiro verificamos se as bobinas já estão girando com a variável spinning. Se os rolos estiverem girando, nenhuma ação adicional ocorrerá e a função retornará no ponto. Se os rolos estiverem girando, definimos a variável de giro como verdadeira, exibimos uma mensagem e giramos todos os rolos enquanto o reelSound
o som está tocando, dando um indicador de que as bobinas estão girando.
No placeBet()
função, chame o spinReels()
função para que quando o botão for clicado, os rolos comecem a girar.
1 |
function placeBet() { |
2 |
if (balance >= betAmount) { |
3 |
balance -= betAmount; |
4 |
updateBalanceDisplay(); |
5 |
spinReels(); |
6 |
} else { |
7 |
alert("Not enough balance to place a bet!"); |
8 |
}
|
9 |
}
|
Verifique se há uma vitória
Numa slot machine, o jogo é considerado uma vitória se um jogador acertar os símbolos consecutivos. Vamos implementar essa lógica. Depois que os rolos pararem, obteremos os símbolos exibidos atualmente para as 2 primeiras linhas e, em seguida, verificaremos se há um par correspondente no tabuleiro. Se for encontrada uma correspondência, atualizaremos o saldo e reproduziremos o som vencedor.
No entanto, se não ocorrer nenhum símbolo correspondente em uma linha, exibiremos uma mensagem incentivando o usuário a tentar novamente.
1 |
function checkWin() { |
2 |
const [reel1, reel2, reel3] = reelStates.map((reel) => reel[0]); |
3 |
const [reel4, reel5, reel6] = reelStates.map((reel) => reel[1]); |
4 |
|
5 |
if ( |
6 |
(reel1 === reel2 && reel2 === reel3) || |
7 |
(reel4 === reel5 && reel5 === reel6) |
8 |
) { |
9 |
const payout = betAmount * 5; |
10 |
balance += payout; |
11 |
console.log("win"); |
12 |
winSound.play(); |
13 |
messageDisplay.textContent = " "; |
14 |
} else { |
15 |
messageDisplay.textContent = "Try Again"; |
16 |
}
|
17 |
updateBalanceDisplay(); |
18 |
}
|
Atualize o spinReel()
funcionar de modo que o checkWin()
a função é chamada depois que os rolos param de girar.
1 |
function spinReel(reel, index) { |
2 |
//......
|
3 |
if (currentSpin >= spinCount) { |
4 |
clearInterval(interval); |
5 |
if (index === reels.length - 1) { |
6 |
spinning = false; |
7 |
reelSound.pause(); |
8 |
reelSound.currentTime = 0; |
9 |
checkWin(); |
10 |
}
|
11 |
}
|
12 |
//........
|
13 |
}
|
E terminamos! Aqui está o que construímos:
Próximas etapas
Para tornar o aplicativo de caça-níqueis ainda melhor, considere adicionar um rastreador de pontuação para acompanhar a pontuação mais alta. Você também pode adicionar animações para uma experiência do usuário mais envolvente. Aproveitar!