In questa lezione ci concentreremo sul rendere interattivo il nostro "Solitario delle 5 carte" sviluppato nelle lezioni precedenti con React. Aggiungeremo la funzionalità di selezione delle carte, permettendo al giocatore di formare combinazioni valide, e implementeremo il calcolo dinamico del punteggio in base alle combinazioni formate.
Cosa vogliamo realizzare con React
Gli obiettivi principali di questa lezione sono:
- Selezione delle carte: consentire al giocatore di selezionare e deselezionare le carte per formare combinazioni.
- Validazione delle combinazioni: implementare la logica per verificare le combinazioni selezionate (tris, scale..).
- Calcolo del punteggio: aggiornare il punteggio in base alle combinazioni formate.
- Miglioramento dell'interfaccia utente: visualizzare chiaramente le carte selezionate e il punteggio.
Inoltre, per una migliore esperienza utente, aggiungeremo un feedback visivo che mostri quali carte sono state selezionate e integreremo una barra di punteggio che si aggiorna dinamicamente.
Aggiornamento del componente Card.js
Per rendere le carte interattive dobbiamo fare in modo che l'utente possa cliccare su ciascuna carta per selezionarla o deselezionarla. Quando una carta è selezionata, vogliamo che appaia evidenziata. Aggiorniamo quindi il componente Card.js aggiungendo la proprietà isSelected che cambia lo stile della carta quando è selezionata.
// src/components/Card.js
import React from 'react';
import './Card.css';
const Card = ({ rank, suit, image, isSelected, onClick }) => {
return (
<div className={`card ${isSelected ? 'selected' : ''}`} onClick={onClick}>
<img src={image} alt={`${rank} di ${suit}`} />
<div className="rank">{rank}</div>
<div className="suit">{suit}</div>
</div>
);
};
export default Card;
Ora aggiungiamo una classe CSS selected per evidenziare le carte selezionate. Questa classe aumenterà il bordo della carta e applicherà un leggero ingrandimento per darle risalto.
/* src/components/Card.css */
.card.selected {
border: 2px solid blue; /* Colore evidenziato */
transform: scale(1.1); /* Ingrandimento leggero */
}
Modifica del componente principale App.js
Passiamo ora ad aggiornare App.js per gestire la selezione delle carte. Quando una carta viene cliccata, sarà aggiunta o rimossa dall'elenco delle carte selezionate. Utilizzeremo un array selectedCards per tenere traccia delle carte scelte e verificare quali appartengono alla selezione attuale del giocatore.
// src/App.js
import React, { useState, useEffect } from 'react';
import './App.css';
import Card from './components/Card';
const App = () => {
const [deck, setDeck] = useState([]);
const [selectedCards, setSelectedCards] = useState([]);
const [score, setScore] = useState(0);
useEffect(() => {
const newDeck = createDeck();
shuffleDeck(newDeck);
setDeck(newDeck);
}, []);
const createDeck = () => {
const suits = ['Denari', 'Coppe', 'Spade', 'Bastoni'];
const ranks = ['Asso', '2', '3', '4', '5', '6', '7', 'Fante', 'Cavallo', 'Re'];
const deck = [];
for (const suit of suits) {
for (const rank of ranks) {
deck.push({ rank, suit, image: require(`../images/${rank}_${suit}.png`) });
}
}
return deck;
};
const handleCardClick = (card) => {
if (selectedCards.includes(card)) {
setSelectedCards(selectedCards.filter(selected => selected !== card));
} else {
setSelectedCards([...selectedCards, card]);
}
};
return (
<div className="game">
<h1>Gioco di Solitario delle 5 Carte</h1>
<div className="deck">
{deck.map((card, index) => (
<Card
key={index}
rank={card.rank}
suit={card.suit}
image={card.image}
isSelected={selectedCards.includes(card)}
onClick={() => handleCardClick(card)}
/>
))}
</div>
</div>
);
};
export default App;
In questo codice, la funzione handleCardClick gestisce la logica di selezione e deselezione delle carte. Quando una carta è cliccata viene aggiunta o rimossa dall'array selectedCards. In questo modo il giocatore può selezionare diverse carte per formare delle combinazioni.
Validazione delle combinazioni e calcolo del punteggio con React
Ora che le carte possono essere selezionate, possiamo aggiungere le funzioni per la validazione delle combinazioni e il calcolo del punteggio. Definiamo due funzioni, checkTris e checkScala, per verificare se le carte selezionate formano una combinazione valida di tris o scala.
Funzioni di validazione
Aggiungiamo le funzioni checkTris e checkScala che controllano le combinazioni:
const checkTris = (cards) => {
const rankCount = {};
cards.forEach(card => {
rankCount[card.rank] = (rankCount[card.rank] || 0) + 1;
});
return Object.values(rankCount).some(count => count === 3);
};
const checkScala = (cards) => {
const suits = [...new Set(cards.map(card => card.suit))];
if (suits.length !== 1) return false;
const ranks = ['Asso', '2', '3', '4', '5', '6', '7', 'Fante', 'Cavallo', 'Re'];
const indices = cards
.map(card => ranks.indexOf(card.rank))
.sort((a, b) => a - b);
return indices.every((val, i, arr) => i === 0 || val === arr[i - 1] + 1);
};
Calcolo del punteggio con React
La funzione calculateScore calcola i punti assegnando un valore di 5 punti per un tris e 10 punti per una scala.
const calculateScore = () => {
let currentScore = 0;
if (checkTris(selectedCards))
currentScore += 5;
if (checkScala(selectedCards))
currentScore += 10;
return currentScore;
};
const handleCombination = () => {
const newScore = calculateScore();
if (newScore > 0) {
setScore(score + newScore);
setSelectedCards([]); // Pulisci le carte selezionate dopo una combinazione valida
} else {
alert("Combinazione non valida!");
}
};
Aggiorniamo quindi il componente App.js inserendo un pulsante per confermare la combinazione e aggiornare il punteggio.
<button onClick={handleCombination}>Conferma Combinazione</button>
<p>Punteggio: {score}</p>
Miglioramenti nell'interfaccia utente
Per migliorare l'esperienza di gioco, aggiungiamo uno stile che evidenzi le carte selezionate e visualizzi chiaramente il punteggio totale del giocatore. In App.css possiamo aggiungere una classe per la sezione del punteggio:
/* src/App.css */
.score {
font-size: 20px;
font-weight: bold;
margin: 10px 0;
}
Inoltre, potremmo evidenziare le carte in modo più visibile usando un bordo più pronunciato o cambiando leggermente il colore di sfondo.
Conclusione
In questa lezione, abbiamo aggiunto un importante livello di interattività al nostro Solitario delle 5 Carte con React, consentendo al giocatore di selezionare carte per formare combinazioni valide. Abbiamo implementato le regole per due tipi di combinazioni — il tris e la scala — e creato un sistema di punteggio dinamico che si aggiorna automaticamente quando il giocatore conferma una combinazione valida. Questo approccio rende il gioco più avvincente e fornisce al giocatore un feedback immediato migliorando il gameplay.
Oltre a questo, abbiamo migliorato l'interfaccia visiva, evidenziando le carte selezionate per fornire un riscontro chiaro delle azioni del giocatore. Questi miglioramenti permettono di rendere più accessibili le meccaniche del gioco e l'interazione sarà essenziale per il completamento delle funzionalità di gioco nelle lezioni successive.
Nella prossima lezione faremo un ulteriore passo avanti arricchendo il gioco con una logica di fine partita. Oltre a questo, introdurremo la possibilità di registrare il punteggio e di confrontarlo con altri punteggi salvati in un database esterno. Per fare ciò, esploreremo l'uso di Node.js, Express e MongoDB per creare un sistema di salvataggio dei punteggi che sarà accessibile anche al di fuori della singola sessione di gioco.
Con questi strumenti server-side ci avvicineremo a una gestione dati più sofisticata, aprendo nuove possibilità per espandere le funzionalità del gioco come classifiche o statistiche per i giocatori.
Se vuoi aggiornamenti su Meccaniche di gioco e interattività in un Solitario con React inserisci la tua email nel box qui sotto: