Skip to content

Commit

Permalink
added Candy, Simon
Browse files Browse the repository at this point in the history
  • Loading branch information
marinitx committed Nov 7, 2024
1 parent 6ebf88d commit 9681754
Show file tree
Hide file tree
Showing 10 changed files with 618 additions and 2 deletions.
Binary file added src/img/games/1.mp3
Binary file not shown.
Binary file added src/img/games/2.mp3
Binary file not shown.
Binary file added src/img/games/3.mp3
Binary file not shown.
Binary file added src/img/games/4.mp3
Binary file not shown.
133 changes: 133 additions & 0 deletions src/pages/advent-calendar-2024/components/games/candy.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
.candy-crush {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
gap: 20px; /* Espacio entre las columnas */
}

.left-column {
flex: 1; /* Ocupa 1/3 del espacio */
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
text-align: left;
gap: 10px;
}

.right-column {
flex: 2; /* Ocupa 2/3 del espacio */
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
padding: 20px;
}

.grid {
height: 560px;
width: 560px;
display: flex;
flex-wrap: wrap;
justify-content: center; /* Centra el contenido dentro de la grilla */
align-items: center;
}

/* Clase para bloquear la cuadrícula */
.grid.locked {
pointer-events: none;
opacity: 0.5;
}

.grid.locked::before {
content: "Game Over";
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 2rem;
color: white;
background-color: rgba(0, 0, 0);
padding: 10px;
border-radius: 5px;
}


/* Estilos y animaciones */
.grid div {
height: 70px;
width: 70px;
transition: transform 0.3s ease-in-out;
}

.dragging {
opacity: 0.4;
transform: scale(0.5);
}

.invalid-move {
animation: shake 0.3s ease;
}

/* Animación para intercambiar posiciones */
@keyframes swap {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(100%, 100%); /* Ejemplo de cómo mover de un lugar a otro */
}
}

@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
50% { transform: translateX(5px); }
75% { transform: translateX(-5px); }
}

.square.shake {
animation: shake 0.5s ease-in-out;
}


.drop {
animation: drop 0.3s cubic-bezier(0.4, 0, 1, 1);
}

@keyframes drop {
0% { transform: translateY(-100%); }
100% { transform: translateY(0); }
}

@keyframes disappear {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(0); opacity: 0; }
}

.disappear {
animation: disappear 0.8s ease forwards;
}

