Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b833341c5 | ||
|
|
4fe6bf4649 | ||
|
|
b10f031133 | ||
|
|
4d2278a8f8 | ||
|
|
5a38e0eafe | ||
|
|
4f2ee45abf | ||
|
|
09b031dc2e | ||
|
|
616d514fc5 | ||
|
|
b07a1e4941 | ||
|
|
f57a91ca74 | ||
|
|
f7ca286066 |
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"image": "alpino_vino.png",
|
||||
"height": 120,
|
||||
"frames": {
|
||||
"stand": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 69,
|
||||
"h": 120,
|
||||
"ax": 28.2,
|
||||
"ay": 120
|
||||
},
|
||||
"blink": {
|
||||
"x": 71,
|
||||
"y": 0,
|
||||
"w": 69,
|
||||
"h": 120,
|
||||
"ax": 28.0,
|
||||
"ay": 120
|
||||
},
|
||||
"talk": {
|
||||
"x": 142,
|
||||
"y": 0,
|
||||
"w": 72,
|
||||
"h": 120,
|
||||
"ax": 29.4,
|
||||
"ay": 120
|
||||
},
|
||||
"explain": {
|
||||
"x": 216,
|
||||
"y": 0,
|
||||
"w": 71,
|
||||
"h": 116,
|
||||
"ax": 29.3,
|
||||
"ay": 116
|
||||
},
|
||||
"pour": {
|
||||
"x": 289,
|
||||
"y": 0,
|
||||
"w": 72,
|
||||
"h": 122,
|
||||
"ax": 30.5,
|
||||
"ay": 122
|
||||
},
|
||||
"pour2": {
|
||||
"x": 363,
|
||||
"y": 0,
|
||||
"w": 73,
|
||||
"h": 122,
|
||||
"ax": 30.3,
|
||||
"ay": 122
|
||||
},
|
||||
"give": {
|
||||
"x": 438,
|
||||
"y": 0,
|
||||
"w": 66,
|
||||
"h": 118,
|
||||
"ax": 24.5,
|
||||
"ay": 118
|
||||
},
|
||||
"cheers": {
|
||||
"x": 506,
|
||||
"y": 0,
|
||||
"w": 72,
|
||||
"h": 120,
|
||||
"ax": 33.4,
|
||||
"ay": 120
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 125 KiB |
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"image": "cuochi.png",
|
||||
"height": 120,
|
||||
"frames": {
|
||||
"stand": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 95,
|
||||
"h": 120,
|
||||
"ax": 41.9,
|
||||
"ay": 120
|
||||
},
|
||||
"blink": {
|
||||
"x": 97,
|
||||
"y": 0,
|
||||
"w": 95,
|
||||
"h": 120,
|
||||
"ax": 42.6,
|
||||
"ay": 120
|
||||
},
|
||||
"talk": {
|
||||
"x": 194,
|
||||
"y": 0,
|
||||
"w": 96,
|
||||
"h": 120,
|
||||
"ax": 44.4,
|
||||
"ay": 120
|
||||
},
|
||||
"explain": {
|
||||
"x": 292,
|
||||
"y": 0,
|
||||
"w": 95,
|
||||
"h": 120,
|
||||
"ax": 44.5,
|
||||
"ay": 120
|
||||
},
|
||||
"work": {
|
||||
"x": 389,
|
||||
"y": 0,
|
||||
"w": 101,
|
||||
"h": 120,
|
||||
"ax": 46.7,
|
||||
"ay": 120
|
||||
},
|
||||
"work2": {
|
||||
"x": 492,
|
||||
"y": 0,
|
||||
"w": 101,
|
||||
"h": 119,
|
||||
"ax": 45.9,
|
||||
"ay": 119
|
||||
},
|
||||
"give": {
|
||||
"x": 595,
|
||||
"y": 0,
|
||||
"w": 104,
|
||||
"h": 121,
|
||||
"ax": 43.1,
|
||||
"ay": 121
|
||||
},
|
||||
"laugh": {
|
||||
"x": 701,
|
||||
"y": 0,
|
||||
"w": 92,
|
||||
"h": 117,
|
||||
"ax": 43.7,
|
||||
"ay": 117
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 191 KiB |
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"image": "fanfara.png",
|
||||
"height": 120,
|
||||
"frames": {
|
||||
"stand": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 107,
|
||||
"h": 120,
|
||||
"ax": 47.1,
|
||||
"ay": 120
|
||||
},
|
||||
"blink": {
|
||||
"x": 109,
|
||||
"y": 0,
|
||||
"w": 106,
|
||||
"h": 120,
|
||||
"ax": 47.1,
|
||||
"ay": 120
|
||||
},
|
||||
"talk": {
|
||||
"x": 217,
|
||||
"y": 0,
|
||||
"w": 110,
|
||||
"h": 120,
|
||||
"ax": 50.3,
|
||||
"ay": 120
|
||||
},
|
||||
"laugh": {
|
||||
"x": 329,
|
||||
"y": 0,
|
||||
"w": 107,
|
||||
"h": 120,
|
||||
"ax": 47.0,
|
||||
"ay": 120
|
||||
},
|
||||
"play": {
|
||||
"x": 438,
|
||||
"y": 0,
|
||||
"w": 112,
|
||||
"h": 113,
|
||||
"ax": 50.3,
|
||||
"ay": 113
|
||||
},
|
||||
"play2": {
|
||||
"x": 552,
|
||||
"y": 0,
|
||||
"w": 114,
|
||||
"h": 118,
|
||||
"ax": 51.8,
|
||||
"ay": 118
|
||||
},
|
||||
"play3": {
|
||||
"x": 668,
|
||||
"y": 0,
|
||||
"w": 111,
|
||||
"h": 115,
|
||||
"ax": 51.6,
|
||||
"ay": 115
|
||||
},
|
||||
"bow": {
|
||||
"x": 781,
|
||||
"y": 0,
|
||||
"w": 110,
|
||||
"h": 104,
|
||||
"ax": 51.2,
|
||||
"ay": 104
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 222 KiB |
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"image": "gente.png",
|
||||
"height": 115,
|
||||
"frames": {
|
||||
"stand": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 126,
|
||||
"h": 115,
|
||||
"ax": 62.9,
|
||||
"ay": 115
|
||||
},
|
||||
"blink": {
|
||||
"x": 128,
|
||||
"y": 0,
|
||||
"w": 125,
|
||||
"h": 115,
|
||||
"ax": 62.8,
|
||||
"ay": 115
|
||||
},
|
||||
"talk": {
|
||||
"x": 255,
|
||||
"y": 0,
|
||||
"w": 126,
|
||||
"h": 115,
|
||||
"ax": 62.9,
|
||||
"ay": 115
|
||||
},
|
||||
"talk2": {
|
||||
"x": 383,
|
||||
"y": 0,
|
||||
"w": 126,
|
||||
"h": 115,
|
||||
"ax": 63.9,
|
||||
"ay": 115
|
||||
},
|
||||
"eat": {
|
||||
"x": 511,
|
||||
"y": 0,
|
||||
"w": 128,
|
||||
"h": 117,
|
||||
"ax": 62.9,
|
||||
"ay": 117
|
||||
},
|
||||
"eat2": {
|
||||
"x": 641,
|
||||
"y": 0,
|
||||
"w": 128,
|
||||
"h": 117,
|
||||
"ax": 63.0,
|
||||
"ay": 117
|
||||
},
|
||||
"laugh": {
|
||||
"x": 771,
|
||||
"y": 0,
|
||||
"w": 127,
|
||||
"h": 117,
|
||||
"ax": 62.0,
|
||||
"ay": 117
|
||||
},
|
||||
"toast": {
|
||||
"x": 900,
|
||||
"y": 0,
|
||||
"w": 127,
|
||||
"h": 116,
|
||||
"ax": 62.5,
|
||||
"ay": 116
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 271 KiB |
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"image": "liscio.png",
|
||||
"height": 115,
|
||||
"frames": {
|
||||
"stand": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 108,
|
||||
"h": 115,
|
||||
"ax": 54.5,
|
||||
"ay": 115
|
||||
},
|
||||
"blink": {
|
||||
"x": 110,
|
||||
"y": 0,
|
||||
"w": 108,
|
||||
"h": 115,
|
||||
"ax": 54.3,
|
||||
"ay": 115
|
||||
},
|
||||
"talk": {
|
||||
"x": 220,
|
||||
"y": 0,
|
||||
"w": 111,
|
||||
"h": 115,
|
||||
"ax": 57.2,
|
||||
"ay": 115
|
||||
},
|
||||
"laugh": {
|
||||
"x": 333,
|
||||
"y": 0,
|
||||
"w": 110,
|
||||
"h": 115,
|
||||
"ax": 55.6,
|
||||
"ay": 115
|
||||
},
|
||||
"dance1": {
|
||||
"x": 445,
|
||||
"y": 0,
|
||||
"w": 117,
|
||||
"h": 112,
|
||||
"ax": 57.2,
|
||||
"ay": 112
|
||||
},
|
||||
"dance2": {
|
||||
"x": 564,
|
||||
"y": 0,
|
||||
"w": 115,
|
||||
"h": 111,
|
||||
"ax": 57.0,
|
||||
"ay": 111
|
||||
},
|
||||
"dance3": {
|
||||
"x": 681,
|
||||
"y": 0,
|
||||
"w": 115,
|
||||
"h": 112,
|
||||
"ax": 56.5,
|
||||
"ay": 112
|
||||
},
|
||||
"dance4": {
|
||||
"x": 798,
|
||||
"y": 0,
|
||||
"w": 113,
|
||||
"h": 113,
|
||||
"ax": 54.4,
|
||||
"ay": 113
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 230 KiB |
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"image": "volontari.png",
|
||||
"height": 120,
|
||||
"frames": {
|
||||
"stand": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 102,
|
||||
"h": 120,
|
||||
"ax": 48.3,
|
||||
"ay": 120
|
||||
},
|
||||
"blink": {
|
||||
"x": 104,
|
||||
"y": 0,
|
||||
"w": 102,
|
||||
"h": 120,
|
||||
"ax": 48.3,
|
||||
"ay": 120
|
||||
},
|
||||
"talk": {
|
||||
"x": 208,
|
||||
"y": 0,
|
||||
"w": 101,
|
||||
"h": 121,
|
||||
"ax": 47.4,
|
||||
"ay": 121
|
||||
},
|
||||
"explain": {
|
||||
"x": 311,
|
||||
"y": 0,
|
||||
"w": 100,
|
||||
"h": 120,
|
||||
"ax": 47.4,
|
||||
"ay": 120
|
||||
},
|
||||
"work": {
|
||||
"x": 413,
|
||||
"y": 0,
|
||||
"w": 107,
|
||||
"h": 112,
|
||||
"ax": 49.0,
|
||||
"ay": 112
|
||||
},
|
||||
"work2": {
|
||||
"x": 522,
|
||||
"y": 0,
|
||||
"w": 104,
|
||||
"h": 111,
|
||||
"ax": 47.4,
|
||||
"ay": 111
|
||||
},
|
||||
"give": {
|
||||
"x": 628,
|
||||
"y": 0,
|
||||
"w": 100,
|
||||
"h": 121,
|
||||
"ax": 47.8,
|
||||
"ay": 121
|
||||
},
|
||||
"laugh": {
|
||||
"x": 730,
|
||||
"y": 0,
|
||||
"w": 100,
|
||||
"h": 119,
|
||||
"ax": 48.2,
|
||||
"ay": 119
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 270 KiB |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 205 KiB |
@@ -675,9 +675,9 @@
|
||||
"file": "andrea-c716ab2381.mp3",
|
||||
"sec": 7.95
|
||||
},
|
||||
"andrea|Il Taglia. Io sono un metro e ottanta, e lui mi guarda dall'alto. Con la Condor in mano.": {
|
||||
"file": "andrea-f1663e7892.mp3",
|
||||
"sec": 8.52
|
||||
"andrea|Il Taglia, con la Condor in mano. Chi lo batte al campone si merita un monumento.": {
|
||||
"file": "andrea-5446c68481.mp3",
|
||||
"sec": 6.49
|
||||
},
|
||||
"andrea|Il giardino coi cedri e le panchine. All'ombra, d'estate, ci si fa la siesta a turno.": {
|
||||
"file": "andrea-4fd811d0c7.mp3",
|
||||
@@ -959,6 +959,26 @@
|
||||
"file": "andrea-bd95e65b0a.mp3",
|
||||
"sec": 4.77
|
||||
},
|
||||
"andrea|Qui sotto, fra il fiume e la strada del campo, gli alpini facevano la Smarronata.": {
|
||||
"file": "andrea-2db7b567b2.mp3",
|
||||
"sec": 5.13
|
||||
},
|
||||
"andrea|E la macchina del tempo è sempre lì, con la data pronta.": {
|
||||
"file": "andrea-11b952f96c.mp3",
|
||||
"sec": 3.63
|
||||
},
|
||||
"andrea|Sul lampione di là c'è ancora un cartello vecchio, mezzo sbiadito.": {
|
||||
"file": "andrea-111de2600b.mp3",
|
||||
"sec": 4.01
|
||||
},
|
||||
"andrea|La macchina del tempo, ferma sulla strada del ponte. Sul cruscotto c'è già ottobre 1993.": {
|
||||
"file": "andrea-0bbc838103.mp3",
|
||||
"sec": 7.34
|
||||
},
|
||||
"andrea|Imposto: 17 ottobre 1993, la domenica della Smarronata.": {
|
||||
"file": "andrea-4f096d64c3.mp3",
|
||||
"sec": 6.91
|
||||
},
|
||||
"andrea|Il tabernacolo del ponte, con l'Annunciazione di Antonio Berti, scultore sanpierino.": {
|
||||
"file": "andrea-9c0935dc77.mp3",
|
||||
"sec": 5.48
|
||||
@@ -979,6 +999,10 @@
|
||||
"file": "andrea-5bf82d4aaa.mp3",
|
||||
"sec": 6.78
|
||||
},
|
||||
"andrea|Lo lascio dov'è: dopo tutti questi anni, ormai fa parte del lampione.": {
|
||||
"file": "andrea-4289b64bed.mp3",
|
||||
"sec": 4.32
|
||||
},
|
||||
"andrea|Il campo secondario della polisportiva. Qui si allenano i piccoli, e i grandi fanno finta di non guardare.": {
|
||||
"file": "andrea-86efb05e99.mp3",
|
||||
"sec": 7.18
|
||||
@@ -1899,6 +1923,178 @@
|
||||
"file": "andrea-d32e1a2a87.mp3",
|
||||
"sec": 3.45
|
||||
},
|
||||
"andrea|Si torna nel 2007. Arrivederci, alpini: e grazie delle bruciate.": {
|
||||
"file": "andrea-2e2fac8aa0.mp3",
|
||||
"sec": 5.63
|
||||
},
|
||||
"andrea|Tutto come prima. Solo le mani, che sanno ancora di castagne.": {
|
||||
"file": "andrea-57348082a9.mp3",
|
||||
"sec": 4.44
|
||||
},
|
||||
"andrea|La Smarronata! Ottobre 1993. Si sente già l'odore delle bruciate.": {
|
||||
"file": "andrea-5b5dfdda13.mp3",
|
||||
"sec": 7.47
|
||||
},
|
||||
"andrea|Il cilindro delle bruciate: si gira la manovella sopra il fuoco, e le castagne ci ballano dentro.": {
|
||||
"file": "andrea-2603f4db73.mp3",
|
||||
"sec": 5.93
|
||||
},
|
||||
"andrea|Si gira piano, sennò le bruciate si bruciano davvero.": {
|
||||
"file": "andrea-675499a046.mp3",
|
||||
"sec": 3.07
|
||||
},
|
||||
"andrea|Una bruciata calda, presa al volo. Scotta! Ma è buonissima.": {
|
||||
"file": "andrea-ebba87b32c.mp3",
|
||||
"sec": 5.87
|
||||
},
|
||||
"andrea|Sacchi di marroni del Mugello, pronti per il fuoco.": {
|
||||
"file": "andrea-5b86ac34b1.mp3",
|
||||
"sec": 3.57
|
||||
},
|
||||
"andrea|Un sacco intero? Gli alpini mi rincorrono fino al ponte.": {
|
||||
"file": "andrea-f55b749652.mp3",
|
||||
"sec": 4.21
|
||||
},
|
||||
"andrea|La legna per il fuoco delle bruciate. Ce n'è per tutto il pomeriggio.": {
|
||||
"file": "andrea-f940d1cc48.mp3",
|
||||
"sec": 5.31
|
||||
},
|
||||
"andrea|La Smarronata del Gruppo Alpini di San Piero a Sieve: 16 e 17 ottobre.": {
|
||||
"file": "andrea-c6d4afc066.mp3",
|
||||
"sec": 5.44
|
||||
},
|
||||
"andrea|Il tendone giallo, con le tavolate e le tovaglie verdi.": {
|
||||
"file": "andrea-fd9e22e01d.mp3",
|
||||
"sec": 4.32
|
||||
},
|
||||
"andrea|I volontari della Misericordia, alle bruciate: uno rimescola, l'altro riempie i cartocci.": {
|
||||
"file": "andrea-bfd09556ea.mp3",
|
||||
"sec": 5.63
|
||||
},
|
||||
"andrea|Che Iddio ve ne renda merito!! A voi e agli alpini!": {
|
||||
"file": "andrea-6933735b75.mp3",
|
||||
"sec": 3.95
|
||||
},
|
||||
"volontari|E a te, figliolo. To', un cartoccio: son belle calde.": {
|
||||
"file": "volontari-e8705fe901.mp3",
|
||||
"sec": 5.14
|
||||
},
|
||||
"andrea|Scottano! Ma son buonissime.": {
|
||||
"file": "andrea-ff81f048f5.mp3",
|
||||
"sec": 2.79
|
||||
},
|
||||
"andrea|La fanfara degli alpini. Quando sfilavano per il paese suonando, s'affacciava tutto San Piero.": {
|
||||
"file": "andrea-a372a71849.mp3",
|
||||
"sec": 6.3
|
||||
},
|
||||
"fanfara|Un'altra? Questa la sanno anche i sassi!": {
|
||||
"file": "fanfara-d1179f98fa.mp3",
|
||||
"sec": 3.72
|
||||
},
|
||||
"andrea|La polenta degli alpini: uno gira nel paiolo, l'altro la taglia col filo.": {
|
||||
"file": "andrea-773164c1a1.mp3",
|
||||
"sec": 5.26
|
||||
},
|
||||
"cuochi|Un po' di pazienza: la polenta vuole il suo tempo.": {
|
||||
"file": "cuochi-9503d771cf.mp3",
|
||||
"sec": 3.67
|
||||
},
|
||||
"andrea|L'alpino del vino. Il naso rosso, a forza d'assaggiarlo, se l'è guadagnato.": {
|
||||
"file": "andrea-ce03d2a10e.mp3",
|
||||
"sec": 5.65
|
||||
},
|
||||
"alpino_vino|Gratis, ma col giudizio: un bicchiere a testa!": {
|
||||
"file": "alpino_vino-2a029d581d.mp3",
|
||||
"sec": 3.39
|
||||
},
|
||||
"andrea|Alla salute degli alpini!": {
|
||||
"file": "andrea-46e16fd214.mp3",
|
||||
"sec": 2.87
|
||||
},
|
||||
"alpino_vino|Alla salute!": {
|
||||
"file": "alpino_vino-7f4871f89d.mp3",
|
||||
"sec": 0.94
|
||||
},
|
||||
"andrea|La gente della festa, coi cartocci di bruciate e il bicchiere di vino.": {
|
||||
"file": "andrea-241b4a7d6a.mp3",
|
||||
"sec": 4.71
|
||||
},
|
||||
"gente|Hai visto che bruciate quest'anno? Belle grosse!": {
|
||||
"file": "gente-0f6e151dd6.mp3",
|
||||
"sec": 3.69
|
||||
},
|
||||
"andrea|Il liscio nello spiazzo: valzer e mazurche, e i nonni ballano meglio di tutti.": {
|
||||
"file": "andrea-8fff6bb18b.mp3",
|
||||
"sec": 5.82
|
||||
},
|
||||
"liscio|Balli anche te? Dai, che la mazurca la sanno tutti!": {
|
||||
"file": "liscio-9e08aa07f3.mp3",
|
||||
"sec": 4.5
|
||||
},
|
||||
"andrea|Un'altra volta. Questa macchina del tempo mi fa girare la testa già da sé.": {
|
||||
"file": "andrea-f2e4a9450c.mp3",
|
||||
"sec": 5.48
|
||||
},
|
||||
"andrea|Di lassù si torna alla strada del ponte, e alla macchina del tempo.": {
|
||||
"file": "andrea-27b72f57db.mp3",
|
||||
"sec": 3.86
|
||||
},
|
||||
"andrea|La polenta degli alpini, tagliata col filo sul tagliere.": {
|
||||
"file": "andrea-e573417a26.mp3",
|
||||
"sec": 3.47
|
||||
},
|
||||
"andrea|Una fetta di polenta. Ci vorrebbe un po' di sugo, ma va bene così.": {
|
||||
"file": "andrea-72789f9ee3.mp3",
|
||||
"sec": 5.58
|
||||
},
|
||||
"andrea|Il vino degli alpini, nelle damigiane impagliate. Sul cartello c'era scritto «gratis».": {
|
||||
"file": "andrea-3bec487739.mp3",
|
||||
"sec": 6.52
|
||||
},
|
||||
"andrea|Un bicchiere solo. Poi mi tocca guidare la macchina del tempo.": {
|
||||
"file": "andrea-9a8297b134.mp3",
|
||||
"sec": 3.95
|
||||
},
|
||||
"andrea|Il ponte sulla Sieve, visto da sotto. Di lassù, nel 2007, la macchina del tempo mi aspetta.": {
|
||||
"file": "andrea-e55ffcecfb.mp3",
|
||||
"sec": 7.28
|
||||
},
|
||||
"andrea|Tovaglie verdi di carta, le tovagliette, l'acqua e il vino. Fra poco qui non ci sarà un posto libero.": {
|
||||
"file": "andrea-9476090301.mp3",
|
||||
"sec": 7.86
|
||||
},
|
||||
"andrea|Mi siedo un attimo ad aspettare la polenta.": {
|
||||
"file": "andrea-8dbfa9b147.mp3",
|
||||
"sec": 2.32
|
||||
},
|
||||
"andrea|...Macché: sono le dieci e mezzo, la polenta arriva a mezzogiorno.": {
|
||||
"file": "andrea-2a97a4b77d.mp3",
|
||||
"sec": 4.23
|
||||
},
|
||||
"andrea|Sono degli alpini. E gli alpini, i loro cartelli, se li riportano a casa.": {
|
||||
"file": "andrea-d83f353975.mp3",
|
||||
"sec": 5.3
|
||||
},
|
||||
"andrea|In fondo il bancone, coi piatti in pila e il vino. Da lì escono i vassoi.": {
|
||||
"file": "andrea-6bf926ffc1.mp3",
|
||||
"sec": 5.62
|
||||
},
|
||||
"andrea|Altre tavolate, apparecchiate fino in fondo. Gli alpini fanno le cose in grande.": {
|
||||
"file": "andrea-f2486823cd.mp3",
|
||||
"sec": 5.75
|
||||
},
|
||||
"andrea|Le sedie di legno, quelle pieghevoli che si chiudono sulle dita.": {
|
||||
"file": "andrea-40a22ff371.mp3",
|
||||
"sec": 4.27
|
||||
},
|
||||
"andrea|Sono entrati a vedere se la polenta è pronta. Non lo è.": {
|
||||
"file": "andrea-68c8b4a477.mp3",
|
||||
"sec": 4.49
|
||||
},
|
||||
"gente|Siediti con noi, che a mezzogiorno qui non si trova un posto!": {
|
||||
"file": "gente-0f4228e156.mp3",
|
||||
"sec": 4.01
|
||||
},
|
||||
"andrea|Si torna nel 2007. Ciao Vannino, ciao Pierino.": {
|
||||
"file": "andrea-baa95acb36.mp3",
|
||||
"sec": 4.41
|
||||
@@ -2883,10 +3079,6 @@
|
||||
"file": "andrea-595df0a426.mp3",
|
||||
"sec": 2.23
|
||||
},
|
||||
"andrea|Ma quanto sei alto, Taglia?": {
|
||||
"file": "andrea-01ecdf3ed8.mp3",
|
||||
"sec": 1.96
|
||||
},
|
||||
"andrea|Ci si vede, Taglia.": {
|
||||
"file": "andrea-5d4d911c06.mp3",
|
||||
"sec": 1.42
|
||||
@@ -2915,10 +3107,6 @@
|
||||
"file": "taglia-c00be84faf.mp3",
|
||||
"sec": 11.54
|
||||
},
|
||||
"taglia|Abbastanza da vedere i pallini arrivare prima di te.": {
|
||||
"file": "taglia-d99c875252.mp3",
|
||||
"sec": 2.57
|
||||
},
|
||||
"taglia|Alla bona: ti faccio vedere dove arriva il pallino.": {
|
||||
"file": "taglia-757564b65e.mp3",
|
||||
"sec": 3.12
|
||||
@@ -3419,13 +3607,13 @@
|
||||
"file": "taglia-1e6660932d.mp3",
|
||||
"sec": 3.34
|
||||
},
|
||||
"andrea|Il Taglia, su un piede solo, è più alto di me su due.": {
|
||||
"file": "andrea-3ed6165062.mp3",
|
||||
"sec": 3.31
|
||||
"andrea|Il Taglia salta come un grillo. Io come un sacco di patate.": {
|
||||
"file": "andrea-94ed1f96a3.mp3",
|
||||
"sec": 4.54
|
||||
},
|
||||
"taglia|È questione di gambe lunghe.": {
|
||||
"file": "taglia-9782816264.mp3",
|
||||
"sec": 1.71
|
||||
"taglia|È questione di allenamento.": {
|
||||
"file": "taglia-1335b18858.mp3",
|
||||
"sec": 1.43
|
||||
},
|
||||
"andrea|Il gesso lo lascio lì. Ci giocherà qualche bambino, che è più in allenamento di me.": {
|
||||
"file": "andrea-356a1afe8d.mp3",
|
||||
@@ -3487,6 +3675,38 @@
|
||||
"file": "andrea-69337973d0.mp3",
|
||||
"sec": 5.94
|
||||
},
|
||||
"andrea|La Smarronata del 1993! Gli alpini, sotto il ponte: le bruciate, la polenta, il vino, la fanfara...": {
|
||||
"file": "andrea-4266372068.mp3",
|
||||
"sec": 10.39
|
||||
},
|
||||
"andrea|La macchina del tempo è sempre lì che aspetta.": {
|
||||
"file": "andrea-81cad76b69.mp3",
|
||||
"sec": 3.49
|
||||
},
|
||||
"andrea|Quanto lo aspettavo, da ragazzino, quel fine settimana di ottobre!": {
|
||||
"file": "andrea-db4aff7e68.mp3",
|
||||
"sec": 4.49
|
||||
},
|
||||
"andrea|Gli alpini che sfilavano per il paese suonando, col cappello e la penna: che bellezza.": {
|
||||
"file": "andrea-8b02e08972.mp3",
|
||||
"sec": 6.38
|
||||
},
|
||||
"andrea|E a scuola ci facevano disegnare i ricci delle castagne. Un ricordo meraviglioso.": {
|
||||
"file": "andrea-2bf6da91a7.mp3",
|
||||
"sec": 5.69
|
||||
},
|
||||
"andrea|Quanto ci tornerei, a una Smarronata!": {
|
||||
"file": "andrea-5deea0bdab.mp3",
|
||||
"sec": 2.59
|
||||
},
|
||||
"andrea|Ma quella... è la macchina del tempo!": {
|
||||
"file": "andrea-b4b5507b6e.mp3",
|
||||
"sec": 2.78
|
||||
},
|
||||
"andrea|Polenta e vino gratis. Gli alpini sapevano come far venire la gente.": {
|
||||
"file": "andrea-c8d1fc18a8.mp3",
|
||||
"sec": 4.63
|
||||
},
|
||||
"andrea|Mahhh... è l'INGORGOOOO!!!": {
|
||||
"file": "andrea-5694cd3779.mp3",
|
||||
"sec": 3.74
|
||||
|
||||
@@ -99,6 +99,18 @@ si segna qui con la data e il punto di `src/story/story.js` dove sta; le persone
|
||||
- **Le mutande del Barone** (Andrea, 25 ottobre; ci pensa ancora): si ritrovano e gli si riportano, e lui in cambio
|
||||
dà qualcosa che serve alla storia. Proposta: appese come trofeo all'insegna del circolino di Campomigliaio
|
||||
(l'Arcu ci scherza), e in cambio due pile per la torcia della casetta, scarica.
|
||||
- **La Smarronata del 1993** (Andrea, 31 ottobre): la festa delle castagne del Gruppo Alpini di San Piero (16-17 ottobre
|
||||
1993, con la Misericordia; manifesto col riccio-alpino col cappello e la penna). Una macchina del tempo anche per lì.
|
||||
Il posto: sotto, a diritto al ponte di Sieve, fra il fiume e la strada per andare al campo. Gli alpini col cappello
|
||||
e la penna e le camicie a quadri; le «bruciate» fatte nel cilindro a rete girato sul fuoco; gli stand gialli
|
||||
(vino gratis, polenta, col bollino dell'Ass. Naz. Alpini); lo striscione «Gli Alpini di S. Piero a Sieve
|
||||
ringraziano». Dal programma: marroni, bruciate, merenda o cena alla maniera antica, ristorante alpino, dolci casalinghi,
|
||||
polenta, crostini, ciambelline, ballo liscio, folklore alpini, fanfara, cori alpini, messa al campo la domenica.
|
||||
Sotto il tendone giallo le tavolate: tavole lunghe con le tovaglie verdi, le tovagliette di carta, le bottiglie
|
||||
d'acqua, le sedie di legno (seconda scena, dentro il tendone).
|
||||
Partenza (Andrea, 31 ottobre): dal Ponte sulla Sieve, guardando lo spiazzo lì sotto Andrea ricorda e compare la
|
||||
macchina del tempo, come col 1997 dall'Arcu.
|
||||
Riferimenti (fotogrammi di un video del 1993 e il manifesto) in `assets/raw/smarronata/`.
|
||||
- **Il sito del Barone e il Muro del Sanpierino** (Andrea, 31 ottobre): parlando col Barone, «Hai visto cosa hanno
|
||||
scritto oggi sul muro del Sanpierino?»; si apre la home di sanpiero50037.it (schermata in arrivo da Andrea) e
|
||||
cliccando sul Muro si apre il muro. Il muro vero è riesumato in `~/Workspaces/misc/spswall` (solo in locale).
|
||||
|
||||
@@ -18,6 +18,33 @@ Online su 50037.manzolo.it tutto fino agli effetti ambientali di Codex. Aperto,
|
||||
|
||||
## Dove siamo arrivati
|
||||
|
||||
- **La folla dell'Ingorgo che salta (31 ottobre)**: nelle cinque scene della festa la gente dipinta nello sfondo va su
|
||||
e giù a tempo (effetto `crowd` in render.js: la fascia della folla tagliata in strisce verticali, ognuna sobbalza sul
|
||||
battito con una fase sua; due fasce per scena, dietro piano e davanti forte, al `bpm` delle luci della scena).
|
||||
- **Il risveglio senza arretrati (31 ottobre)**: le palpebre si disegnano nette su una tela 128×72 e si allargano
|
||||
con l'interpolazione (bordo morbido senza filtri né passate), tutto sulla tela principale, una versione sola. Con
|
||||
la grafica software delle prove (swiftshader) ogni lavoro grafico si paga alla prima lettura dei pixel: dopo il
|
||||
risveglio l'arretrato era di 24 s (filtro) o 14 s (sedici passate), ora un decimo di secondo; la 0.1.62 stava a 2,5.
|
||||
Da ricordare per gli effetti futuri: niente `ctx.filter` e niente riempimenti trasparenti a tutto schermo ripetuti.
|
||||
- **La Smarronata del 1993 (31 ottobre)**: la festa delle castagne degli alpini di San Piero, sotto il ponte sulla
|
||||
Sieve fra il fiume e la strada del campo. Al Ponte sulla Sieve, sul lampione di destra, un vecchio cartello: si apre
|
||||
ingrandito (primo piano `manifesto_smarronata`, Codex dal manifesto vero, senza lo sponsor), e toccandolo i ricordi di
|
||||
Andrea (l'attesa, gli alpini che sfilavano suonando, i ricci disegnati a scuola) e la macchina del tempo. Il
|
||||
cruscotto (17/10/1993), la partenza sulla strada del ponte, e la festa (`smarronata_1993`: il bruciatore delle
|
||||
bruciate, i sacchi, la legna, gli stand della polenta e del vino, il cartellone, il ponte) e dentro il tendone giallo
|
||||
(`smarronata_tendone`, le tavolate). Sfondi di Codex dai fotogrammi del video del 1993 (`assets/raw/smarronata/`).
|
||||
«Torna al 2007» o la scaletta riportano al ponte, e la macchina sparisce. Dalle scene del viaggio (anche il
|
||||
Barrettino) la mappa non porta più via. Test in `story.test.mjs`, prova `npm run browser:smarronata`.
|
||||
Il tendone col tetto a botte e la fascia tricolore (come nel video), i cartelli dipinti della polenta e del vino gratis
|
||||
da guardare nel tendone, il fuoco vivo sotto il cilindro (effetto `fire`) col fumo. La gente (sprite di gruppo di
|
||||
Codex, inventati, vestiti come nel video): i volontari della Misericordia alle bruciate («Che Iddio ve ne renda
|
||||
merito!! A voi e agli alpini!»), la fanfara degli alpini, gli alpini della polenta e del vino, la gente coi cartocci
|
||||
(anche nel tendone), le coppie del liscio che girano (`flourish` continuo).
|
||||
La musica di Andrea (Suno): il liscio fuori, più forte vicino alle coppie (`stages`), la mazurca nel tendone.
|
||||
[DA ANDREA] le battute; un minigioco delle bruciate (girare il cilindro sul fuoco).
|
||||
- **Dedica allo zio Mario (31 ottobre)**: nei Ringraziamenti, sotto quella al Lele e più piccola: «Al mio caro zio
|
||||
Mario, che mi ha fatto vivere tante avventure più belle della fantasia.»
|
||||
- **Il Taglia (31 ottobre)**: tolte le battute sulla sua altezza (Baldoria: non gli fa piacere).
|
||||
- **Il Muro del Sanpierino sul telefonino del Barone (31 ottobre)**: il Barone ora ha un dialogo a scelte (le
|
||||
mutande, oppure «Hai visto cosa c'era sul muro del Sanpierino?»). Col muro tira fuori il telefonino, che sale dal
|
||||
basso come il libro (primo piano `muro_sanpierino`, `src/engine/telefono.js`, telefonino di Codex); nello schermo la
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
<section id="credits" class="overlay" hidden aria-label="Ringraziamenti">
|
||||
<h2>Ringraziamenti</h2>
|
||||
<p class="dedication credits-dedication">Al Lele, che mi ha fatto conoscere Monkey Island.</p>
|
||||
<p class="dedication credits-dedication dedication-small">Al mio caro zio Mario, che mi ha fatto vivere tante avventure più belle della fantasia.</p>
|
||||
<dl id="credits-list"></dl>
|
||||
<div id="credits-reel"><button class="arrow prev" type="button" aria-label="Foto precedente">‹</button><div class="track" aria-label="Le immagini del gioco: toccane una per vederla grande"></div><button class="arrow next" type="button" aria-label="Foto successiva">›</button></div>
|
||||
<p class="legal">Monkey Island è un marchio di Lucasfilm Ltd., citato solo nella dedica: questo gioco non è affiliato né approvato da Lucasfilm.</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "leggenda-del-regolo",
|
||||
"version": "0.1.62",
|
||||
"version": "0.1.63",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -16,6 +16,7 @@
|
||||
"browser:tressette": "node tests/tressette.browser.mjs",
|
||||
"browser:scopa": "node tests/scopa.browser.mjs",
|
||||
"browser:briscola": "node tests/briscola.browser.mjs",
|
||||
"browser:smarronata": "node tests/smarronata.browser.mjs",
|
||||
"browser:telefono": "node tests/telefono.browser.mjs",
|
||||
"browser:risveglio": "node tests/risveglio.browser.mjs",
|
||||
"browser:effects": "node tests/ambient.browser.mjs",
|
||||
|
||||
@@ -645,6 +645,8 @@ export class Game {
|
||||
const sc = this.story.scenes[scene];
|
||||
if (!sc?.map || !this.state.flags['visto:' + scene] || scene === this.state.scene) return false;
|
||||
if (this.busy || this.walking || this.dialogue || this.state.ended) return false;
|
||||
// Dalle scene del viaggio nel tempo (il Barrettino del 1997, la Smarronata) si torna solo con la macchina.
|
||||
if (this.scene.viaggio) return false;
|
||||
this.go(scene, sc.entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -350,6 +350,31 @@ export const EFFECTS = {
|
||||
ctx.fillRect(x0 + c, y0 + dy, 1, h);
|
||||
}
|
||||
},
|
||||
// Il fuoco di legna (il braciere delle bruciate alla Smarronata, Andrea 31 ottobre): lingue che guizzano a scatti
|
||||
// sulla base `area` [x, y, w, h], rosse fuori e gialle dentro, e un bagliore caldo che pulsa.
|
||||
fire(ctx, e, time) {
|
||||
const [x, y, w, h] = e.area, step = e.every ?? 110, n = Math.max(3, Math.round(w / 4));
|
||||
ctx.save();
|
||||
ctx.globalCompositeOperation = 'lighter';
|
||||
const g = ctx.createRadialGradient(x + w / 2, y + h / 2, 0, x + w / 2, y + h / 2, w * 0.9);
|
||||
g.addColorStop(0, `rgba(255, 140, 50, ${0.28 + 0.08 * Math.sin(time / 170)})`);
|
||||
g.addColorStop(1, 'rgba(255, 90, 30, 0)');
|
||||
ctx.fillStyle = g;
|
||||
ctx.fillRect(x - w, y - w, w * 3, w * 2.4);
|
||||
ctx.restore();
|
||||
// Ogni lingua: righe che si stringono salendo, gialla alla base, arancio a metà, rossa in punta, e ondeggia.
|
||||
for (let i = 0; i < n; i++) {
|
||||
const t = Math.floor(time / step) * 13 + i * 7, cx = x + (i + 0.5) * w / n;
|
||||
const tall = Math.round(h * (0.5 + 0.8 * hash(t))), base = y + h, lean = (hash(t + 1) - 0.5) * 3;
|
||||
for (let r = 0; r < tall; r++) {
|
||||
const k = r / tall, half = Math.max(0.5, 2.2 * (1 - k)), px = cx + lean * k;
|
||||
ctx.fillStyle = k < 0.3 ? '#ffe27a' : k < 0.65 ? '#ff9a2e' : '#d8401c';
|
||||
ctx.fillRect(Math.round(px - half), base - r - 1, Math.max(1, Math.round(half * 2)), 1);
|
||||
}
|
||||
// Una scintilla che sale, ogni tanto.
|
||||
if (hash(t + 3) < 0.25) { ctx.fillStyle = '#ffd25a'; ctx.fillRect(Math.round(cx + lean), base - tall - 2 - Math.round(hash(t + 9) * 5), 1, 1); }
|
||||
}
|
||||
},
|
||||
// Il fumo da un comignolo: sbuffi che salgono, crescono e svaniscono.
|
||||
smoke(ctx, e, time) {
|
||||
const [x, y] = e.at, life = 2600;
|
||||
@@ -493,6 +518,22 @@ export const EFFECTS = {
|
||||
},
|
||||
// Una bandiera dipinta nello sfondo che sventola: a strisce verticali che salgono e scendono, ferme dalla parte
|
||||
// dell'asta (`pole`: 'left' o 'right') e sempre più mosse verso il lembo libero.
|
||||
// La folla dell'Ingorgo che salta a tempo (Andrea, 31 ottobre): la fascia di sfondo `area` tagliata in strisce
|
||||
// verticali larghe `step`, ognuna che sobbalza sul battito (`bpm`) con una fase sua, come teste che vanno su e giù;
|
||||
// ogni striscia salta un battito sì e uno no, a turno, con un colpo secco in su e una ricaduta.
|
||||
crowd(ctx, e, time, game) {
|
||||
const bg = backgrounds.get(game.backdrop());
|
||||
if (!bg) return;
|
||||
const k = bg.width / WIDTH, [ax, ay, aw, ah] = e.area, step = e.step ?? 5, amount = e.amount ?? 3;
|
||||
const beats = time / 60000 * (e.bpm ?? 120);
|
||||
for (let x = ax; x < ax + aw; x += step) {
|
||||
const i = (x - ax) / step, b = (beats / 2 + hash(i * 17 + ay)) % 1, jump = b < 0.5 ? Math.sin(b * Math.PI) : 0;
|
||||
const dy = Math.round(amount * (0.4 + 0.6 * hash(i * 31 + 5)) * jump);
|
||||
if (!dy) continue;
|
||||
const w = Math.min(step, ax + aw - x);
|
||||
ctx.drawImage(bg, x * k, ay * k, w * k, ah * k, x, ay - dy, w, ah);
|
||||
}
|
||||
},
|
||||
cloth(ctx, e, time, game) {
|
||||
const bg = backgrounds.get(game.backdrop());
|
||||
if (!bg) return;
|
||||
@@ -722,7 +763,7 @@ export const EFFECTS = {
|
||||
ctx.restore();
|
||||
},
|
||||
};
|
||||
const BACKGROUND_EFFECTS = new Set(['sway', 'clouds', 'cloth', 'leafshadow', ...Object.keys(ambientEffects)]);
|
||||
const BACKGROUND_EFFECTS = new Set(['sway', 'clouds', 'cloth', 'leafshadow', 'crowd', ...Object.keys(ambientEffects)]);
|
||||
function drawEffects(ctx, game, time, background = false) {
|
||||
for (const e of game.scene.effects ?? []) {
|
||||
if (BACKGROUND_EFFECTS.has(e.type) !== background || !onNow(e, game)) continue;
|
||||
|
||||
@@ -30,10 +30,12 @@ export function updateRisveglio(c, def, dt) {
|
||||
return { due, end: c.t >= END && c.fired >= lines.length };
|
||||
}
|
||||
|
||||
// La nebbia è lo sfondo rimpicciolito e riallargato morbido, sopra la scena: niente filtri. Sfocare con ctx.filter
|
||||
// (rileggendo la tela) o col filter CSS sulla tela rallentava tutto il gioco anche a risveglio finito.
|
||||
const SMALL = [80, 45];
|
||||
let small = null, smallOf = null;
|
||||
// Niente filtri e niente passate a tutto schermo (ctx.filter, il filter CSS e sedici palpebre trasparenti a ogni
|
||||
// fotogramma lasciavano alla grafica un arretrato che si pagava dopo, a risveglio finito: il gioco si inceppava).
|
||||
// La nebbia è lo sfondo rimpicciolito e riallargato morbido; le palpebre si disegnano nette su una tela piccola e
|
||||
// si allargano di cinque volte con l'interpolazione, che sfuma il bordo da sé. Una versione sola, computer e telefono.
|
||||
const SMALL = [80, 45], LIDS = [128, 72];
|
||||
let small = null, smallOf = null, lids = null;
|
||||
function blurred(bg) {
|
||||
if (smallOf !== bg) {
|
||||
small ??= Object.assign(document.createElement('canvas'), { width: SMALL[0], height: SMALL[1] });
|
||||
@@ -58,9 +60,7 @@ export function drawRisveglio(ctx, c, bg) {
|
||||
ctx.drawImage(fog, dx, dy, W, H);
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
}
|
||||
// La luce del mattino che abbaglia.
|
||||
if (h > 0.01) {
|
||||
// La luce del mattino che abbaglia.
|
||||
ctx.fillStyle = `rgba(255,244,214,${0.22 * h})`;
|
||||
ctx.fillRect(0, 0, W, H);
|
||||
}
|
||||
@@ -70,21 +70,22 @@ export function drawRisveglio(ctx, c, bg) {
|
||||
v.addColorStop(1, `rgba(10,2,4,${0.85 * (1 - open * 0.75) * Math.max(h, 0.3)})`);
|
||||
ctx.fillStyle = v;
|
||||
ctx.fillRect(0, 0, W, H);
|
||||
// Le palpebre: sopra e sotto, col bordo curvo; il bordo morbido sono quattro passate sempre più chiuse e più
|
||||
// scure. Chiuse, si vede il rosso scuro della luce che passa.
|
||||
if (open < 0.999) {
|
||||
const mid = H / 2, lid = (gap, bulge, sign) => {
|
||||
const edge = mid + sign * gap, side = edge - sign * bulge, far = sign < 0 ? -20 : H + 20;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(-20, far); ctx.lineTo(W + 20, far); ctx.lineTo(W + 20, side);
|
||||
ctx.quadraticCurveTo(W / 2, edge * 2 - side, -20, side);
|
||||
ctx.closePath(); ctx.fill();
|
||||
};
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const gap = 200 * open + (3 - i) * 4, bulge = 70 + 60 * open;
|
||||
ctx.fillStyle = `rgba(22,4,6,${i === 3 ? 1 : 0.3})`;
|
||||
lid(gap, bulge, -1); lid(gap, bulge, 1);
|
||||
// Le palpebre: sopra e sotto, col bordo curvo; chiuse, si vede il rosso scuro della luce che passa.
|
||||
if (open < 0.999 && typeof document !== 'undefined') {
|
||||
lids ??= Object.assign(document.createElement('canvas'), { width: LIDS[0], height: LIDS[1] });
|
||||
const l = lids.getContext('2d'), k = LIDS[0] / W, mid = H / 2 * k, gap = 200 * open * k, bulge = (70 + 60 * open) * k;
|
||||
l.clearRect(0, 0, ...LIDS);
|
||||
l.fillStyle = 'rgb(22,4,6)';
|
||||
for (const sign of [-1, 1]) {
|
||||
const edge = mid + sign * gap, side = edge - sign * bulge, far = sign < 0 ? -4 : LIDS[1] + 4;
|
||||
l.beginPath();
|
||||
l.moveTo(-4, far); l.lineTo(LIDS[0] + 4, far); l.lineTo(LIDS[0] + 4, side);
|
||||
l.quadraticCurveTo(LIDS[0] / 2, edge * 2 - side, -4, side);
|
||||
l.closePath(); l.fill();
|
||||
}
|
||||
ctx.imageSmoothingEnabled = true;
|
||||
ctx.drawImage(lids, 0, 0, W, H);
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ function openPause() {
|
||||
voices.pause();
|
||||
ambience.configure({ active: false });
|
||||
command.reset();
|
||||
$('pause-map').hidden = !!game.closeup || game.mapPlaces().length < 2;
|
||||
$('pause-map').hidden = !!game.closeup || !!game.scene?.viaggio || game.mapPlaces().length < 2;
|
||||
$('pause').hidden = false;
|
||||
}
|
||||
function closePause() {
|
||||
@@ -1090,7 +1090,7 @@ function updateUi() {
|
||||
}
|
||||
if (mg || c?.events) for (const event of c.events.splice(0)) ambience.play(event.kind, { pan: 0, strength: event.power });
|
||||
// Il pulsante della mappa c'è solo in partita, fuori dai dialoghi, e quando c'è almeno un altro posto dove andare.
|
||||
setProp($('map-button'), 'hidden', !running || !!game.dialogue || !!game.closeup || game.mapPlaces().length < 2);
|
||||
setProp($('map-button'), 'hidden', !running || !!game.dialogue || !!game.closeup || !!game.scene?.viaggio || game.mapPlaces().length < 2);
|
||||
// «Torna al 2007»: nelle scene fuori dal tempo, finché non si parla con qualcuno.
|
||||
setProp($('back-button'), 'hidden', !running || !game.scene?.back || !!game.dialogue || !!game.closeup);
|
||||
setText($('back-button'), game.scene?.back?.label ?? '');
|
||||
|
||||
@@ -60,6 +60,16 @@ const RITORNO_2007 = [
|
||||
{ say: 'Riportata dove l\'ho presa. Se ti riviene voglia di pokerini, chiedi.', who: 'arcu', pose: 'explain' },
|
||||
];
|
||||
|
||||
// Il ritorno dalla Smarronata del 1993 (Andrea, 31 ottobre): come dal 1997, la macchina riporta al Ponte sulla Sieve
|
||||
// e sparisce; per tornarci si riguarda lo spiazzo sotto il ponte. [DA ANDREA: le battute]
|
||||
const RITORNO_1993 = [
|
||||
{ say: 'Si torna nel 2007. Arrivederci, alpini: e grazie delle bruciate.' },
|
||||
{ go: 'ponte_sieve', at: [250, 320], face: 'down' },
|
||||
{ closeup: 'arrivo_1993' },
|
||||
{ unset: 'macchina_ponte' },
|
||||
{ say: 'Tutto come prima. Solo le mani, che sanno ancora di castagne.' },
|
||||
];
|
||||
|
||||
export const story = {
|
||||
title: 'La Leggenda del Regolo',
|
||||
// La mappa (pulsante «Mappa»): ogni scena con `map: [x, y]` (percentuali della pianta) ci compare quando è
|
||||
@@ -278,6 +288,25 @@ export const story = {
|
||||
date: '10/07/1997 18:30',
|
||||
complete: [{ closeup: 'partenza' }],
|
||||
},
|
||||
// Il viaggio alla Smarronata del 1993, dal Ponte sulla Sieve (Andrea, 31 ottobre): lo stesso cruscotto, un'altra data;
|
||||
// la partenza e l'arrivo sulla strada del ponte.
|
||||
viaggio_1993: {
|
||||
type: 'viaggio',
|
||||
picture: 'assets/closeups/cruscotto-tempo.png',
|
||||
display: [220, 158, 212, 62],
|
||||
date: '17/10/1993 10:30',
|
||||
complete: [{ closeup: 'partenza_1993' }],
|
||||
},
|
||||
partenza_1993: {
|
||||
type: 'corsa', mode: 'parti', scene: 'ponte_sieve', ...MACCHINA_CORSA,
|
||||
path: [[250, 350, 1], [325, 205, 0.05]],
|
||||
complete: [{ go: 'smarronata_1993', at: [320, 330], face: 'up' }],
|
||||
},
|
||||
arrivo_1993: {
|
||||
type: 'corsa', mode: 'arriva', scene: 'ponte_sieve', ...MACCHINA_CORSA,
|
||||
path: [[150, 470, 2.2], [325, 205, 0.05]],
|
||||
complete: [],
|
||||
},
|
||||
// La partenza vista da fuori: giù per Via Liguri Magelli, il fulmine e le sgommate di fuoco; e l'arrivo, al
|
||||
// ritorno dal 1997 (Andrea, 30 ottobre; la macchina da dietro e davanti è di Codex).
|
||||
partenza: {
|
||||
@@ -327,7 +356,7 @@ export const story = {
|
||||
picture: 'assets/closeups/campone-campana.png',
|
||||
names: { player: 'Andrea', cpu: 'il Taglia' },
|
||||
win: [{ say: 'Dalla 1 fino in cima, e ritorno. A ventisett\'anni, davanti alle poste.' }, { say: 'Te lo dico io: se ti vede qualcuno, domani lo sa tutto il paese.', who: 'taglia', pose: 'laugh' }, { set: 'campana_vinta' }],
|
||||
lose: [{ say: 'Il Taglia, su un piede solo, è più alto di me su due.' }, { say: 'È questione di gambe lunghe.', who: 'taglia', pose: 'explain' }],
|
||||
lose: [{ say: 'Il Taglia salta come un grillo. Io come un sacco di patate.' }, { say: 'È questione di allenamento.', who: 'taglia', pose: 'explain' }],
|
||||
draw: [],
|
||||
quit: [{ say: 'Il gesso lo lascio lì. Ci giocherà qualche bambino, che è più in allenamento di me.' }],
|
||||
},
|
||||
@@ -391,6 +420,32 @@ export const story = {
|
||||
{ say: 'La festa è domani: se nessuno lo ritrova, salta tutto. Tocca a me.' },
|
||||
],
|
||||
},
|
||||
// Il vecchio cartello della Smarronata sul lampione del ponte, ingrandito (Codex dal manifesto vero del 1993, senza lo
|
||||
// sponsor): toccandolo, il ricordo e la macchina del tempo. [DA ANDREA: le battute]
|
||||
manifesto_smarronata: {
|
||||
type: 'poster',
|
||||
picture: 'assets/closeups/manifesto-smarronata.png',
|
||||
hint: 'Tocca il cartello',
|
||||
tap: [
|
||||
{ say: 'La Smarronata del 1993! Gli alpini, sotto il ponte: le bruciate, la polenta, il vino, la fanfara...' },
|
||||
{ if: 'macchina_ponte', then: [{ say: 'La macchina del tempo è sempre lì che aspetta.' }], else: [
|
||||
// I ricordi di Andrea (31 ottobre).
|
||||
{ say: 'Quanto lo aspettavo, da ragazzino, quel fine settimana di ottobre!' },
|
||||
{ say: 'Gli alpini che sfilavano per il paese suonando, col cappello e la penna: che bellezza.' },
|
||||
{ say: 'E a scuola ci facevano disegnare i ricci delle castagne. Un ricordo meraviglioso.' },
|
||||
{ say: 'Quanto ci tornerei, a una Smarronata!' },
|
||||
{ set: 'macchina_ponte' },
|
||||
{ say: 'Ma quella... è la macchina del tempo!' },
|
||||
] },
|
||||
],
|
||||
},
|
||||
// I cartelli dipinti della Smarronata, polenta e vino gratis (Codex dai fotogrammi del video del 1993). [DA ANDREA]
|
||||
cartelli_smarronata: {
|
||||
type: 'poster',
|
||||
picture: 'assets/closeups/cartelli-smarronata.png',
|
||||
hint: 'Tocca per tornare',
|
||||
tap: [{ say: 'Polenta e vino gratis. Gli alpini sapevano come far venire la gente.' }],
|
||||
},
|
||||
// L'incantesimo dell'Ingorgo Sonoro, dal manifesto in piazza: luci, cassa, lampo, ed è la notte della festa.
|
||||
ingorgo: {
|
||||
type: 'incanto',
|
||||
@@ -467,6 +522,13 @@ export const story = {
|
||||
andrea_pesca: { name: 'Andrea', sprite: 'assets/characters/andrea-pesca.json' },
|
||||
// Quattro ragazzi inventati (sprite di Codex, idea di Andrea del 27 ottobre): nessuna persona reale.
|
||||
pescatori: { name: 'I ragazzi delle canne', color: '#b8f08a', sprite: 'assets/characters/pescatori.json' },
|
||||
// La gente della Smarronata del 1993 (Andrea, 31 ottobre): tutti inventati, vestiti come nei fotogrammi del video.
|
||||
volontari: { name: 'I volontari della Misericordia', color: '#c8d0b0', sprite: 'assets/characters/volontari.json' },
|
||||
fanfara: { name: 'La fanfara degli alpini', color: '#e0c060', sprite: 'assets/characters/fanfara.json' },
|
||||
cuochi: { name: 'Gli alpini della polenta', color: '#f0d070', sprite: 'assets/characters/cuochi.json' },
|
||||
alpino_vino: { name: 'L\'alpino del vino', color: '#e08080', sprite: 'assets/characters/alpino_vino.json' },
|
||||
gente: { name: 'La gente della festa', color: '#d8b8a0', sprite: 'assets/characters/gente.json' },
|
||||
liscio: { name: 'Le coppie del liscio', color: '#f0a0a0', sprite: 'assets/characters/liscio.json' },
|
||||
vecchietta: { name: 'Vecchietta', color: '#ffd27a', sprite: 'assets/characters/vecchietta.json' },
|
||||
vecchietto: { name: 'Vecchietto', color: '#9fe3ff', sprite: 'assets/characters/vecchietto.json' },
|
||||
castello: { name: 'Lo spirito del Trebbio', color: '#c8f0ff' },
|
||||
@@ -642,7 +704,7 @@ export const story = {
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-house.mp3', at: [195, 235] },
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-latino.mp3', at: [-160, 250], far: 600 },
|
||||
],
|
||||
effects: [{ type: 'stagelights', phase: 'ingorgo', from: [[116, 146], [276, 146], [196, 140]], wash: [200, 215, 170], bpm: 124, beams: 3, strobe: 4, pulse: 0.08 }, { type: 'lasers', phase: 'ingorgo', at: [196, 150], count: 7, color: '255,60,200', len: 360 }, { type: 'floorspots', phase: 'ingorgo', area: [40, 240, 560, 110], bpm: 124, count: 7 }, { type: 'clouds', area: [160, 0, 440, 80], count: 3, big: true, phase: ['pomeriggio', 'tramonto', 'sera'] }, { type: 'windows', phase: 'sera', rects: [[16, 37, 8, 18], [48, 42, 8, 18], [50, 110, 8, 16], [97, 77, 8, 12], [122, 80, 8, 12], [170, 90, 8, 12], [204, 103, 8, 12], [239, 111, 8, 12], [268, 117, 7, 14], [287, 125, 6, 14], [97, 130, 9, 14], [127, 133, 9, 14], [170, 142, 9, 14], [204, 150, 8, 12], [239, 155, 8, 12], [268, 160, 7, 14], [287, 163, 6, 14], [386, 163, 14, 16], [424, 160, 14, 16], [472, 157, 14, 16], [524, 155, 14, 16], [390, 212, 14, 16], [526, 208, 14, 16]] }, { type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [150, 20, 460, 80] }],
|
||||
effects: [{ type: 'crowd', phase: 'ingorgo', area: [0, 205, 640, 70], bpm: 124, amount: 3 }, { type: 'crowd', phase: 'ingorgo', area: [0, 275, 640, 85], bpm: 124, amount: 5 }, { type: 'stagelights', phase: 'ingorgo', from: [[116, 146], [276, 146], [196, 140]], wash: [200, 215, 170], bpm: 124, beams: 3, strobe: 4, pulse: 0.08 }, { type: 'lasers', phase: 'ingorgo', at: [196, 150], count: 7, color: '255,60,200', len: 360 }, { type: 'floorspots', phase: 'ingorgo', area: [40, 240, 560, 110], bpm: 124, count: 7 }, { type: 'clouds', area: [160, 0, 440, 80], count: 3, big: true, phase: ['pomeriggio', 'tramonto', 'sera'] }, { type: 'windows', phase: 'sera', rects: [[16, 37, 8, 18], [48, 42, 8, 18], [50, 110, 8, 16], [97, 77, 8, 12], [122, 80, 8, 12], [170, 90, 8, 12], [204, 103, 8, 12], [239, 111, 8, 12], [268, 117, 7, 14], [287, 125, 6, 14], [97, 130, 9, 14], [127, 133, 9, 14], [170, 142, 9, 14], [204, 150, 8, 12], [239, 155, 8, 12], [268, 160, 7, 14], [287, 163, 6, 14], [386, 163, 14, 16], [424, 160, 14, 16], [472, 157, 14, 16], [524, 155, 14, 16], [390, 212, 14, 16], [526, 208, 14, 16]] }, { type: 'birds', phase: ['pomeriggio', 'tramonto'], area: [150, 20, 460, 80] }],
|
||||
walk: [[84, 244], [330, 238], [345, 230], [362, 238], [462, 246], [466, 276], [544, 276], [548, 248], [588, 250], [600, 290], [640, 300], [640, 360], [0, 360], [0, 330], [84, 318]],
|
||||
depth: [[236, 0.5], [360, 1.35]],
|
||||
entry: [345, 240],
|
||||
@@ -1518,7 +1580,7 @@ export const story = {
|
||||
{
|
||||
id: 'taglia', name: 'il Taglia', box: [448, 224, 44, 72], at: [430, 306], face: 'right', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'Il Taglia. Io sono un metro e ottanta, e lui mi guarda dall\'alto. Con la Condor in mano.' }],
|
||||
look: [{ say: 'Il Taglia, con la Condor in mano. Chi lo batte al campone si merita un monumento.' }],
|
||||
talk: [{ dialogue: 'taglia' }],
|
||||
},
|
||||
},
|
||||
@@ -1679,7 +1741,7 @@ export const story = {
|
||||
// Le console dell'Ingorgo Sonoro (music.js, mix). [DA ANDREA: quale genere suonava in quale piazza]
|
||||
// La tecno davanti alla casetta bianca; l'underground arriva da giù, da Via dell'Antica Posta.
|
||||
// Le luci da palco della festa (render.js: stagelights, lasers, mirrorball).
|
||||
effects: [{ type: 'lasers', phase: 'ingorgo', at: [400, 198], count: 13, len: 460 }, { type: 'lasers', phase: 'ingorgo', at: [370, 200], count: 7, color: '60,220,255' }, { type: 'stagelights', phase: 'ingorgo', from: [[356, 192], [460, 192], [408, 186]], wash: [408, 225, 180], bpm: 132, beams: 3, strobe: 2, pulse: 0.1, colors: ['90,255,110', '255,255,255', '60,220,255'] }, { type: 'floorspots', phase: 'ingorgo', area: [40, 250, 560, 100], bpm: 132, count: 8, colors: ['90,255,110', '255,255,255', '60,220,255'] }],
|
||||
effects: [{ type: 'crowd', phase: 'ingorgo', area: [0, 215, 640, 65], bpm: 132, amount: 3 }, { type: 'crowd', phase: 'ingorgo', area: [0, 280, 640, 80], bpm: 132, amount: 5 }, { type: 'lasers', phase: 'ingorgo', at: [400, 198], count: 13, len: 460 }, { type: 'lasers', phase: 'ingorgo', at: [370, 200], count: 7, color: '60,220,255' }, { type: 'stagelights', phase: 'ingorgo', from: [[356, 192], [460, 192], [408, 186]], wash: [408, 225, 180], bpm: 132, beams: 3, strobe: 2, pulse: 0.1, colors: ['90,255,110', '255,255,255', '60,220,255'] }, { type: 'floorspots', phase: 'ingorgo', area: [40, 250, 560, 100], bpm: 132, count: 8, colors: ['90,255,110', '255,255,255', '60,220,255'] }],
|
||||
stages: [
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-techno.mp3', at: [495, 245] },
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-underground.mp3', at: [700, 300], far: 650 },
|
||||
@@ -1725,7 +1787,7 @@ export const story = {
|
||||
// Le console dell'Ingorgo Sonoro (music.js, mix). [DA ANDREA: quale genere suonava in quale piazza]
|
||||
// Il bar della birra sui gradini; il latino dal Comune a sinistra, la house giù dalla piazza, l'underground su in cima.
|
||||
// Le luci da palco della festa (render.js: stagelights, lasers, mirrorball).
|
||||
effects: [{ type: 'stagelights', phase: 'ingorgo', wash: [90, 190, 130], bpm: 98, colors: ['255,170,60', '255,90,160'], pulse: 0.05 }, { type: 'stagelights', phase: 'ingorgo', from: [[430, 205], [130, 150]], beams: 2, len: 260, bpm: 98 }, { type: 'floorspots', phase: 'ingorgo', area: [40, 230, 560, 120], bpm: 98, count: 5 }],
|
||||
effects: [{ type: 'crowd', phase: 'ingorgo', area: [0, 190, 640, 70], bpm: 98, amount: 3 }, { type: 'crowd', phase: 'ingorgo', area: [0, 260, 640, 100], bpm: 98, amount: 5 }, { type: 'stagelights', phase: 'ingorgo', wash: [90, 190, 130], bpm: 98, colors: ['255,170,60', '255,90,160'], pulse: 0.05 }, { type: 'stagelights', phase: 'ingorgo', from: [[430, 205], [130, 150]], beams: 2, len: 260, bpm: 98 }, { type: 'floorspots', phase: 'ingorgo', area: [40, 230, 560, 120], bpm: 98, count: 5 }],
|
||||
stages: [
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-latino.mp3', at: [-110, 250] },
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-house.mp3', at: [320, 560] },
|
||||
@@ -1774,7 +1836,7 @@ export const story = {
|
||||
// Le console dell'Ingorgo Sonoro (music.js, mix). [DA ANDREA: quale genere suonava in quale piazza]
|
||||
// La console del latino davanti al Comune; la house arriva da giù, dalla piazza.
|
||||
// Le luci da palco della festa (render.js: stagelights, lasers, mirrorball).
|
||||
effects: [{ type: 'stagelights', phase: 'ingorgo', from: [[232, 212], [332, 212], [282, 205]], wash: [282, 228, 170], bpm: 98, beams: 3, strobe: 8, pulse: 0.08, colors: ['255,120,40', '255,60,120', '255,200,60', '200,80,255'] }, { type: 'floorspots', phase: 'ingorgo', area: [40, 250, 560, 100], bpm: 98, count: 7, colors: ['255,120,40', '255,60,120', '255,200,60', '200,80,255'] }],
|
||||
effects: [{ type: 'crowd', phase: 'ingorgo', area: [0, 240, 640, 50], bpm: 98, amount: 3 }, { type: 'crowd', phase: 'ingorgo', area: [0, 290, 640, 70], bpm: 98, amount: 5 }, { type: 'stagelights', phase: 'ingorgo', from: [[232, 212], [332, 212], [282, 205]], wash: [282, 228, 170], bpm: 98, beams: 3, strobe: 8, pulse: 0.08, colors: ['255,120,40', '255,60,120', '255,200,60', '200,80,255'] }, { type: 'floorspots', phase: 'ingorgo', area: [40, 250, 560, 100], bpm: 98, count: 7, colors: ['255,120,40', '255,60,120', '255,200,60', '200,80,255'] }],
|
||||
stages: [
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-latino.mp3', at: [290, 235] },
|
||||
{ when: 'ingorgo', music: 'assets/audio/ingorgo-house.mp3', at: [260, 640], far: 700 },
|
||||
@@ -1832,7 +1894,7 @@ export const story = {
|
||||
// Le luci da palco della festa (render.js: stagelights, lasers, mirrorball).
|
||||
// Qui le luci sono quelle di Codex (Andrea, 30 ottobre: «l'effetto qui mi piaceva molto»): teste sulle casse a
|
||||
// destra, la palla a specchi che proietta sui due muri e sulla folla, le lampade a inseguimento sulla traversa.
|
||||
effects: [
|
||||
effects: [{ type: 'crowd', phase: 'ingorgo', area: [0, 185, 640, 75], bpm: 122, amount: 3 }, { type: 'crowd', phase: 'ingorgo', area: [0, 260, 640, 100], bpm: 122, amount: 5 },
|
||||
{ type: 'pixelbeams', phase: 'ingorgo', from: [[499, 177], [620, 153]], wash: [568, 220, 70], bpm: 122, aim: -0.35, spread: 0.55, sweep: 8, power: 0.28, colors: ['155,65,255', '65,110,255'] },
|
||||
{ type: 'mirrorball', phase: 'ingorgo', at: [550, 131], hang: 91, from: [499, 177], surfaces: [[430, 60, 205, 140], [18, 105, 155, 85], [35, 245, 570, 105]], bpm: 122, count: 72 },
|
||||
{ type: 'stagechase', phase: 'ingorgo', points: [[533, 210], [557, 210], [583, 209], [609, 208]], bpm: 122, colors: ['155,65,255', '65,110,255'] },
|
||||
@@ -2031,7 +2093,30 @@ export const story = {
|
||||
walk: [[0, 360], [0, 252], [180, 226], [300, 202], [342, 202], [380, 214], [330, 238], [330, 300], [460, 330], [640, 318], [640, 360]],
|
||||
depth: [[202, 0.4], [360, 1.15]],
|
||||
entry: [300, 350],
|
||||
// La macchina del tempo per la Smarronata del 1993, dopo il ricordo dello spiazzo (Andrea, 31 ottobre).
|
||||
people: [{ who: 'macchina', when: 'macchina_ponte', at: [250, 300], size: 1.5, idle: 'stand', talk: [] }],
|
||||
hotspots: [
|
||||
{
|
||||
// Sotto, a diritto al ponte, fra il fiume e la strada per andare al campo: lì gli alpini facevano la
|
||||
// Smarronata (Andrea, 31 ottobre). Guardandolo, Andrea ricorda, e compare la macchina del tempo.
|
||||
// [DA ANDREA: le battute sono provvisorie]
|
||||
id: 'spiazzo_smarronata', name: 'lo spiazzo sotto il ponte', box: [190, 196, 60, 20], at: [250, 236], face: 'up',
|
||||
actions: {
|
||||
look: [
|
||||
{ say: 'Qui sotto, fra il fiume e la strada del campo, gli alpini facevano la Smarronata.' },
|
||||
{ if: 'macchina_ponte', then: [{ say: 'E la macchina del tempo è sempre lì, con la data pronta.' }],
|
||||
else: [{ say: 'Sul lampione di là c\'è ancora un cartello vecchio, mezzo sbiadito.' }] },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'macchina_ponte', name: 'macchina del tempo', box: [190, 262, 120, 50], at: [250, 326], face: 'up', default: 'use', when: 'macchina_ponte',
|
||||
actions: {
|
||||
look: [{ say: 'La macchina del tempo, ferma sulla strada del ponte. Sul cruscotto c\'è già ottobre 1993.' }],
|
||||
use: [{ say: 'Imposto: 17 ottobre 1993, la domenica della Smarronata.' }, { closeup: 'viaggio_1993' }],
|
||||
open: [{ say: 'Imposto: 17 ottobre 1993, la domenica della Smarronata.' }, { closeup: 'viaggio_1993' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'tabernacolo', name: 'tabernacolo dell\'Annunciazione', box: [138, 148, 36, 60], at: [180, 236], face: 'up',
|
||||
actions: {
|
||||
@@ -2049,6 +2134,18 @@ export const story = {
|
||||
look: [{ say: 'Sotto il ponte la Carza si butta nella Sieve, e da qui vanno avanti insieme.' }, { say: 'Nel 1758 la piena arrivò fino a Cardetole: in casa mia, di sicuro, c\'erano i pesci.' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
// Dopo la Sieve, che gli sta dietro: l'ultimo dell'elenco vince il clic.
|
||||
// Il vecchio cartello della Smarronata legato al lampione sopra lo spiazzo (Andrea, 31 ottobre): si apre
|
||||
// ingrandito come il manifesto dell'Ingorgo, e toccandolo parte il ricordo e arriva la macchina del tempo.
|
||||
id: 'cartello_smarronata', name: 'il vecchio cartello della Smarronata', box: [528, 168, 26, 32], at: [352, 212], face: 'right',
|
||||
art: [{ rect: [535, 175, 12, 17], fill: '#e9e2cc' }, { rect: [536, 176, 10, 2], fill: '#2f6b32' }, { rect: [536, 179, 5, 5], fill: '#5b4a2a' },
|
||||
{ rect: [542, 180, 4, 5], fill: '#2f6b32' }, { rect: [536, 186, 10, 1], fill: '#b7342e' }, { rect: [536, 188, 8, 1], fill: '#3b3b44' }],
|
||||
actions: {
|
||||
look: [{ closeup: 'manifesto_smarronata' }],
|
||||
take: [{ say: 'Lo lascio dov\'è: dopo tutti questi anni, ormai fa parte del lampione.' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'alla_polisportiva', name: 'di là dal ponte, il campo sportivo', box: [250, 180, 110, 36], at: [320, 206], exit: { scene: 'polisportiva_principale', at: [40, 330], face: 'right' },
|
||||
},
|
||||
@@ -3600,6 +3697,202 @@ export const story = {
|
||||
},
|
||||
// Il Barrettino il 10 luglio 1997 alle 18:30 (Andrea, 29 ottobre; l'interno è una proposta di Codex, [DA ANDREA]):
|
||||
// Vannino e Pierino Parigi con la tavola apparecchiata da poker. Si torna nel 2007 dalla porta.
|
||||
// La Smarronata del 1993 (Andrea, 31 ottobre): la festa delle castagne del Gruppo Alpini di San Piero, sotto il ponte
|
||||
// sulla Sieve, fra il fiume e la strada del campo. Sfondo di Codex dai fotogrammi del video del 1993
|
||||
// (assets/raw/smarronata). Ci si arriva solo con la macchina del tempo. [DA ANDREA: battute, alpini, minigioco]
|
||||
smarronata_1993: {
|
||||
name: 'La Smarronata, 17 ottobre 1993',
|
||||
viaggio: true,
|
||||
back: { label: 'Torna al 2007', actions: RITORNO_1993 },
|
||||
background: 'assets/scenes/smarronata-1993.png',
|
||||
// Il fuoco sotto il cilindro delle bruciate, col fumo che sale (Andrea, 31 ottobre).
|
||||
effects: [{ type: 'fire', area: [206, 219, 36, 8] }, { type: 'smoke', at: [226, 186] }, { type: 'smoke', at: [214, 192] }],
|
||||
// La gente della festa (Andrea, 31 ottobre: «rendiamola bella come allora»): i volontari della Misericordia alle
|
||||
// bruciate, la fanfara degli alpini, gli alpini della polenta e del vino, la gente coi cartocci, il liscio.
|
||||
// Il liscio di Andrea (Suno, 31 ottobre): più forte vicino alle coppie che ballano, più piano verso il ponte.
|
||||
stages: [{ music: 'assets/audio/liscio.mp3', at: [430, 300], near: 130, far: 620, floor: 0.35 }],
|
||||
speakers: { volontari: [176, 144], fanfara: [330, 141], cuochi: [474, 148], alpino_vino: [606, 159], gente: [250, 196], liscio: [430, 201] },
|
||||
people: [
|
||||
{ who: 'volontari', at: [176, 262], size: 1.35, idle: 'stand', talk: ['talk', 'explain'], blink: 'blink', every: 4.4, flourish: { poses: ['work', 'work2'], every: 5, for: 3.6, step: 0.45 } },
|
||||
{ who: 'fanfara', at: [330, 244], size: 1.35, idle: 'stand', talk: ['talk', 'laugh'], blink: 'blink', every: 5.2, flourish: { poses: ['play', 'play2', 'play3', 'play2'], every: 7, for: 5.6, step: 0.35 } },
|
||||
{ who: 'cuochi', at: [474, 258], size: 1.3, idle: 'stand', talk: ['talk', 'explain'], blink: 'blink', every: 4.8, offset: 1.5, flourish: { poses: ['work', 'work2'], every: 4.6, for: 3.2, step: 0.4 } },
|
||||
{ who: 'alpino_vino', at: [606, 270], size: 1.2, facing: -1, idle: 'stand', talk: ['talk', 'explain'], blink: 'blink', every: 3.9, flourish: { poses: ['pour', 'pour2', 'give'], every: 8, for: 2.4, step: 0.6 } },
|
||||
{ who: 'liscio', at: [430, 318], idle: 'dance1', talk: ['talk', 'laugh'], flourish: { poses: ['dance1', 'dance2', 'dance3', 'dance4'], every: 2.4, for: 2.4, step: 0.3 } },
|
||||
{ who: 'gente', at: [250, 308], idle: 'stand', talk: ['talk', 'talk2'], blink: 'blink', every: 4.1, flourish: { poses: ['eat', 'eat2', 'eat', 'eat2'], every: 6, for: 2.4, step: 0.5 } },
|
||||
],
|
||||
walk: [[125, 245], [330, 232], [590, 238], [600, 262], [420, 292], [400, 360], [250, 360], [240, 276], [125, 276]],
|
||||
depth: [[232, 0.55], [360, 1.2]],
|
||||
entry: [320, 340],
|
||||
enter: [{ if: '!visto_1993', then: [{ set: 'visto_1993' }, { say: 'La Smarronata! Ottobre 1993. Si sente già l\'odore delle bruciate.' }] }],
|
||||
// Il cartellone sopra la festa, e i cartelli degli stand (come nel video: vino gratis, polenta).
|
||||
art: [
|
||||
{ text: 'LA SMARRONATA', at: [191, 134], size: 5, fill: '#2f6b32' },
|
||||
{ text: 'ALPINI S.PIERO', at: [191, 144], size: 4, fill: '#b7342e' },
|
||||
],
|
||||
hotspots: [
|
||||
{
|
||||
id: 'bruciatore', name: 'il cilindro delle bruciate', box: [192, 188, 68, 54], at: [226, 262], face: 'up',
|
||||
actions: {
|
||||
look: [{ say: 'Il cilindro delle bruciate: si gira la manovella sopra il fuoco, e le castagne ci ballano dentro.' }],
|
||||
use: [{ say: 'Si gira piano, sennò le bruciate si bruciano davvero.' }],
|
||||
take: [{ say: 'Una bruciata calda, presa al volo. Scotta! Ma è buonissima.' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'sacchi', name: 'i sacchi di castagne', box: [110, 202, 58, 40], at: [150, 262], face: 'up',
|
||||
actions: { look: [{ say: 'Sacchi di marroni del Mugello, pronti per il fuoco.' }], take: [{ say: 'Un sacco intero? Gli alpini mi rincorrono fino al ponte.' }] },
|
||||
},
|
||||
{
|
||||
id: 'legna', name: 'la catasta di legna', box: [262, 206, 48, 34], at: [286, 254], face: 'up',
|
||||
actions: { look: [{ say: 'La legna per il fuoco delle bruciate. Ce n\'è per tutto il pomeriggio.' }] },
|
||||
},
|
||||
{
|
||||
id: 'cartellone', name: 'il cartellone della festa', box: [153, 122, 76, 31], at: [226, 262], face: 'up',
|
||||
actions: { look: [{ say: 'La Smarronata del Gruppo Alpini di San Piero a Sieve: 16 e 17 ottobre.' }] },
|
||||
},
|
||||
{
|
||||
id: 'tendone', name: 'il tendone giallo', box: [330, 146, 260, 86], at: [430, 244], face: 'up', default: 'walk',
|
||||
actions: {
|
||||
look: [{ say: 'Il tendone giallo, con le tavolate e le tovaglie verdi.' }],
|
||||
walk: [{ walk: [430, 244] }, { go: 'smarronata_tendone', at: [320, 340], face: 'up' }],
|
||||
open: [{ walk: [430, 244] }, { go: 'smarronata_tendone', at: [320, 340], face: 'up' }],
|
||||
},
|
||||
},
|
||||
// La gente: ultima nell'elenco, così sta sopra le cose dello sfondo. [DA ANDREA: le battute]
|
||||
{
|
||||
id: 'volontari', name: 'i volontari della Misericordia', box: [130, 148, 97, 114], at: [200, 272], face: 'left', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'I volontari della Misericordia, alle bruciate: uno rimescola, l\'altro riempie i cartocci.' }],
|
||||
talk: [
|
||||
{ say: 'Che Iddio ve ne renda merito!! A voi e agli alpini!' },
|
||||
{ say: 'E a te, figliolo. To\', un cartoccio: son belle calde.', who: 'volontari', pose: 'give' },
|
||||
{ say: 'Scottano! Ma son buonissime.' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'fanfara', name: 'la fanfara degli alpini', box: [291, 145, 88, 99], at: [330, 262], face: 'up', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'La fanfara degli alpini. Quando sfilavano per il paese suonando, s\'affacciava tutto San Piero.' }],
|
||||
talk: [{ say: 'Un\'altra? Questa la sanno anche i sassi!', who: 'fanfara', pose: 'laugh' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'cuochi', name: 'gli alpini della polenta', box: [437, 152, 84, 106], at: [474, 270], face: 'up', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'La polenta degli alpini: uno gira nel paiolo, l\'altro la taglia col filo.' }],
|
||||
talk: [{ say: 'Un po\' di pazienza: la polenta vuole il suo tempo.', who: 'cuochi', pose: 'explain' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'alpino_vino', name: 'l\'alpino del vino', box: [581, 163, 62, 107], at: [565, 262], face: 'right', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'L\'alpino del vino. Il naso rosso, a forza d\'assaggiarlo, se l\'è guadagnato.' }],
|
||||
talk: [
|
||||
{ say: 'Gratis, ma col giudizio: un bicchiere a testa!', who: 'alpino_vino', pose: 'give' },
|
||||
{ say: 'Alla salute degli alpini!' },
|
||||
{ say: 'Alla salute!', who: 'alpino_vino', pose: 'cheers' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'gente', name: 'la gente della festa', box: [191, 200, 118, 108], at: [320, 330], face: 'left', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'La gente della festa, coi cartocci di bruciate e il bicchiere di vino.' }],
|
||||
talk: [{ say: 'Hai visto che bruciate quest\'anno? Belle grosse!', who: 'gente', pose: 'talk2' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'liscio', name: 'le coppie del liscio', box: [376, 205, 107, 113], at: [340, 330], face: 'right', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'Il liscio nello spiazzo: valzer e mazurche, e i nonni ballano meglio di tutti.' }],
|
||||
talk: [
|
||||
{ say: 'Balli anche te? Dai, che la mazurca la sanno tutti!', who: 'liscio', pose: 'talk' },
|
||||
{ say: 'Un\'altra volta. Questa macchina del tempo mi fa girare la testa già da sé.' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
// La scaletta del terrazzino, in basso a sinistra: si risale alla strada, e alla macchina del tempo.
|
||||
id: 'scaletta_1993', name: 'su, alla strada: si torna nel 2007', box: [0, 280, 110, 80], at: [250, 340], face: 'left', default: 'walk',
|
||||
actions: { look: [{ say: 'Di lassù si torna alla strada del ponte, e alla macchina del tempo.' }], walk: RITORNO_1993, open: RITORNO_1993 },
|
||||
},
|
||||
{
|
||||
id: 'stand_polenta', name: 'lo stand della polenta', box: [504, 175, 74, 80], at: [520, 262], face: 'up',
|
||||
actions: { look: [{ say: 'La polenta degli alpini, tagliata col filo sul tagliere.' }], take: [{ say: 'Una fetta di polenta. Ci vorrebbe un po\' di sugo, ma va bene così.' }] },
|
||||
},
|
||||
{
|
||||
id: 'stand_vino', name: 'lo stand del vino', box: [579, 158, 61, 104], at: [570, 262], face: 'right',
|
||||
actions: {
|
||||
look: [{ say: 'Il vino degli alpini, nelle damigiane impagliate. Sul cartello c\'era scritto «gratis».' }],
|
||||
take: [{ say: 'Un bicchiere solo. Poi mi tocca guidare la macchina del tempo.' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'ponte_1993', name: 'il ponte sulla Sieve', box: [14, 132, 186, 76], at: [150, 262], face: 'up',
|
||||
actions: { look: [{ say: 'Il ponte sulla Sieve, visto da sotto. Di lassù, nel 2007, la macchina del tempo mi aspetta.' }] },
|
||||
},
|
||||
],
|
||||
},
|
||||
// Sotto il tendone giallo della Smarronata: le tavolate con le tovaglie verdi (Andrea, 31 ottobre; sfondo di Codex
|
||||
// dal fotogramma del video del 1993). [DA ANDREA: le battute, e chi c'era a tavola]
|
||||
smarronata_tendone: {
|
||||
name: 'Il tendone della Smarronata, 1993',
|
||||
viaggio: true,
|
||||
back: { label: 'Torna al 2007', actions: RITORNO_1993 },
|
||||
background: 'assets/scenes/smarronata-tendone.png',
|
||||
indoor: true,
|
||||
music: 'assets/audio/mazurka.mp3', // la mazurca di Andrea (Suno, 31 ottobre), per chi è a tavola
|
||||
speakers: { gente: [470, 176] },
|
||||
people: [{ who: 'gente', at: [470, 300], idle: 'stand', talk: ['talk', 'talk2'], blink: 'blink', every: 4.1, flourish: { poses: ['toast', 'laugh'], every: 7, for: 1.6, step: 0.8 } }],
|
||||
walk: [[0, 360], [0, 262], [150, 262], [165, 175], [215, 175], [225, 262], [400, 262], [640, 270], [640, 360]],
|
||||
depth: [[175, 0.5], [360, 1.3]],
|
||||
entry: [320, 340],
|
||||
hotspots: [
|
||||
{
|
||||
id: 'tavolata', name: 'la tavolata', box: [218, 140, 182, 122], at: [320, 290], face: 'up',
|
||||
actions: {
|
||||
look: [{ say: 'Tovaglie verdi di carta, le tovagliette, l\'acqua e il vino. Fra poco qui non ci sarà un posto libero.' }],
|
||||
use: [{ say: 'Mi siedo un attimo ad aspettare la polenta.' }, { say: '...Macché: sono le dieci e mezzo, la polenta arriva a mezzogiorno.' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
// I cartelli dipinti della polenta e del vino gratis, appesi alla tela in fondo (Andrea, 31 ottobre: «erano
|
||||
// carini»): si aprono ingranditi. Ultimi dell'elenco nella loro zona, così non li copre la tavolata.
|
||||
id: 'cartelli_tendone', name: 'i cartelli della polenta e del vino', box: [192, 112, 60, 32], at: [190, 240], face: 'up',
|
||||
art: [{ rect: [196, 122, 28, 17], fill: '#f4efe0' }, { rect: [197, 123, 26, 1], fill: '#2f6b32' }, { rect: [199, 126, 22, 4], fill: '#e0a92a' },
|
||||
{ rect: [204, 132, 12, 4], fill: '#e8b83a' }, { rect: [230, 116, 17, 25], fill: '#f4efe0' }, { rect: [232, 119, 13, 4], fill: '#8a2a1e' },
|
||||
{ rect: [235, 125, 7, 9], fill: '#c98a2e' }, { rect: [236, 127, 5, 5], fill: '#7a1e22' }, { rect: [232, 136, 13, 2], fill: '#8a2a1e' }],
|
||||
actions: {
|
||||
look: [{ closeup: 'cartelli_smarronata' }],
|
||||
take: [{ say: 'Sono degli alpini. E gli alpini, i loro cartelli, se li riportano a casa.' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'bancone_tendone', name: 'il bancone', box: [330, 132, 170, 34], at: [300, 270], face: 'up',
|
||||
actions: { look: [{ say: 'In fondo il bancone, coi piatti in pila e il vino. Da lì escono i vassoi.' }] },
|
||||
},
|
||||
{
|
||||
id: 'tavole_sinistra', name: 'le tavole', box: [0, 140, 160, 112], at: [120, 290], face: 'left',
|
||||
actions: { look: [{ say: 'Altre tavolate, apparecchiate fino in fondo. Gli alpini fanno le cose in grande.' }] },
|
||||
},
|
||||
{
|
||||
id: 'tavole_destra', name: 'le tavole', box: [400, 140, 240, 128], at: [480, 300], face: 'right',
|
||||
actions: { look: [{ say: 'Le sedie di legno, quelle pieghevoli che si chiudono sulle dita.' }] },
|
||||
},
|
||||
{
|
||||
id: 'gente_tendone', name: 'la gente della festa', box: [405, 180, 131, 120], at: [380, 320], face: 'right', default: 'talk',
|
||||
actions: {
|
||||
look: [{ say: 'Sono entrati a vedere se la polenta è pronta. Non lo è.' }],
|
||||
talk: [{ say: 'Siediti con noi, che a mezzogiorno qui non si trova un posto!', who: 'gente', pose: 'talk' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'fuori_tendone', name: 'fuori, alla festa', box: [0, 336, 640, 24], at: [320, 354], default: 'walk',
|
||||
actions: { walk: [{ go: 'smarronata_1993', at: [430, 250], face: 'down' }], open: [{ go: 'smarronata_1993', at: [430, 250], face: 'down' }] },
|
||||
},
|
||||
],
|
||||
},
|
||||
barrettino_1997: {
|
||||
name: 'Il Barrettino, 10 luglio 1997',
|
||||
// Ci si arriva solo con la macchina del tempo: niente mappa, niente strade (la porta riporta nel 2007).
|
||||
@@ -4193,7 +4486,6 @@ export const story = {
|
||||
{ say: 'A campana? Alla nostra età?', who: 'taglia', pose: 'laugh' },
|
||||
{ say: 'Va bene: il gesso ce l\'ho in tasca, il sassolino lo scelgo io. Sul vialetto, dalla 1 alla 8, e chi pesta la riga passa la mano.', who: 'taglia', pose: 'explain' },
|
||||
] },
|
||||
{ text: 'Ma quanto sei alto, Taglia?', then: [{ say: 'Abbastanza da vedere i pallini arrivare prima di te.', who: 'taglia', pose: 'laugh' }] },
|
||||
{ text: 'Ci si vede, Taglia.', next: 'end' },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// La versione del gioco: la cambia scripts/bump.sh, insieme a package.json.
|
||||
export const VERSION = '0.1.62';
|
||||
export const VERSION = '0.1.63';
|
||||
|
||||
// Immagini, musiche e voci con ?v=<versione>: a ogni versione l'indirizzo cambia e il browser le riscarica,
|
||||
// mentre fra una versione e l'altra le tiene in cache a lungo (nginx.conf).
|
||||
|
||||
@@ -210,6 +210,8 @@ body.full #sound { position: fixed; z-index: 13; top: max(8px, env(safe-area-ins
|
||||
.overlay p { margin: 0; max-width: 34em; font-size: clamp(9.36px, 1.44vw, 14.4px); }
|
||||
.subtitle { color: var(--dim); }
|
||||
.dedication { margin-top: .8em !important; font-style: italic; color: var(--accent); }
|
||||
/* La seconda dedica, allo zio Mario (Andrea, 31 ottobre): sotto quella del Lele, più piccola. */
|
||||
.dedication-small { margin-top: .3em !important; font-size: .78em; opacity: .85; }
|
||||
.buttons { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: .4em; }
|
||||
.buttons button { font: inherit; font-weight: bold; font-size: clamp(10.8px, 1.58vw, 15.84px); padding: .45em 1.2em; border-radius: 6px; cursor: pointer;
|
||||
color: var(--bg); background: var(--accent); border: 0; }
|
||||
@@ -269,6 +271,7 @@ body.full #sound { position: fixed; z-index: 13; top: max(8px, env(safe-area-ins
|
||||
/* I crediti crescono con chi contribuisce: scorre solo l'elenco, dedica e Chiudi restano sempre in vista. */
|
||||
#credits { justify-content: flex-start; overflow: hidden; padding-top: 4%; background: rgba(15, 10, 20, .96); }
|
||||
#credits .credits-dedication { margin: .2em 0 .5em !important; font-size: clamp(10px, 1.6vw, 17px); }
|
||||
#credits .dedication-small { margin: -.3em 0 .6em !important; font-size: clamp(8px, 1.15vw, 13px); }
|
||||
/* Due colonne: il ruolo a destra della sua colonna, il nome a sinistra della sua, allineati sulla riga. */
|
||||
#credits dl { flex: 1 1 auto; min-height: 0; overflow-y: auto; align-content: start; padding-right: .4em; margin: .2em 0 0; display: grid; grid-template-columns: 1fr 1fr; column-gap: 1em; row-gap: .45em; align-items: baseline; width: min(100%, 44em); scrollbar-width: thin; }
|
||||
#credits dt { text-align: right; color: var(--dim); font-size: clamp(7.2px, 1.01vw, 10.08px); letter-spacing: .12em; text-transform: uppercase; }
|
||||
|
||||
@@ -398,8 +398,9 @@ try {
|
||||
assert.equal(await book.evaluate(() => game.closeup.step), 'turn', 'un altro gira la pagina');
|
||||
await book.waitForFunction(() => game.closeup?.step === 'end');
|
||||
assert.equal(await book.evaluate(() => game.speech), null, '«FINE» non lo dice nessuno');
|
||||
await book.screenshot({ path: `${OUT}/03b-libro-fine.png` });
|
||||
// Prima la battuta, poi la schermata: con swiftshader una schermata può durare più della battuta.
|
||||
await book.waitForFunction(() => game.speech?.text === 'Mi ricordavo un finale diverso.', null, { timeout: 5000 });
|
||||
await book.screenshot({ path: `${OUT}/03b-libro-fine.png` });
|
||||
assert.deepEqual(await book.evaluate(() => [game.state.x, game.state.y]), where, 'i clic sul libro non muovono Andrea');
|
||||
await book.keyboard.press('Space');
|
||||
await book.keyboard.press('Escape');
|
||||
|
||||
@@ -154,3 +154,20 @@ test('le musiche e gli sfondi della festa esistono', () => {
|
||||
assert.ok(files.size >= 10);
|
||||
for (const f of files) assert.ok(existsSync(new URL('../' + f, import.meta.url)), `manca ${f}`);
|
||||
});
|
||||
|
||||
test('alla festa la folla dipinta salta a tempo: l\'effetto crowd in tutte e cinque le scene, dietro piano e davanti forte', async () => {
|
||||
const { EFFECTS } = await import('../src/engine/render.js');
|
||||
assert.equal(typeof EFFECTS.crowd, 'function');
|
||||
for (const id of ZONE.scenes) {
|
||||
const crowds = (story.scenes[id].effects ?? []).filter(e => e.type === 'crowd');
|
||||
assert.equal(crowds.length, 2, `${id}: due fasce di folla`);
|
||||
assert.ok(crowds.every(e => e.phase === 'ingorgo' && e.bpm > 0 && e.area[1] + e.area[3] <= 360), id);
|
||||
assert.ok(crowds[0].amount < crowds[1].amount, `${id}: quella davanti salta di più`);
|
||||
}
|
||||
// Il salto: ogni striscia va su e giù nel tempo; senza sfondo l'effetto non disegna niente.
|
||||
const calls = [];
|
||||
const ctx = { drawImage: (...a) => calls.push(a) };
|
||||
const game = { backdrop: () => 'x.png' };
|
||||
EFFECTS.crowd(ctx, { area: [0, 200, 640, 100], bpm: 120 }, 0, game);
|
||||
assert.equal(calls.length, 0, 'senza sfondo caricato non disegna');
|
||||
});
|
||||
|
||||
@@ -12,7 +12,10 @@ let browser;
|
||||
const errors = [];
|
||||
try {
|
||||
browser = await chromium.launch({ args: ['--autoplay-policy=no-user-gesture-required', '--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader'] });
|
||||
const page = await browser.newPage({ viewport: { width: 1280, height: 860 } });
|
||||
// Sul computer la versione con la sfocatura vera, sul telefono (touch) quella leggera senza filtri.
|
||||
for (const mobile of [false, true]) {
|
||||
const page = await browser.newPage(mobile ? { viewport: { width: 844, height: 390 }, hasTouch: true, isMobile: true } : { viewport: { width: 1280, height: 860 } });
|
||||
const tag = mobile ? 'telefono' : 'computer';
|
||||
page.on('pageerror', e => { errors.push(e.message); console.log('ERR', e.message); });
|
||||
await page.goto(`http://127.0.0.1:${server.port}/`);
|
||||
await page.click('#splash'); await page.click('#new-game'); await page.click('#rione [data-rione="campomigliaio"]'); await page.click('#skip-intro');
|
||||
@@ -21,10 +24,11 @@ try {
|
||||
// Le battute si saltano solo per far correre il tempo fino ai momenti da fotografare.
|
||||
for (const [t, name] of [[0.5, '0-buio'], [2.1, '1-primo-tentativo'], [3.8, '2-secondo'], [5.6, '3-quasi'], [7.2, '4-aperti']]) {
|
||||
await page.waitForFunction(at => { if (game.speech && game.closeup) game.skip(); return !game.closeup || game.closeup.t >= at; }, t, { timeout: 30000, polling: 50 });
|
||||
await page.screenshot({ path: `${out}/${name}.png` });
|
||||
await page.screenshot({ path: `${out}/${tag}-${name}.png` });
|
||||
}
|
||||
await page.waitForFunction(() => !game.closeup && game.state.flags.intro, null, { timeout: 15000 });
|
||||
await page.screenshot({ path: `${out}/5-vecchietti.png` });
|
||||
await page.screenshot({ path: `${out}/${tag}-5-vecchietti.png` });
|
||||
}
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(`ok: schermate in ${out}`);
|
||||
} finally { await browser?.close(); server.kill(); }
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// La Smarronata del 1993 nel browser vero: lo spiazzo sotto il Ponte sulla Sieve, la macchina del tempo, il cruscotto,
|
||||
// la festa sotto il ponte, il tendone e il ritorno al 2007. npm run browser:smarronata — schermate in /tmp/regolo-smarronata.
|
||||
import { chromium } from 'playwright';
|
||||
import { mkdirSync } from 'node:fs';
|
||||
import assert from 'node:assert/strict';
|
||||
import { staticServer } from './helpers.mjs';
|
||||
|
||||
const out = process.env.OUT ?? '/tmp/regolo-smarronata';
|
||||
mkdirSync(out, { recursive: true });
|
||||
const server = await staticServer();
|
||||
let browser;
|
||||
const errors = [];
|
||||
try {
|
||||
browser = await chromium.launch({ args: ['--autoplay-policy=no-user-gesture-required', '--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader'] });
|
||||
const page = await browser.newPage({ viewport: { width: 1280, height: 860 } });
|
||||
page.on('pageerror', e => { errors.push(e.message); console.log('ERR', e.message); });
|
||||
await page.goto(`http://127.0.0.1:${server.port}/`);
|
||||
await page.click('#splash'); await page.click('#new-game'); await page.click('#rione [data-rione="campomigliaio"]'); await page.click('#skip-intro');
|
||||
const settle = () => page.evaluate(async () => { const { settle } = await import('/tests/helpers.mjs'); settle(game); });
|
||||
// Si salta tutto quello che si può: viaggio, corse, battute (il tempo nel gioco va veloce).
|
||||
const run = () => page.evaluate(async () => {
|
||||
const { settle } = await import('/tests/helpers.mjs');
|
||||
for (let i = 0; i < 3000 && (game.closeup || game.speech || game.queue.length || game.walking); i++) { if (game.speech) game.skip(); else game.update(0.1); }
|
||||
settle(game);
|
||||
});
|
||||
await run();
|
||||
await page.evaluate(() => { game.go('ponte_sieve', [250, 320]); });
|
||||
await run();
|
||||
// Il cartello sul lampione si apre ingrandito; un tocco, e arriva la macchina.
|
||||
await page.evaluate(() => game.act('look', 'cartello_smarronata'));
|
||||
await page.waitForFunction(() => game.closeup?.id === 'manifesto_smarronata' && game.closeup.t > 0.6, null, { timeout: 15000 });
|
||||
await page.screenshot({ path: `${out}/0-cartello.png` });
|
||||
await page.evaluate(() => game.closeupTap());
|
||||
await run();
|
||||
assert.ok(await page.evaluate(() => game.state.flags.macchina_ponte), 'la macchina compare');
|
||||
await page.waitForTimeout(800);
|
||||
await page.screenshot({ path: `${out}/1-ponte-macchina.png` });
|
||||
await page.evaluate(() => game.act('use', 'macchina_ponte'));
|
||||
await page.waitForFunction(() => game.closeup?.id === 'viaggio_1993', null, { timeout: 15000 });
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: `${out}/2-cruscotto.png` });
|
||||
await run();
|
||||
assert.equal(await page.evaluate(() => game.state.scene), 'smarronata_1993');
|
||||
await page.waitForTimeout(1200);
|
||||
await page.screenshot({ path: `${out}/3-smarronata.png` });
|
||||
await page.waitForFunction(() => [...music.tracks.keys()].some(k => k.includes('liscio')), null, { timeout: 8000 });
|
||||
await page.evaluate(() => game.act('walk', 'tendone'));
|
||||
await run();
|
||||
assert.equal(await page.evaluate(() => game.state.scene), 'smarronata_tendone');
|
||||
await page.waitForTimeout(1200);
|
||||
await page.screenshot({ path: `${out}/4-tendone.png` });
|
||||
await page.waitForFunction(() => music.current?.src.includes('mazurka'), null, { timeout: 8000 });
|
||||
// I cartelli della polenta e del vino gratis, ingranditi.
|
||||
await page.evaluate(() => game.act('look', 'cartelli_tendone'));
|
||||
await page.waitForFunction(() => game.closeup?.id === 'cartelli_smarronata' && game.closeup.t > 0.6, null, { timeout: 15000 });
|
||||
await page.screenshot({ path: `${out}/5-cartelli.png` });
|
||||
await page.evaluate(() => game.closeupTap());
|
||||
await run();
|
||||
await page.evaluate(() => game.goBack());
|
||||
await run();
|
||||
assert.equal(await page.evaluate(() => game.state.scene), 'ponte_sieve');
|
||||
assert.ok(!await page.evaluate(() => game.state.flags.macchina_ponte), 'tornati, la macchina sparisce');
|
||||
// Nei Ringraziamenti, sotto la dedica al Lele, quella allo zio Mario.
|
||||
await page.evaluate(() => document.querySelector('.open-credits').click());
|
||||
await page.waitForSelector('#credits:not([hidden])');
|
||||
assert.match(await page.textContent('#credits'), /zio Mario/);
|
||||
await page.screenshot({ path: `${out}/6-crediti.png` });
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(`ok: schermate in ${out}`);
|
||||
} finally { await browser?.close(); server.kill(); }
|
||||
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import { backgroundOrder } from '../src/engine/render.js';
|
||||
import { story } from '../src/story/story.js';
|
||||
import { solution } from '../src/story/solution.js';
|
||||
import { Game, VERBS, checkSave, introText, shuffledCredits, matchPlace, reelPictures } from '../src/engine/game.js';
|
||||
import { Game, VERBS, checkSave, introText, shuffledCredits, matchPlace, reelPictures, POSTER_READY } from '../src/engine/game.js';
|
||||
import { inside } from '../src/engine/geometry.js';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { settle, exploreTorch } from './helpers.mjs';
|
||||
@@ -350,7 +350,8 @@ test('le strade vanno e tornano: niente sensi unici, e ogni posto si raggiunge d
|
||||
const text = JSON.stringify(story);
|
||||
assert.ok(text.includes(`"go":"${id}"`), `${id}: nessun viaggio ci porta`);
|
||||
const back = JSON.stringify(sc.hotspots).match(/"go":"([a-z_0-9]+)"/g)?.map(m => m.slice(6, -1)) ?? [];
|
||||
assert.ok(back.some(b => seen.has(b)), `${id}: non si torna indietro`);
|
||||
// Si torna in una scena vera, o in un'altra del viaggio (il tendone della Smarronata riporta alla festa).
|
||||
assert.ok(back.some(b => seen.has(b) || story.scenes[b]?.viaggio), `${id}: non si torna indietro`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -691,3 +692,43 @@ test('i file che il Docker copia sono leggibili da tutti (nginx gira con un altr
|
||||
dirs.forEach(walk);
|
||||
assert.deepEqual(closed, [], 'file non leggibili da nginx (chmod 644)');
|
||||
});
|
||||
|
||||
test('la Smarronata del 1993: lo spiazzo sotto il ponte fa comparire la macchina, il viaggio, la festa, il tendone e il ritorno', async () => {
|
||||
const g = new Game(story);
|
||||
settle(g); g.go('ponte_sieve', [250, 320]); settle(g);
|
||||
assert.ok(!g.hotspot('macchina_ponte'), 'prima del ricordo la macchina non c\'è');
|
||||
// Il vecchio cartello sul lampione si clicca (davanti alla Sieve, che gli sta dietro): si apre ingrandito, e
|
||||
// toccandolo arriva la macchina del tempo.
|
||||
const [bx, by, bw, bh] = g.hotspot('cartello_smarronata').box;
|
||||
assert.equal(g.hotspotAt([bx + bw / 2, by + bh / 2])?.id, 'cartello_smarronata');
|
||||
g.act('look', 'cartello_smarronata'); settle(g);
|
||||
assert.equal(g.closeup?.id, 'manifesto_smarronata');
|
||||
g.update(POSTER_READY); assert.ok(g.closeupTap()); settle(g);
|
||||
assert.ok(g.state.flags.macchina_ponte && g.hotspot('macchina_ponte'));
|
||||
g.act('use', 'macchina_ponte'); settle(g);
|
||||
assert.equal(g.closeup?.id, 'viaggio_1993');
|
||||
// Il cruscotto, poi la partenza vista da fuori: due primi piani di fila.
|
||||
for (let i = 0; i < 4000 && (g.closeup || g.queue.length || g.speech); i++) { g.skip(); g.update(0.05); }
|
||||
settle(g);
|
||||
assert.equal(g.state.scene, 'smarronata_1993');
|
||||
// La musica: il liscio fuori (più forte vicino alle coppie), la mazurca nel tendone.
|
||||
const { trackFor } = await import('../src/engine/music.js');
|
||||
const fuori = trackFor(story, { screen: 'game', scene: 'smarronata_1993', at: [430, 300], ok: () => true });
|
||||
assert.equal(fuori[0].src, 'assets/audio/liscio.mp3'); assert.equal(fuori[0].gain, 1);
|
||||
assert.equal(trackFor(story, { screen: 'game', scene: 'smarronata_tendone' }), 'assets/audio/mazurka.mp3');
|
||||
assert.ok(!g.travel('piazza'), 'dal 1993 la mappa non porta via: si torna con la macchina');
|
||||
g.act('walk', 'tendone'); settle(g);
|
||||
assert.equal(g.state.scene, 'smarronata_tendone');
|
||||
// I cartelli dipinti della polenta e del vino gratis, sulla tela in fondo: si aprono ingranditi.
|
||||
const [cx, cy, cw, ch] = g.hotspot('cartelli_tendone').box;
|
||||
assert.equal(g.hotspotAt([cx + cw / 2, cy + ch / 2])?.id, 'cartelli_tendone');
|
||||
g.act('look', 'cartelli_tendone'); settle(g);
|
||||
assert.equal(g.closeup?.id, 'cartelli_smarronata');
|
||||
g.update(POSTER_READY); assert.ok(g.closeupTap()); settle(g);
|
||||
g.act('walk', 'fuori_tendone'); settle(g);
|
||||
assert.equal(g.state.scene, 'smarronata_1993');
|
||||
assert.ok(g.goBack()); for (let i = 0; i < 4000 && (g.closeup || g.queue.length || g.speech); i++) { g.skip(); g.update(0.05); }
|
||||
settle(g);
|
||||
assert.equal(g.state.scene, 'ponte_sieve');
|
||||
assert.ok(!g.state.flags.macchina_ponte, 'tornati nel 2007 la macchina sparisce');
|
||||
});
|
||||
|
||||