Stomazzo
Descrizione
L'app di questo mese è un gioco di magia, ho voluto sfruttare diverse modalità tecnologiche per dare l'illusione che il mago sia in grado di indovinare la carta scelta dello spettatore.
Il contesto d'uso è diverso dei soliti giochi: chi vuole utilizzarla, dopo averla installata nella schermata home, deve necessariamente leggere le istruzioni d'uso che spiegano dettagliatamente il miglior modo di proporla al pubblico.
Vengono usate diverse API Javascript, alcune poco note, e purtroppo non del tutto supportate. Mi perdonino i possessori di iPhone se stavolta ho fatto un'app che è poco compatibile con i loro telefoni.
Come al solito, ecco la scheda tecnica dell'app.
Stomazzo
- Url
- https://stomazzo.it
- Github
- https://github.com/polesello/stomazzo
- Data di uscita
- 1 aprile 2024
- Caratteristiche
- SpeechSynthesis, vibrazione, MediaDevices, web-NFC
- Dispositivi
- Android
- Browser
- Chrome
Funzionamento generale
L'app contiene cinque magie diverse, ossia cinque modi tramite i quali il mago fa scegliere una carta allo spettatore per poi indovinarla.
Il processo è il seguente:
- Lo spettatore sceglie una carta del mazzo, che poi compare a pieno schermo
- Lo spettatore gira il telefono sottosopra e l'appoggia sul tavolo, in modo che lo schermo sia rivolto verso il basso
- Il mago indovina la carta scelta, o comunque interagisce con lo spettatore.
Tutte le magie partono dopo 10 secondi che il telefono è stato girato sottosopra, e vengono annullate se il telefono torna in posizione normale.
Per maggiori informazioni su come riconoscere la posizione del telefono si veda l'app Piano in tasca.
Di seguito il codice che si occupa di fare il riconoscimento della posizione sottosopra.
function checkUpsideDown(event) {
// Controlla se il telefono viene messo a faccia in giù
// e dopo 10 secondi fa partire la funzione magica
if (magicFunction) {
// facedown è un booleano che indica se il telefono è a faccia in giù
// calcolato in base alle proprietà beta e gamma dell'evento deviceorientation
// magicTimer è un timeout che fa partire la funzione magica dopo 10 secondi
const enteringFaceDown = Math.abs(event.beta) > 150 && Math.abs(event.gamma) < 30
const exitingFaceDown = Math.abs(event.beta) < 130 && Math.abs(event.gamma) > 50
if (!isFaceDown && enteringFaceDown) {
isFaceDown = true
magicTimer = setTimeout(magicFunction, 10000)
}
if (isFaceDown && exitingFaceDown) {
isFaceDown = false
clearTimeout(magicTimer)
}
}
}
Modalità 2 di picche
Qui c'è poco da dire, dopo 10 secondi la carta scelta dello spettatore viene cambiata sempre con il 2 di picche. Questa modalità è compatibile con tutti i telefoni e funziona tramite questa semplicissima funzione magica.
function changeCard() {
// Cambia la carta scelta con il 2 di picche
document.querySelector('#scelta .card').setAttribute('src', 'cards/2S.svg')
}
Modalità annuncio vocale
Dopo 10 secondi una voce sintetizzata annuncia che il giocatore ha scelto la carta, ma non dice quella giusta. Tramite un semplice calcolo mentale, il mago sarà in grado di indovinare la carta scelta.
function sayCard() {
// faccio dire non il nome della carta scelta, ma una carta diversa
// tolgo 7 al numero della carta
// e vado di un seme indietro, secondo l'ordine degli semi Cuori Quadri Fiori Picche
// Il mago dovrà quindi calcolare la carta scelta veramente dal giocatore
// aggiungendo 7 e andando di un seme avanti
const cardId = document.querySelector('#scelta .card').dataset.cardid
const SUITS = ['H', 'D', 'C', 'S']
const number = parseInt(cardId)
const suit = cardId.slice(-1)
const newNumber = number > 7 ? number - 7 : number + 6
const newSuit = SUITS[(SUITS.indexOf(suit) + 3) % 4]
const newCard = document.querySelector('img[src="cards/' + newNumber + newSuit + '.svg"]')
const frase = localStorage['frase-scelta']
const msg = new SpeechSynthesisUtterance(frase + ' ' + newCard.getAttribute('alt'))
window.speechSynthesis.speak(msg)
}
La variabile frase contiene una semplice frase predefinita come "Hai scelto il" che è possibile personalizzare dal menù iniziale.
Viene quindi creato un messaggio vocale tramite l'oggetto SpeechSynthesisUtterance che aggiunge alla frase predefinita il nome della carta, che è contenuto nell'attributo HTML alt.
Anche questa modalità è compatibile con tutti i telefoni.
Modalità vibrazione
In questa modalità viene usata l'API navigator.vibrate per produrre una sequenza di punti e linee (vibrazioni corte e lunghe) che il mago dovrà decodificare per risalire al nome della carta. La tabella di decodifica è nella pagina delle istruzioni, ho cercato di inventare una codifica che minimizzi il numero di vibrazioni emesse ma sia anche facile da imparare.
Questa modalità non è supportata da iOS ma dovrebbe essere disponibile per tutti gli Android.
function vibrateCard() {
const cardId = document.querySelector('#scelta .card').dataset.cardid
const pattern = getMorsePattern(cardId)
navigator.vibrate(pattern)
}
Non è finita qui...
Lo scrittura del manuale d'istruzioni del mago mi ha portato via più tempo del previsto, e quindi non ho ancora completato la parte tecnica, lo farò nei prossimi giorni.
È sempre gradito un riscontro tramite questo modulo.