/* Animación para filas o columnas de 3 o 4 elementos */
@keyframes clearRowOrColumn {
0% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(1.2);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

/* Clase para aplicar la animación */
.clear-animation {
animation: clearRowOrColumn 0.5s ease-out forwards;
}

217 changes: 217 additions & 0 deletions src/pages/advent-calendar-2024/components/games/candy.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import {
Text10,
Text4,
Text3,
Text9
} from "@telefonica/mistica";
import React, { useState, useEffect } from 'react';
import blau from '../../../../img/games/blau.svg';
import movistar from '../../../../img/games/movistar.svg';
import o2 from '../../../../img/games/o2.svg';
import telefonica from '../../../../img/games/telefonica.svg';
import tu from '../../../../img/games/tu.svg';
import vivo from '../../../../img/games/vivo.svg';
import './candy.css';

const CandyCrush = () => {
const width = 8;
const candyColors = [movistar, tu, vivo, blau, telefonica, o2];
const maxMoves = 10;

const [squares, setSquares] = useState([]);
const [score, setScore] = useState(0);
const [movesRemaining, setMovesRemaining] = useState(maxMoves);
const [draggingIndex, setDraggingIndex] = useState(null);
const [invalidMove, setInvalidMove] = useState(null); // Estado para identificar si un movimiento es inválido

useEffect(() => {
if (movesRemaining === 0) {
document.querySelector('.grid').classList.add('locked'); // Bloquea la cuadrícula
}
}, [movesRemaining]);

useEffect(() => {
createBoard();
}, []);

useEffect(() => {
const intervalId = setInterval(() => {
moveDown();
checkMatches();
}, 100);

return () => clearInterval(intervalId); // Limpiar el intervalo al desmontar
}, [squares]);

function createBoard() {
const initialSquares = [];
for (let i = 0; i < width * width; i++) {
const randomColor = Math.floor(Math.random() * candyColors.length);
initialSquares.push(candyColors[randomColor]);
}
setSquares(initialSquares);
}

function moveDown() {
let newSquares = [...squares];
for (let i = width * (width - 1) - 1; i >= 0; i--) {
if (newSquares[i + width] === undefined || newSquares[i + width] === '') {
newSquares[i + width] = newSquares[i];
newSquares[i] = '';
}
}
for (let i = 0; i < width; i++) {
if (newSquares[i] === '') {
const randomColor = Math.floor(Math.random() * candyColors.length);
newSquares[i] = candyColors[randomColor];
}
}
setSquares(newSquares);
}

function animateAndClear(squaresToClear) {
let newSquares = [...squares];
squaresToClear.forEach(index => {
newSquares[index] = '';
});
setSquares(newSquares);
}

function checkMatches() {
checkRowForFour();
checkColumnForFour();
checkRowForThree();
checkColumnForThree();
}

function checkRowForFour() {
for (let i = 0; i < 63; i++) {
if (i % width > width - 4) continue;
const rowOfFour = [i, i + 1, i + 2, i + 3];
const decidedColor = squares[i];
const isBlank = decidedColor === '';

if (rowOfFour.every(index => squares[index] === decidedColor) && !isBlank) {
setScore(prevScore => prevScore + 4);
animateAndClear(rowOfFour);
}
}
}

function checkColumnForFour() {
for (let i = 0; i < 47; i++) {
const columnOfFour = [i, i + width, i + width * 2, i + width * 3];
const decidedColor = squares[i];
const isBlank = decidedColor === '';

if (columnOfFour.every(index => squares[index] === decidedColor) && !isBlank) {
setScore(prevScore => prevScore + 4);
animateAndClear(columnOfFour);
}
}
}

function checkRowForThree() {
for (let i = 0; i < 64; i++) {
if (i % width > width - 3) continue;
const rowOfThree = [i, i + 1, i + 2];
const decidedColor = squares[i];
const isBlank = decidedColor === '';

if (rowOfThree.every(index => squares[index] === decidedColor) && !isBlank) {
setScore(prevScore => prevScore + 3);
animateAndClear(rowOfThree);
}
}
}

function checkColumnForThree() {
for (let i = 0; i < 48; i++) {
const columnOfThree = [i, i + width, i + width * 2];
const decidedColor = squares[i];
const isBlank = decidedColor === '';

if (columnOfThree.every(index => squares[index] === decidedColor) && !isBlank) {
setScore(prevScore => prevScore + 3);
animateAndClear(columnOfThree);
}
}
}

const handleDragStart = (e, index) => {
if (movesRemaining === 0) return; // Bloquea el drag si no hay movimientos restantes
setDraggingIndex(index);
e.dataTransfer.setData('draggedIndex', index);
};

// const handleDrop = (e, index) => {
// if (movesRemaining === 0) return; // Bloquea el drop si no hay movimientos restantes
// const draggedIndex = e.dataTransfer.getData('draggedIndex');

// let newSquares = [...squares];
// let temp = newSquares[index];
// newSquares[index] = newSquares[draggedIndex];
// newSquares[draggedIndex] = temp;

// setSquares(newSquares);
// setMovesRemaining(prev => prev - 1);
// };


const handleDrop = (e, index) => {
if (movesRemaining === 0) return;
const draggedIndex = e.dataTransfer.getData('draggedIndex');
const isAdjacent = Math.abs(draggedIndex - index) === 1 || Math.abs(draggedIndex - index) === width;

if (isAdjacent) {
let newSquares = [...squares];
let temp = newSquares[index];
newSquares[index] = newSquares[draggedIndex];
newSquares[draggedIndex] = temp;
setSquares(newSquares);
setMovesRemaining(prev => prev - 1);
setInvalidMove(null); // Reset el estado de movimiento inválido
setDraggingIndex(null);
} else {
setInvalidMove(draggedIndex); // Activamos el movimiento inválido

setDraggingIndex(null); // Limpiamos el estado de "draggingIndex"
}
};

const handleDragOver = (e) => {
e.preventDefault();
};

return (
<div className="candy-crush">
<div className="left-column">
<Text10>Candy Crush</Text10>
<p>Instructions: Try to match Telefonica brands of the same type in a row or column of 3!</p>
<p id="score">Score: {score}</p>
</div>
<div className="right-column">
<div className="grid">
{squares.map((color, index) => (
<div
key={index}
id={index}
className={`square ${draggingIndex === index ? 'dragging' : ''} ${invalidMove === index ? 'invalid-move' : ''}`} // Aplica shake a la imagen arrastrada si el movimiento es inválido
style={{ backgroundImage: `url(${color})` }}
draggable
onDragStart={(e) => handleDragStart(e, index)}
onDragOver={handleDragOver}
onDrop={(e) => handleDrop(e, index)}
></div>
))}
</div>
<p id="timer">{movesRemaining} moves</p>
</div>
</div>
);
};

export default CandyCrush;



Loading

0 comments on commit 9681754

Please sign in to comment.