Discover how to integrate five popular mini-games such as Snake, Morpion, Pong, Breakout and a reflex game directly into your Webflow site.
Dive into a world of online fun and discover how to add a touch of interactive entertainment to your Webflow site! In this exciting article, we provide you with codes to integrate five popular mini-games directly into your site. Whether you're a developer looking to liven up your portfolio or a site owner looking to provide a memorable experience for your visitors, these classic games are sure to get your users excited and engaged.
Imagine your visitors browsing your site and discovering a section dedicated to a classic game. Not only will they be able to read about these nostalgic games, but they will also be able to play them instantly, without leaving your site. Mini-games offer a unique opportunity to combine entertainment and content, making your site memorable and encouraging users to spend more time there.
Attention: The games are only available on Computer and work with the keys of your keyboard
Each set includes an HTML structure and CSS styles that you can either copy or reproduce in the Webflow Project Designer by adding the script then in the custom code of the page settings.
Integrate the Snake game in Webflow
Discover how to add a playful touch to your Webflow site by integrating the famous Snake game! With just a few lines of code, you can offer your users a captivating retro experience. Immerse yourself in the action of the Snake game directly from your site and let your visitors be entertained by this timeless classic.
Code used:
<style>
@media screen and (max-width: 992px) {
#snakeContainer {
display: none !important;
}
}
#snakeContainer {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 31.25rem;
margin: 0 auto;
}
#snakeScoreWrapper {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 1rem;
}
#snakeCanvas {
border: 1px solid #00FF00;
background-color: #101010;
}
#snakeScore {
font-size: 1rem;
}
#snakeBestScore {
font-size: 1rem;
color: #666;
}
#snakeRestartButton {
font-size: 1rem;
padding: 0.625rem 1rem;
background-color: #333;
color: #FFF;
border: none;
cursor: pointer;
position: absolute;
display: block;
}
#snakeRestartButton:hover {
background-color: #666;
}
</style>
<div id="snakeContainer">
<canvas id="snakeCanvas" width="500" height="500"></canvas>
<button id="snakeRestartButton" onclick="startGame()">Jouer</button>
<div id="snakeScoreWrapper">
<div id="snakeScore">Score : 0</div>
<div id="snakeBestScore">Meilleur Score : 0</div>
</div>
</div>
<script>
// Récupérer le canvas et son contexte
const canvas = document.getElementById("snakeCanvas");
const context = canvas.getContext("2d");
// Taille d'une cellule du jeu
const cellSize = 20;
// Initialiser la position du serpent et sa direction
let snake = [{ x: 10, y: 10 }];
let direction = "right";
// Initialiser la position de la nourriture
let food = { x: 5, y: 5 };
// Initialiser le score
let score = 0;
let bestScore = 0;
// Variable pour stocker la boucle de jeu
let gameLoop;
// Fonction pour dessiner le serpent
function drawSnake() {
context.fillStyle = "#00FF00";
snake.forEach((segment) => {
context.fillRect(segment.x * cellSize, segment.y * cellSize, cellSize, cellSize);
});
}
// Fonction pour dessiner la nourriture
function drawFood() {
context.fillStyle = "#FF0000";
context.fillRect(food.x * cellSize, food.y * cellSize, cellSize, cellSize);
}
// Fonction pour dessiner le score
function drawScore() {
document.getElementById("snakeScore").textContent = `Score : ${score}`;
document.getElementById("snakeBestScore").textContent = `Meilleur Score : ${bestScore}`;
}
// Fonction pour mettre à jour le jeu à chaque frame
function update() {
// Effacer le canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Mettre à jour la position du serpent en fonction de la direction
const head = { x: snake[0].x, y: snake[0].y };
switch (direction) {
case "up":
head.y--;
break;
case "down":
head.y++;
break;
case "left":
head.x--;
break;
case "right":
head.x++;
break;
}
snake.unshift(head);
// Vérifier si le serpent a mangé la nourriture
if (head.x === food.x && head.y === food.y) {
// Générer une nouvelle position pour la nourriture
food.x = Math.floor(Math.random() * canvas.width / cellSize);
food.y = Math.floor(Math.random() * canvas.height / cellSize);
// Augmenter le score
score++;
// Mettre à jour le meilleur score si nécessaire
if (score > bestScore) {
bestScore = score;
}
} else {
// Supprimer la dernière cellule du serpent s'il n'a pas mangé de nourriture
snake.pop();
}
// Vérifier si le serpent a atteint les bords du canvas ou s'est mordu la queue
if (
head.x < 0 ||
head.y < 0 ||
head.x >= canvas.width / cellSize ||
head.y >= canvas.height / cellSize ||
hasSelfCollision()
) {
// Arrêter le jeu
clearInterval(gameLoop);
// Afficher le score final
alert(`Game Over! Votre score est de ${score}`);
// Afficher le bouton de redémarrage
document.getElementById("snakeRestartButton").style.display = "block";
}
// Dessiner le serpent, la nourriture et le score
drawSnake();
drawFood();
drawScore();
}
// Fonction pour vérifier si le serpent s'est mordu la queue
function hasSelfCollision() {
const head = snake[0];
for (let i = 1; i < snake.length; i++) {
if (snake[i].x === head.x && snake[i].y === head.y) {
return true;
}
}
return false;
}
// Fonction pour gérer les événements de touche
function handleKeyPress(event) {
// Mettre à jour la direction en fonction de la touche pressée
switch (event.key) {
case "ArrowUp":
if (direction !== "down") {
direction = "up";
}
break;
case "ArrowDown":
if (direction !== "up") {
direction = "down";
}
break;
case "ArrowLeft":
if (direction !== "right") {
direction = "left";
}
break;
case "ArrowRight":
if (direction !== "left") {
direction = "right";
}
break;
}
}
// Fonction pour démarrer le jeu
function startGame() {
// Réinitialiser les variables
snake = [{ x: 10, y: 10 }];
direction = "right";
score = 0;
// Masquer le bouton de redémarrage
document.getElementById("snakeRestartButton").style.display = "none";
// Démarrer la boucle de jeu
gameLoop = setInterval(update, 1000 / 8);
}
// Écouter les événements de touche
document.addEventListener("keydown", handleKeyPress);
</script>
Integrate a Tic-Tac-Toe on your Webflow site
Add a competitive dimension to your Webflow site by integrating the Tic-tac-toe game! Allow your users to challenge each other with this strategic and fun game. In a few simple steps, you can offer an interactive experience where visitors can compete against an online bot.
Code used:
<style>
@media screen and (max-width: 992px) {
#tictactoeContainer {
display: none !important;
}
}
#tictactoeContainer {
width: 28.125rem;
margin: 0 auto;
}
table {
border-collapse: collapse;
margin: 1.25rem auto;
background-color: #101010;
}
td {
width: 9.375rem;
height: 9.375rem;
text-align: center;
font-size: 4.5rem;
border: 1px solid #333;
cursor: pointer;
}
#tictactoe-scoreboard {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 1rem;
}
#tictactoe-scoreboard span {
margin-right: 0.625rem;
}
.player-symbol, .bot-symbol {
color: #fdd33c;
}
</style>
<div id="tictactoeContainer">
<table>
<tr>
<td id="tictactoe-cell-0-0"></td>
<td id="tictactoe-cell-0-1"></td>
<td id="tictactoe-cell-0-2"></td>
</tr>
<tr>
<td id="tictactoe-cell-1-0"></td>
<td id="tictactoe-cell-1-1"></td>
<td id="tictactoe-cell-1-2"></td>
</tr>
<tr>
<td id="tictactoe-cell-2-0"></td>
<td id="tictactoe-cell-2-1"></td>
<td id="tictactoe-cell-2-2"></td>
</tr>
</table>
<div id="tictactoe-scoreboard">
<span id="tictactoe-player-score">Joueur : 0</span>
<span id="tictactoe-draw-score">Matchs nuls : 0</span>
<span id="tictactoe-bot-score">Bot : 0</span>
</div>
</div>
<script>
// Variable pour suivre l'état du tour (true = tour du joueur, false = tour du bot)
let tictactoePlayerTurnFlag = true;
// Tableau représentant la grille du jeu
let tictactoeBoard = [
["", "", ""],
["", "", ""],
["", "", ""]
];
// Symboles utilisés pour les joueurs et le bot
const tictactoePlayerSymbol = "X";
const tictactoeBotSymbol = "O";
// Compteurs de victoires du joueur, des matchs nuls et du bot
let tictactoePlayerWins = 0;
let tictactoeDraws = 0;
let tictactoeBotWins = 0;
// Fonction pour afficher la grille du jeu
function tictactoeDisplayBoard() {
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const cell = document.getElementById(`tictactoe-cell-${i}-${j}`);
cell.textContent = tictactoeBoard[i][j];
// Ajouter la classe appropriée en fonction du symbole
if (tictactoeBoard[i][j] === tictactoePlayerSymbol) {
cell.classList.add("player-symbol");
} else if (tictactoeBoard[i][j] === tictactoeBotSymbol) {
cell.classList.add("bot-symbol");
}
}
}
}
// Ajouter les gestionnaires d'événements de clic une seule fois, au chargement de la page
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const cell = document.getElementById(`tictactoe-cell-${i}-${j}`);
cell.addEventListener("click", () => {
tictactoePlayerTurn(i, j);
});
}
}
// Fonction pour mettre à jour le scoreboard
function tictactoeUpdateScoreboard() {
document.getElementById("tictactoe-player-score").textContent = `Joueur : ${tictactoePlayerWins}`;
document.getElementById("tictactoe-draw-score").textContent = `Matchs nuls : ${tictactoeDraws}`;
document.getElementById("tictactoe-bot-score").textContent = `Bot : ${tictactoeBotWins}`;
}
// Fonction pour vérifier si un joueur a gagné
function tictactoeCheckWinner(symbol) {
// Vérification des lignes
for (let i = 0; i < 3; i++) {
if (
tictactoeBoard[i][0] === symbol &&
tictactoeBoard[i][1] === symbol &&
tictactoeBoard[i][2] === symbol
) {
return true;
}
}
// Vérification des colonnes
for (let j = 0; j < 3; j++) {
if (
tictactoeBoard[0][j] === symbol &&
tictactoeBoard[1][j] === symbol &&
tictactoeBoard[2][j] === symbol
) {
return true;
}
}
// Vérification des diagonales
if (
tictactoeBoard[0][0] === symbol &&
tictactoeBoard[1][1] === symbol &&
tictactoeBoard[2][2] === symbol
) {
return true;
}
if (
tictactoeBoard[0][2] === symbol &&
tictactoeBoard[1][1] === symbol &&
tictactoeBoard[2][0] === symbol
) {
return true;
}
return false;
}
// Fonction pour vérifier si la grille est complètement remplie (match nul)
function tictactoeCheckDraw() {
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (tictactoeBoard[i][j] === "") {
return false;
}
}
}
return true;
}
// Fonction pour le tour du joueur
function tictactoePlayerTurn(row, col) {
if (tictactoePlayerTurnFlag && tictactoeBoard[row][col] === "") {
tictactoeBoard[row][col] = tictactoePlayerSymbol;
tictactoeDisplayBoard();
if (tictactoeCheckWinner(tictactoePlayerSymbol)) {
setTimeout(() => {
alert("Tu as gagné !");
tictactoePlayerWins++;
tictactoeUpdateScoreboard();
tictactoeResetGame();
}, 100);
} else if (tictactoeCheckDraw()) {
setTimeout(() => {
alert("Match Nul !");
tictactoeDraws++;
tictactoeUpdateScoreboard();
tictactoeResetGame();
}, 100);
} else {
// Switch the turn to the bot
tictactoePlayerTurnFlag = false;
setTimeout(tictactoeBotTurn, 500);
}
}
}
// Fonction pour le tour du bot
function tictactoeBotTurn() {
// Vérifier si le jeu est déjà terminé
if (tictactoeCheckWinner(tictactoePlayerSymbol) || tictactoeCheckWinner(tictactoeBotSymbol) || tictactoeCheckDraw()) {
return;
}
let bestScore = -Infinity;
let bestMove;
// Parcourir toutes les cellules disponibles
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (tictactoeBoard[i][j] === "") {
// Effectuer un mouvement temporaire pour évaluer son score
tictactoeBoard[i][j] = tictactoeBotSymbol;
// Ajouter une logique de chance pour faire un mauvais coup
if (Math.random() < 0.01) {
// Mauvais coup : Choisir une cellule aléatoire parmi les disponbiles
bestMove = { row: i, col: j };
} else {
// Bon coup : Utiliser l'algorithme minimax pour trouver le meilleur mouvement
let score = tictactoeMinimax(tictactoeBoard, 0, false);
// Mettre à jour le meilleur score et le meilleur mouvement
if (score > bestScore) {
bestScore = score;
bestMove = { row: i, col: j };
}
}
tictactoeBoard[i][j] = ""; // Annuler le mouvement temporaire
}
}
}
// Effectuer le meilleur mouvement
const { row, col } = bestMove;
tictactoeBoard[row][col] = tictactoeBotSymbol;
tictactoeDisplayBoard();
if (tictactoeCheckWinner(tictactoeBotSymbol)) {
setTimeout(() => {
alert("Le bot a gagné !");
tictactoeBotWins++;
tictactoeUpdateScoreboard();
tictactoeResetGame();
}, 100);
} else if (tictactoeCheckDraw()) {
setTimeout(() => {
alert("Match nul !");
tictactoeDraws++;
tictactoeUpdateScoreboard();
tictactoeResetGame();
}, 100);
} else {
// Passer le tour au joueur
tictactoePlayerTurnFlag = true;
}
}
// Fonction récursive du Minimax avec élagage alpha-bêta
function tictactoeMinimax(board, depth, isMaximizingPlayer) {
let score = tictactoeEvaluateState();
if (score !== undefined) {
return score;
}
if (isMaximizingPlayer) {
let bestScore = -Infinity;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (board[i][j] === "") {
board[i][j] = tictactoeBotSymbol;
let score = tictactoeMinimax(board, depth + 1, false);
board[i][j] = "";
bestScore = Math.max(score, bestScore);
}
}
}
return bestScore;
} else {
let bestScore = Infinity;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (board[i][j] === "") {
board[i][j] = tictactoePlayerSymbol;
let score = tictactoeMinimax(board, depth + 1, true);
board[i][j] = "";
bestScore = Math.min(score, bestScore);
}
}
}
return bestScore;
}
}
// Fonction pour évaluer l'état actuel du jeu
function tictactoeEvaluateState() {
if (tictactoeCheckWinner(tictactoePlayerSymbol)) {
return -1;
} else if (tictactoeCheckWinner(tictactoeBotSymbol)) {
return 1;
} else if (tictactoeCheckDraw()) {
return 0;
} else {
return undefined;
}
}
// Fonction pour réinitialiser le jeu
function tictactoeResetGame() {
tictactoeBoard = [
["", "", ""],
["", "", ""],
["", "", ""]
];
tictactoeDisplayBoard();
tictactoePlayerTurnFlag = true; // Réinitialiser le tour du joueur à true
}
// Fonction pour initialiser le jeu
function tictactoeStartGame() {
tictactoeDisplayBoard();
tictactoeUpdateScoreboard();
}
// Appel à la fonction d'initialisation du jeu au chargement de la page
tictactoeStartGame();
</script>
Integrating Pong into your project
Turn your Webflow website into a playful platform by integrating a revisited and entertaining version of the game Pong! Give your users an enjoyable experience by allowing them to play against a competitive bot. Even though the game is simple in design, it still provides classic and timeless entertainment.
Code used:
<style>
@media screen and (max-width: 992px) {
#pong-game-container {
display: none !important;
}
}
#pong-game-container {
width: 37.5rem;
margin: 0 auto;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#pong-game-area {
top: 0;
left: 0;
width: 100%;
height: 25rem;
border: 1.5px solid #f5f5f5;
background-color: #101010;
}
#pong-paddle-left,
#pong-paddle-right {
position: absolute;
width: 1.25rem;
height: 4rem;
background-color: #f5f5f5;
transition: all 75ms linear;
border-radius: 0.75rem;
}
#pong-paddle-left {
top: 168px;
left: 10px;
}
#pong-paddle-right {
top: 168px;
right: 10px;
}
#pong-ball {
position: absolute;
width: 1.25rem;
height: 1.25rem;
background-color: #fdd33c;
border-radius: 50%;
}
#pong-scoreboard {
text-align: center;
font-size: 1.5rem;
margin-top: 1.25rem;
}
#pong-restart-button {
padding: 0.625rem 1rem;
font-size: 1rem;
background-color: #333;
color: #fff;
border: none;
cursor: pointer;
position: absolute;
}
#pong-restart-button:hover {
background-color: #666;
}
</style>
<div id="pong-game-container">
<div id="pong-game-area">
<div id="pong-paddle-left"></div>
<div id="pong-paddle-right"></div>
<div id="pong-ball"></div>
</div>
<button id="pong-restart-button">Jouer</button>
<div id="pong-scoreboard">
<span id="pong-player-score">0</span> : <span id="pong-bot-score">0</span>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
// Déclarations et initialisation des variables
const raquetteGauche = document.getElementById("pong-paddle-left");
const raquetteDroite = document.getElementById("pong-paddle-right");
const balle = document.getElementById("pong-ball");
const scoreJoueurElement = document.getElementById("pong-player-score");
const scoreBotElement = document.getElementById("pong-bot-score");
const boutonRestart = document.getElementById("pong-restart-button");
let scoreJoueur = 0;
let scoreBot = 0;
const vitesseBalleInitiale = 4;
let vitesseBalle = vitesseBalleInitiale;
let posXballe = 290;
let posYballe = 190;
let directionXBalle = 1;
let directionYBalle = 1;
const vitesseRaquette = 28;
let posYraquetteGauche = 168;
let posYraquetteDroite = 168;
let intervalleJeu;
let partieDemarree = false;
let partieTerminee = false;
// Création de l'objet bot pour contrôler la raquette de droite
const bot = {
update: function() {
deplacerRaquetteBot();
}
};
boutonRestart.addEventListener("click", () => {
if (!partieDemarree || partieTerminee) {
demarrerPartie();
partieDemarree = true;
partieTerminee = false;
boutonRestart.style.display = "none";
} else {
reinitialiserPartie();
demarrerPartie();
}
});
function reinitialiserPartie() {
reinitialiserBalle();
reinitialiserRaquettes();
}
// Écouteur d'événement pour la touche enfoncée
document.addEventListener("keydown", (event) => {
if (event.code === "ArrowDown") {
event.preventDefault();
deplacerRaquetteBas();
} else if (event.code === "ArrowUp") {
event.preventDefault();
deplacerRaquetteHaut();
}
});
// Écouteur d'événement pour la touche relâchée
document.addEventListener("keyup", (event) => {
if (event.code === "ArrowDown" || event.code === "ArrowUp") {
event.preventDefault();
arreterRaquette();
}
});
// Fonction pour démarrer la partie
function demarrerPartie() {
reinitialiserBalle();
reinitialiserRaquettes();
boutonRestart.style.display = "none";
intervalleJeu = setInterval(mettreAJourJeu, 20);
partieDemarree = true;
partieTerminee = false;
}
// Fonction pour mettre à jour l'état du jeu
function mettreAJourJeu() {
deplacerBalle();
deplacerRaquettes();
verifierCollision();
verifierFinManche();
bot.update();
}
// Fonction pour déplacer la balle
function deplacerBalle() {
posXballe += vitesseBalle * directionXBalle;
posYballe += vitesseBalle * directionYBalle;
balle.style.left = posXballe + "px";
balle.style.top = posYballe + "px";
}
// Fonction pour déplacer les raquettes
function deplacerRaquettes() {
raquetteGauche.style.top = posYraquetteGauche + "px";
raquetteDroite.style.top = posYraquetteDroite + "px";
}
// Vitesse de déplacement réduite pour une raquette plus fluide
const vitesseRaquetteBot = 14;
function deplacerRaquetteBot() {
// Ajustement correct de la raquette en fonction de la position estimée de la balle
if (posYraquetteDroite + 32 > posYballe + 35 && posYraquetteDroite > 0) {
posYraquetteDroite -= vitesseRaquetteBot;
} else if (posYraquetteDroite + 32 < posYballe - 35 && posYraquetteDroite + 64 < 336) {
posYraquetteDroite += vitesseRaquetteBot;
}
// Appeler la fonction de déplacement du bot à nouveau pour créer une boucle continue
requestAnimationFrame(deplacerRaquetteBot);
}
// Appeler la fonction de déplacement du bot pour la première fois
requestAnimationFrame(deplacerRaquetteBot);
// Fonction pour vérifier la collision de la balle avec les raquettes et les murs
function verifierCollision() {
// Collision avec les raquettes
if (
posXballe <= 30 &&
posYballe + 10 >= posYraquetteGauche &&
posYballe <= posYraquetteGauche + 64
) {
directionXBalle = 1;
augmenterVitesseBalle();
} else if (
posXballe >= 560 &&
posYballe + 10 >= posYraquetteDroite &&
posYballe <= posYraquetteDroite + 64
) {
directionXBalle = -1;
augmenterVitesseBalle();
}
// Collision avec les murs supérieur et inférieur
if (posYballe <= 0 || posYballe >= 380) {
directionYBalle *= -1;
}
}
// Fonction pour augmenter la vitesse de la balle
function augmenterVitesseBalle() {
if (vitesseBalle < 12) {
vitesseBalle += 0.25;
}
}
// Fonction pour mettre à jour le tableau des scores
function mettreAJourTableauScores() {
scoreJoueurElement.textContent = scoreJoueur;
scoreBotElement.textContent = scoreBot;
}
// Fonction pour marquer un point et mettre à jour le score
function marquerPoint(scoreElement) {
const score = parseInt(scoreElement.textContent);
scoreElement.textContent = score + 1;
}
// Fonction pour vérifier la fin de la manche
function verifierFinManche() {
if (posXballe <= 0) {
marquerPoint(scoreBotElement);
afficherAlerte("Le bot a marqué un point !");
stopperPartie();
reinitialiserBalle();
boutonRestart.style.display = "block";
} else if (posXballe >= 585) {
marquerPoint(scoreJoueurElement);
afficherAlerte("Vous avez marqué un point !");
stopperPartie();
reinitialiserBalle();
boutonRestart.style.display = "block";
}
}
// Fonction pour afficher une alerte
function afficherAlerte(message) {
alert(message);
}
// Fonction pour réinitialiser la position de la balle
function reinitialiserBalle() {
posXballe = 290;
posYballe = 190;
directionXBalle = 1;
directionYBalle = 1;
vitesseBalle = vitesseBalleInitiale;
}
// Fonction pour réinitialiser la position des raquettes
function reinitialiserRaquettes() {
posYraquetteGauche = 168;
posYraquetteDroite = 168;
}
// Fonction pour arrêter la partie
function stopperPartie() {
clearInterval(intervalleJeu);
}
// Fonction pour déplacer la raquette vers le bas
function deplacerRaquetteBas() {
if (posYraquetteGauche < 336) {
posYraquetteGauche += vitesseRaquette;
}
}
// Fonction pour déplacer la raquette vers le haut
function deplacerRaquetteHaut() {
if (posYraquetteGauche > 0) {
posYraquetteGauche -= vitesseRaquette;
}
}
// Fonction pour arrêter le déplacement de la raquette
function arreterRaquette() {
// Ne fait rien
}
});
</script>
Integrate the brick-breaking game (breakout)
Enjoy a new and entertaining version of the Breakout game on our Webflow site. Challenge yourself in a classic and timeless experience by destroying bricks with a bouncing ball!
Code used:
<style>
@media screen and (max-width: 992px) {
#breakoutContainer {
display: none !important;
}
}
#breakoutContainer {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 31.25rem;
margin: 0 auto;
}
#breakoutScoreWrapper {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 1rem;
}
#breakoutCanvas {
border: 1px solid #fdd33c;
background-color: #101010;
}
#breakoutScore {
font-size: 1rem;
}
#breakoutBestScore {
font-size: 1rem;
color: #666;
}
#breakoutRestartButton {
font-size: 1rem;
padding: 0.625rem 1rem;
background-color: #333;
color: #FFF;
border: none;
cursor: pointer;
position: absolute;
}
#breakoutRestartButton:hover {
background-color: #666;
}
#breakoutBall {
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fdd33c;
left: calc(50% - 10px);
top: calc(50% - 10px);
display: none;
}
#breakoutPaddle {
position: absolute;
width: 80px;
height: 10px;
background-color: #ffffff;
animation: all 75ms linear;
display: none;
}
#breakoutBricks {
position: absolute;
display: none;
}
</style>
<div id="breakoutContainer">
<canvas id="breakoutCanvas" width="500" height="500"></canvas>
<button id="breakoutRestartButton">Jouer</button>
<div id="breakoutScoreWrapper">
<div id="breakoutScore">Score : 0</div>
<div id="breakoutBestScore">Meilleur Score : 0</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const breakoutCanvas = document.getElementById("breakoutCanvas");
const breakoutContext = breakoutCanvas.getContext("2d");
const breakoutRestartButton = document.getElementById("breakoutRestartButton");
const breakoutScoreElement = document.getElementById("breakoutScore");
const breakoutBestScoreElement = document.getElementById("breakoutBestScore");
const breakoutBrickRowCount = 3;
const breakoutBrickColumnCount = 5;
const brickWidth = 80;
const brickHeight = 20;
const brickPadding = 10;
const brickOffsetTop = 30;
const brickOffsetLeft = (breakoutCanvas.width - (breakoutBrickColumnCount * (brickWidth + brickPadding))) / 2;
let breakoutBricks = [];
let breakoutBall = { x: breakoutCanvas.width / 2, y: breakoutCanvas.height - 30, dx: 2, dy: -2, radius: 10 };
let breakoutPaddle = { x: breakoutCanvas.width / 2 - 40, y: breakoutCanvas.height - 10, width: 80, height: 10 };
let breakoutScore = 0;
let breakoutBestScore = 0;
let gameStarted = false;
let gameOver = false;
let intervalId;
let leftPressed = false;
let rightPressed = false;
let ballSpeed = 0.7;
let gameWon = false;
let checkCollision = true;
function breakoutClearCanvas() {
breakoutContext.clearRect(0, 0, breakoutCanvas.width, breakoutCanvas.height);
}
function breakoutRestartGame() {
breakoutResetGame(); // Réinitialise le score à 0
breakoutResetBall();
breakoutResetPaddle();
breakoutResetBricks();
breakoutRestartButton.style.display = "none";
breakoutCanvas.style.display = "block";
intervalId = setInterval(breakoutUpdateGame, 10);
gameStarted = true;
gameOver = false;
}
function breakoutResetBall() {
breakoutBall.x = breakoutCanvas.width / 2;
breakoutBall.y = breakoutCanvas.height - 180;
breakoutBall.dx = 2;
breakoutBall.dy = 2;
}
function breakoutResetPaddle() {
breakoutPaddle.x = breakoutCanvas.width / 2;
breakoutPaddle.y = breakoutCanvas.height - 10;
}
function breakoutResetBricks() {
breakoutBricks = [];
for (let c = 0; c < breakoutBrickColumnCount; c++) {
breakoutBricks[c] = [];
for (let r = 0; r < breakoutBrickRowCount; r++) {
const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
breakoutBricks[c][r] = { x: brickX, y: brickY, status: 1 };
}
}
}
function breakoutDrawBricks() {
for (let c = 0; c < breakoutBrickColumnCount; c++) {
for (let r = 0; r < breakoutBrickRowCount; r++) {
const brick = breakoutBricks[c][r];
if (brick && brick.status === 1) {
const brickX = brick.x;
const brickY = brick.y;
breakoutContext.fillStyle = "#f5f5f5";
breakoutContext.fillRect(brickX, brickY, brickWidth, brickHeight);
}
}
}
}
function breakoutDrawBall() {
breakoutContext.beginPath();
breakoutContext.arc(breakoutBall.x, breakoutBall.y, breakoutBall.radius, 0, Math.PI * 2);
breakoutContext.fillStyle = "#fdd33c";
breakoutContext.fill();
breakoutContext.closePath();
}
function breakoutDrawPaddle() {
breakoutContext.beginPath();
breakoutContext.rect(breakoutPaddle.x, breakoutPaddle.y, breakoutPaddle.width, breakoutPaddle.height);
breakoutContext.fillStyle = "#f5f5f5";
breakoutContext.fill();
breakoutContext.closePath();
}
function breakoutMoveBall() {
breakoutBall.x += breakoutBall.dx * ballSpeed;
breakoutBall.y += breakoutBall.dy * ballSpeed;
}
function breakoutMovePaddle() {
if (leftPressed && breakoutPaddle.x > 0) {
breakoutPaddle.x -= 6;
} else if (rightPressed && breakoutPaddle.x + breakoutPaddle.width < breakoutCanvas.width) {
breakoutPaddle.x += 6;
}
}
function breakoutCheckCollision() {
if (!checkCollision) {
return; // Arrête la fonction si la vérification de la collision n'est pas nécessaire
}
if (
breakoutBall.x + breakoutBall.dx > breakoutCanvas.width - breakoutBall.radius ||
breakoutBall.x + breakoutBall.dx < breakoutBall.radius
) {
breakoutBall.dx = -breakoutBall.dx;
}
if (breakoutBall.y + breakoutBall.dy < breakoutBall.radius) {
breakoutBall.dy = -breakoutBall.dy;
}
if (
breakoutBall.y + breakoutBall.dy > breakoutCanvas.height - breakoutBall.radius - breakoutPaddle.height + 10
) {
if (
breakoutBall.x > breakoutPaddle.x &&
breakoutBall.x < breakoutPaddle.x + breakoutPaddle.width
) {
const paddleCenter = breakoutPaddle.x + breakoutPaddle.width / 2;
const ballOffsetFromCenter = breakoutBall.x - paddleCenter;
breakoutBall.dy = -breakoutBall.dy;
breakoutBall.dx = ballOffsetFromCenter / (breakoutPaddle.width / 2);
} else {
gameOver = true;
clearInterval(intervalId);
breakoutRestartButton.style.display = "block";
if (breakoutScore > breakoutBestScore) {
breakoutBestScore = breakoutScore;
}
}
}
for (let c = 0; c < breakoutBrickColumnCount; c++) {
for (let r = 0; r < breakoutBrickRowCount; r++) {
const brick = breakoutBricks[c][r];
if (brick && brick.status === 1) {
if (
breakoutBall.x > brick.x &&
breakoutBall.x < brick.x + brickWidth &&
breakoutBall.y > brick.y &&
breakoutBall.y < brick.y + brickHeight
) {
breakoutBall.dy = -breakoutBall.dy;
brick.status = 0;
breakoutScore++;
// Augmenter la vitesse de la balle uniquement lorsque des briques sont cassées
if (breakoutScore === breakoutScore) {
ballSpeed += 0.15;
}
}
}
}
}
if (breakoutScore === breakoutBrickRowCount * breakoutBrickColumnCount) {
gameWon = true;
checkCollision = false; // Arrête la vérification de la collision
clearInterval(intervalId); // Arrête la boucle de jeu
}
}
function breakoutUpdateScore() {
breakoutScoreElement.textContent = "Score: " + breakoutScore;
breakoutBestScoreElement.textContent = "Meilleur Score: " + breakoutBestScore;
}
function breakoutResetGame() {
gameWon = false;
breakoutScore = 0;
breakoutClearCanvas();
breakoutRestartButton.style.display = "block";
breakoutUpdateScore();
gameStarted = false;
ballSpeed = 0.7;
}
function breakoutUpdateGame() {
breakoutClearCanvas();
breakoutDrawBricks();
breakoutDrawBall();
breakoutDrawPaddle();
breakoutMoveBall();
breakoutMovePaddle();
breakoutCheckCollision();
breakoutUpdateScore();
if (gameWon) {
alert("Bravo, vous avez gagné ! Score: " + breakoutScore);
breakoutScore = 0;
breakoutBestScore = 15;
breakoutResetPaddle();
breakoutResetBricks();
breakoutRestartButton.style.display = "block";
checkCollision = true; // Réactive la vérification de la collision
}
if (gameOver) {
alert("Partie terminée ! Score: " + breakoutScore);
if (breakoutScore > breakoutBestScore) {
breakoutBestScore = breakoutScore;
}
breakoutScore = 0;
breakoutResetPaddle();
breakoutResetBricks();
breakoutRestartButton.style.display = "block";
}
}
breakoutRestartButton.addEventListener("click", () => {
if (!gameStarted || gameOver || gameWon){
breakoutRestartGame();
checkCollision = true; // Réactive la vérification de la collision
} else {
breakoutResetGame();
}
});
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);
function handleKeyDown(event) {
if (event.key === "ArrowLeft") {
leftPressed = true;
} else if (event.key === "ArrowRight") {
rightPressed = true;
}
}
function handleKeyUp(event) {
if (event.key === "ArrowLeft") {
leftPressed = false;
} else if (event.key === "ArrowRight") {
rightPressed = false;
}
}
});
</script>
Integrate a reactivity mini-game on Webflow
Discover our redesigned and simplified version of the mole game, a classic reactivity game! Test your reflexes by quickly tapping the moles as they emerge from their burrows (in this case the white circles). Have fun beating your own record for speed and accuracy in this exciting and fun reaction game!
Code used:
<style>
@media screen and (max-width: 992px) {
#moleContainer {
display: none !important;
}
}
#moleContainer {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 25rem;
margin: 0 auto;
}
#moleField {
display: grid;
grid-template-columns: repeat(4, 6.25rem);
grid-template-rows: repeat(4, 6.25rem);
margin: 2rem 0;
background-color: #101010;
}
.moleHole {
width: 6.25rem;
height: 6.25rem;
background-color: #fdd33c;
border-radius: 50%;
cursor: pointer;
}
.moleHole.active {
background-color: #FFFFFF;
}
#moleStartButton {
font-size: 1rem;
padding: 0.625rem 1rem;
background-color: #333;
color: #FFF;
border: none;
cursor: pointer;
position: absolute;
margin-top: -1rem;
}
#moleStartButton:hover {
background-color: #666;
}
#moleBoardWrapper {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 1rem;
}
#moleBestScore
{
margin-top: 0.25rem;
color: #666;
}
#moleScore, #moleBestScore,
#moleTimer {
font-size: 1rem;
}
</style>
<div id="moleContainer">
<div id="moleField">
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
<div class="moleHole"></div>
</div>
<button id="moleStartButton" onclick="startMoleGame()">Jouer</button>
<div id="moleBoardWrapper">
<div id="moleScoreWrapper">
<div id="moleScore">Score : 0</div>
<div id="moleBestScore">Meilleur Score : 0</div>
</div>
<div id="moleTimer">Temps restant : 30</div>
</div>
</div>
<script>
(function() {
const moleScoreElement = document.getElementById("moleScore");
const moleBestScoreElement = document.getElementById("moleBestScore");
const moleTimerElement = document.getElementById("moleTimer");
const moleStartButton = document.getElementById("moleStartButton");
const moleHoles = document.querySelectorAll(".moleHole");
let moleScore = 0;
let moleBestScore = 0;
let moleTimer = 30; // Durée du jeu en secondes
let moleGameTimer;
let activeMoles = [];
let initialMoleInterval = 1500;
let moleTimeout;
let moleGameActive = false;
function moleClicked() {
if (this.classList.contains("active")) {
moleScore++;
this.classList.remove("active");
activeMoles.splice(activeMoles.indexOf(this), 1);
clearTimeout(moleTimeout);
updateMoleScore();
// Réinitialiser le timer à 3 secondes
clearTimeout(moleTimeout);
moleTimeout = setTimeout(() => {
endMoleGame("Trop lent");
}, 1500);
} else {
endMoleGame("Il faut améliorer ta précision !");
if (moleTimeout) {
clearTimeout(moleTimeout);
moleTimeout = null;
}
}
}
function updateMoleScore() {
moleScoreElement.textContent = `Score : ${moleScore}`;
}
function updateMoleBestScore() {
moleBestScoreElement.textContent = `Meilleur Score : ${moleBestScore}`;
}
function updateMoleTimer() {
moleTimerElement.textContent = `Temps restant : ${moleTimer}`;
}
function generateMole() {
if (!moleGameActive) {
return;
}
if (activeMoles.length < 2) {
const randomIndex = Math.floor(Math.random() * moleHoles.length);
const moleHole = moleHoles[randomIndex];
// Vérifier si le trou est déjà actif
if (!moleHole.classList.contains("active")) {
moleHole.classList.add("active");
moleHole.addEventListener("click", moleClicked);
activeMoles.push(moleHole);
}
// Augmenter la vitesse d'apparition à chaque point
initialMoleInterval -= 200;
if (initialMoleInterval < 300) {
initialMoleInterval = 300; // Limiter la vitesse minimale
}
}
setTimeout(generateMole, initialMoleInterval);
}
function endMoleGame(reason) {
clearInterval(moleGameTimer);
moleGameActive = false;
activeMoles.forEach((mole) => {
mole.classList.remove("active");
mole.removeEventListener("click", moleClicked);
});
activeMoles = [];
moleStartButton.disabled = false;
moleStartButton.style.display = "block";
if (moleScore > moleBestScore) {
moleBestScore = moleScore;
updateMoleBestScore();
}
alert(`Fin du jeu de la taupe ! Votre score final est de ${moleScore}. Raison : ${reason}`);
}
function hideMoleHoles() {
moleHoles.forEach((moleHole) => {
moleHole.addEventListener("click", moleClicked);
moleHole.classList.remove("active");
});
}
function startMoleGame() {
moleGameActive = true;
moleScore = 0;
moleTimer = 30;
updateMoleScore();
updateMoleBestScore();
updateMoleTimer();
moleStartButton.disabled = true;
moleGameTimer = setInterval(() => {
moleTimer--;
updateMoleTimer();
if (moleTimer === 0) {
clearInterval(moleGameTimer);
endMoleGame("Temps écoulé");
}
}, 1000);
moleStartButton.style.display = "none";
// Générer la première taupe
generateMole();
// Initialiser le timeout pour la fin du jeu si trop lent
moleTimeout = setTimeout(() => {
endMoleGame("Trop lent");
}, 1500);
}
hideMoleHoles();
moleStartButton.addEventListener("click", startMoleGame);
})();
</script>
Give your Webflow site a dose of fun and interactive entertainment with these engaging mini-games. Give your users a memorable experience by incorporating reinvented classics such as Snake, Tic-Tac-Toe, Pong, Breakout and our redesigned Mole Game. Attract, engage and entertain your visitors, turning your site into a must-see destination. Let your games begin and surprise your users today!
Discover the Webflow 2023 portfolios!