mercoledì 29 luglio 2015

Il gioco del 15

Il gioco del 15 è quel giochino composto da 15 tessere che bisogna rimettere in ordine, facendone scorrere solo una alla volta, sfruttando la posizione vuota che si viene a creare.
Farlo in livecode è veramente facile e veloce, vediamo come.
Create uno stack con 16 pulsanti:
Numerate i pulsanti e ordinatele in modo che siano equidistanti. Vi consiglio di selezionarle in righe e colonne e usare i pulsanti di allineamento e distribuzione del property inspector.
Fatto ciò nel codice del pulsante 16 mettete il seguente codice:

on mouseUp
   lock screen   
   put the loc of me into locme
   put the loc of button "16" into loc16
   if distanza(locme,loc16) < 97 then
      set the loc of me to loc16
      set the loc of button "16" to locme
   end if   
   unlock screen
   controllaVittoria
end mouseUp

function distanza aa,bb
   put ((item 1 of aa) - (item 1 of bb) )^2 into xx
   put ((item 2 of aa) - (item 2 of bb) )^2 into yy
   return sqrt(xx + yy)
end distanza

Come vedete il codice controlla se il pulsante premuto è sufficientemente vicino al pulsante 16, in tal caso lo scambia di posto col pulsante 16. In pratica fa un controllo se si trova accanto al pulsante 16 applicando la formula della distanza di geometria analitica √(ΔX2 + ΔY2) applicata ai baricentri (proprietà loc). Chiaramente io ho impostato 97 pixel, voi dovrete controllare quale valore rappresenta l'adiacenza dei pulsanti rispetto a quanto grandi li avete fatti.
Ora rendete invisibile il pulsante 16:
Impostate come behaviour di tutti i pulsanti quello del pulsante 16 e metà del gioco è già completo.
Se provate a premere su un pulsante esso si sposterà solo se è vicino alla casella vuota.
Ora mettete nella card il seguente codice:

on openCard
   mescola
end openCard

on controllaVittoria
   put the soluzione of me into ordine
   repeat with i=1 to 16
      put (the loc of button i ) & cr after temp
   end repeat
   if ordine = temp then
      answer "Hai vinto!"
   end if
end controllaVittoria

on impostaVittoria
   repeat with i=1 to 16
      put (the loc of button i ) & cr after temp
   end repeat
   set the soluzione of me to temp
end impostaVittoria

on mescola
   put "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16" into temp
   put the soluzione of me into posizioni
   repeat with i=1 to 16
      put the number of items of temp into nn      
      put random(nn) into elemento
      put item elemento of temp & CR after ordineBottoni
      delete item elemento of temp #così leva anche la virgola
   end repeat   
   repeat for each line tLine in ordineBottoni
      set the loc of button tLine to the first line of posizioni
      delete the first line of posizioni
   end repeat
end mescola

lanciate il comando impostaVittoria e avete finito!
Lanciando il messaggio impostaVittoria salvate le posizioni dei pulsanti vincenti, quindi il messaggio controllaVittoria controlla se tutte le posizioni sono quelle giuste.
Il messaggio mescola serve per mescolare le carte.
Potete anche aggiungere un pulsate per poter rimettere tutti i pulsanti in ordine con il seguente codice:

on mouseUp
   put the soluzione of this card into temp
   repeat with i=1 to 16
      set the loc of button i to line i of temp
   end repeat
end mouseUp

Così:
Ora tocca a voi divertirvi ad aggiungere un timer, il numero di mosse utilizzato per vincere e qualche elemento grafico!
Se avete dubbi chiedete pure nei commenti.
NOTA: non tutte le combinazioni casuali generano un gioco del 15 risolvibile. Per l'esattezza solo la metà di tutte le possibili configurazioni (16! / 2), in un prossimo post spiegherò come capire se una combinazione è risolvibile.

martedì 28 luglio 2015

Cercare in modo più scenografico

Livecode vi permette di cercare nei vari campi di testo (field) utilizzando il comando find:

find "macchina"

se viene trovata la parola, viene posto un rettangolo attorno a quella parola (o frase).
ogni volta che contiamo a usare find, la ricerca prosegue dal punto in cui eravamo arrivati. Possiamo anche indicare di limitare la ricerca ad un unico campo field.
Se preferiamo fare una ricerca più carina possiamo sfruttare la proprietà foundchunk che contiene tutti i dati del testo appena trovato con find. Ci basterà sapere la proprietà rect del foundchunk per disegnarli attorno ciò che preferiamo.
L'esempio seguente usa find per trovare la parola, memorizza quante volte è stato già chiamato find, poi usa find empty per cancellare il rettangolo attorno alla parola cercata, e disegna ciò che preferiamo attorno alla a parola trovata. Ecco il codice commentato:

on mouseUp
   lock screen #blocchiamo lo schermo
   #controlliamo che non ci sia già il cerchio verde
   if exists(graphic "cerca") then
      delete graphic "cerca"
   end if
   #vediamo se abbiamo già cercato la parola e quante volte
   put the numfind of me into n
   if n is empty then
      put 1 into n
   end if
   put the text of field "paroladacercare" into parola
   put the oldparola of me into oldpar
   if oldpar is not parola then
      put 1 into n
   end if
   #cerchiamo la parola o frase
   repeat for n times
      find parola in field "testo"
   end repeat   
   #salviamo la parola cercata
   set the oldparola of me to parola
   #vediamo cosa abbiamo trovato ed evidenziamo con un rettangolo arrotondato verde
   if the foundchunk is not empty then
      put the foundchunk into temp
      find empty      
      create graphic "cerca"
      set the style of graphic "cerca" to "roundrect"
      set the linesize of graphic "cerca" to 3
      set the foregroundcolor of graphic "cerca" to "green"
      put the formattedrect of temp into tempRect
      #facciamo un po' più grosso del rettangolo della parola
      add -4 to item 1 of tempRect
      add -4 to item 2 of tempRect
      add 4 to item 3 of tempRect
      add 4 to item 4 of tempRect
      set the rect of graphic "cerca" to tempRect
      add 1 to n
      set the numfind of me to n
   else
      #se non troviamo nulla azzeriamo il contatore della ricerca
      set the numfind of me to empty
   end if   
   #sblocchiamo la grafica del programma
   unlock screen
end mouseUp


ed ecco il risultato:

venerdì 24 luglio 2015

Gioco Xplorer

Oggi presentiamo un gioco prodotto con livecode e disponibile per windows, linux e Mac: Xplorer.
Come altri è presente sul sito: http://www.bakno.com/


In questo gioco dovrete navigare per il modo alla ricerca di oggetti misteriosi.

Veramente un ottimo esempio di programmazione in Livecode.

giovedì 23 luglio 2015

Aggiungere ad un file

Aggiungere dati ad un file è un'operazione comune nei diari (log) di servizio. Tenere un diario di cosa si fa o viene eseguito è importantissimo per capire cosa è andato storto o cosa è stato eseguito e cosa no.
La sintassi per aggiungere dati ad un file è semplicissima, se vogliamo aggiungerlo alla fine del file basta scrivere:


put "ore 9:38, salpati dal porto" after URL "file:diariodiBordo.txt"


se invece vogliamo mettere delle informazioni prima basta usare la parola before invece di after:


put "Diario di bordo della nave Tritone" before URL "file:diariodiBordo.txt"


Questa tecnica potete utilizzarla per tantissime occasioni.

mercoledì 22 luglio 2015

Rilasciata 7.1.0 dp1

E' stata rilasciata la versione 7.0.1dp1 di livecode, tra le novità abbiamo:
  • supporto integrato per i socket su Android e iOS
  • funzione ceil()ceiling(), per arrotondare al numero intero più in alto
  • funzione floor(), per arrotondare al numero intero più in basso
  • mobileGetLaunchData per capire il manifest di intent con cui è stata avviata l'app, in pratica si leggono i paremetri inviati all'app
Come al solito si scarica da qui: http://downloads.livecode.com/livecode/

martedì 21 luglio 2015

Non utilizzare le variabili globali

Le variabili globali (global) sono una tentazione troppo forte per chi viene da altri linguaggi di programmazione, ma sono anche un elemento di cattiva programmazione in Livecode.
Le variabili globali sono variabili visibili da tutti gli elementi del programma, per dichiararle basta:


global miavariabile

ma sono un male, e vediamo il motivo. Di solito si usano per avere un valore visibile da più funzioni, messaggi e altri elementi del programma.
Poichè sono accessibili da ogni parte del programma, è praticamente impossibile capire quale parte del programma stia modificandone il valore, anche un semplice errore di battitura in qualche punto del programma potrebbe creare enormi problemi.
Le variabili globali hanno anche problemi di sicurezza, sempre perchè è difficile anche sapere dove e se ci sono, se più programmatori mettono mano al programma può essere complicato risalire a tutte le varibili globali.
Chi usa variabili globali tende a creare un programma monolitico, invece un buon programma dovrebbe essere modulare, in modo da poter aggiungere e togliere funzionalità all'occorrenza.
Per ultimo non dimentichiamo che non potendo recuperare facilmente la lista delle variabili globali mentre si scrive il codice, si rischia di creare situazioni pericoloso, dove lo stesso nome per diversi tipi di variabili senza accorgersene. Vi ricordo che le variabili normali dentro un messaggio, sono eliminate alla fine del messaggio.
In un linguaggio come livecode ogni variabile dovrebbe essere contenuto in un controllo.
Per fare questo basta utilizzare le custom property:


set miavariabile of button 1 to "Luigi"

In questo modo è sempre possibile recuperare il valore della variabile utilizzando o il property inspector, o message box.



Possiamo anche cambiarla facilmente, avere la lista delle variabili di ogni controllo. Anche le custom properties sono visibili da tutti i punti del programma, ma dovendo scrivere tutto il percorso, si evitano confusioni di variabili per errori di battitura, il programma è realmente modulare, e eliminando un controllo, si vedono immediatamente gli effetti se quelle variabili erano legate anche a qualche altra parte di del programma, aumentando notevolmente la sicurezza.

venerdì 17 luglio 2015

HTML 5

Se vi ricordate, l'anno scorso livecode aveva promosso una raccolta fondi per aggiungere l'esportazione in web HTML 5 dei nostri programmi. Grazie a questa funzioni i nostri programmi potevano funzionare anche mettendoli su una pagina web.
Oggi sono stati rilasciati due esempi di cosa si può ottenere.
Il primo esempio lo trovate a questa pagina: http://livecode.com/products/livecode-platform/html5/demos/calculator/
si tratta di una calcolatrice:
mentre a quest'altra pagine potete vedere come funziona con le animazioni: http://livecode.com/products/livecode-platform/html5/demos/bouncing-balls/
Lo sviluppo dell'esportazione in HTML procede, speriamo di vedere qualcosa di più prima della fine dell'estate.

mercoledì 15 luglio 2015

Mettere un programma nel systray

L'area delle icone vicino all'orologio è chiamata systray, è può essere comoda per mettere dei programmi che debbono essere sempre presenti o inviare delle notifiche sul desktop.
Per livecode esiste questa estensione, sia gratuita che a pagamento ($19) per poter mettere questo effetto ai nostri programmi. Il programma è scaricabile dal sito: http://www.sonsothunder.com/products/ststray/ststray.htm
La versione gratuita (demo) è completa, ma manda periodicamente un messaggio di comprare la versione a pagamento; una volta comprata la licenza potete fare qualsiasi numero di programmi diversi senza doverla pagare nuovamente.
Questo è un prodotto dei programmatori Sons of thunder:

Se volete qualche funzione aggiuntiva, basta scrivere a ststray@sonsothunder.com

martedì 14 luglio 2015

Creare un mappamondo rotante partendo da un'immagine piatta

Oggi vedremo come realizzare un'animazione come questa:
Partendo da partendo da un'immagine piatta come questa:
Per fare prima, faremo anche le modifiche alle immagini attraverso livecode.
Prima di tutto ci servono due immagini uguali, poi dobbiamo affiancarle, per affiancarle basta usare il seguente codice:

on mouseUp
   set the topleft of image 1 to the topright of image 2
end mouseUp

e otterremo questo:
Adesso raggruppatele, impostate il bordo del gruppo a zero. Ora copiate il gruppo in modo da avere sue immagini doppie:

Fatto ciò dobbiamo rendere una delle due immagini doppie più scura. Per far questo basta andare sulla proprietà  graphic effect->color overlay:
Chiaramente l'immagine più scura farà da retro e perciò va specchiata, per rigirarla basta andare su Object -> Flip -> Horizontaly:
Ora dobbiamo fare in modo che di veda solo una porzione circolare di queste due immagini, per questo fate un cerchio 200x200, impostate lo sfondo di colore nero (backgroundcolor), poi impostate la proprietà blending a blendDstIn e otterrete questo:
Ora per posizionare tutto correttamente basta usare il seguente codice:


set the loc of group 1 to the loc of graphic 1
set the loc of group 2 to the loc of graphic 1   
move group 1 relative 240,0
   


Prima di andare avanti chiamiamo i due gruppi di immagini fronte e retro, e ogni gruppo al suo interno ha le due immagini che chiameremo rispettivamente sinistra (quella più a sinistra) e destra (quella più a destra). In questo modo il codice seguente da mettere in un pulsante per animare il tutto sarà molto semplice da capire:

on mouseUp    
    if the label of me is not "Ruota!" then
       set the label of me to "Ruota!"
    else
       set the label of me to "Ferma!"
       runAnimation
       end if
end mouseUp

on runAnimation   
   #controlliamo se dobbiamo continuare l'animazione
   if the label of me is "Ruota!" then
      exit to top
   end if   
   #dobbiamo muovere due cose contemporaneamente,
   #conviene prima fermare tutto e poi riavviare:
   lock screen
   #impostiamo la velocita':
   put 3 into animRate
   #mappa sul fronte
   put the loc of group "fronte" into temp
   subtract animRate from item 1 of temp #scorre verso sinistra
   set the loc of group "fronte" to temp
   if the left of image "destra" of group "fronte" < the left of graphic 1 then
      set the left of group "fronte" to the left of graphic 1
   end if
    #mappa sul retro
   put the loc of group "retro" into temp
   add animRate to item 1 of temp #scorre verso destra
   set the loc of group "retro" to temp
   if the left of image "sinistra" of group "retro" > the left of graphic 1 then      
      set the loc of group "retro" to (the left of graphic 1, item 2 of temp)
   end if   
   send "runAnimation" to me in 50 millisecs
   unlock screen
end runAnimation

Ora se vedete l'animazione in funzione capite perchè abbiamo sdoppiato le immagini, serve a dare un effetto di uniformità.
Ci manca solo da sistemare la grafica, per non fare vedere la parte fuori dal cerchio basta aggiungere due rettangoli 500x200 da mettere ai lati del cerchio:
Ora fate tutto un gruppo con tutti gli elementi (2 rettangoli, due gruppi e il cerchio), mettete il bordo dei due rettangoli a zero, il colore dei due rettangoli vuoto (empty, si ottiene premendo clear nel property inspector del colore). Ora al questo gruppone date la proprietà di blending blendSrcOver e per magia ecco il risultato:
Ora potete sbizzarrirvi con l'aggiunta del mare, di zone più luminose e semitrasparenti, tutto da mettere sopra o sotto la nostra immagine.
Aggiungendo un cerchio con un gradiente radiale come questo:
Si ottiene questo effetto di sfericità:
Se poi vogliamo dare un tocco di luminosità possiamo applicare un gradiente lineare per ad un altro cerchio:
Per ottenere questo effetto:
Potete scaricare il mio risultato da qui.
Ora che abbiamo finito, quali vantaggi porta crearsi l'animazione del mondo che gira, invece che scaricarsi una GIF animata già pronta da internet?
La risposta è che possiamo modificarla al volo, possiamo inserire dei pallini che indichino dei punti particolari sulla mappa, possiamo passare da notte a giorno, renderla interattiva e molto altro; tutto questo solo modificando il gruppo fronte.
Lascio a voi nei commenti altre soluzioni o idee da applicare al mondo che gira.

venerdì 10 luglio 2015

Mappe interattive

L'università del Massachusetts ha sviluppato un software con livecode per fare mappe interattive. Queste mappe, cliccando sulle immagini vi tirano fuori tutte le informazioni sul punto cliccato dell'immagine:
Le informazioni possono essere foto, tabelle, filmati, ecc. Potete scaricare il software dal sito http://ddm.geo.umass.edu/ 
Sempre sul sito potete scaricare le mappe già pronte della Luna, del cratere Gale di Marte, i vulcani dell'Arizona, della Patagonia, di varie città e altri posti interessanti.
Queste mappe hanno a disposizione anche il sorgente in livecode e sono disponibili gli eseguibili per tutti i pc (Mac, Win e Linux), l'unico accorgimento su Win è di avere installato QuickTime.

giovedì 9 luglio 2015

Far vibrare un cellulare



Se stiamo facendo un programma per un cellulare, potrebbe farci comodo farlo vibrare invece di farlo suonare. Il comando per far vibrare un cellulare è mobileVibrate, ad esempio:

mobilevibrate 5

Il numero dopo il comando indica quante volte volete far vibrare il cellulare.

martedì 7 luglio 2015

Fare telefonate

Per fare telefonate su Android e iOS il codice da poter utilizzare è semplicemente il seguente:

launch url "tel:+39321321321"

Ricordatevi di mettere il prefisso (+39 per l'Italia).

lunedì 6 luglio 2015

Data tree (grafici espandibili ad albero)

Un tipo di menù molto comodo è quello di tipo espandibile ad albero, potreste farlo con il datagrid in modalità form, ma esiste una versione già pronta che è scaricabile da qui: http://tapirsoft.on-rev.com/?ddownload=2332
Questo nuovo controllo si chiama rTree, una volta avviato si presenta come una finestra con un controllo da trascinare nel vostro programma:
Trascinando il rettangolo bianco nel vostro stack otterrete un controllo molto speciale, potrete avere a disposizione molti temi grafici già pronti:
Stile Mac
Stile Mini
Stile Windows
Stile con linee attivate

Potete creare l'albero sia da un array che da un file di testo oppure inviando i comandi, per sperimentare vi basta cliccare con il destro sul controllo in modalità Run.

Ad esempio, una volta chiamato "tree" il nome del gruppo del controllo,  se volete aggiungere un nodo all'albero principale potete utilizzare il seguente codice.


send "new_node as child 1 of node id 1" to group "tree"
send "scan_node_ID" to group "Tree"
send "render_tree" to group "Tree"

venerdì 3 luglio 2015

App che avviano altre app

Se un'app su un dispositivo mobile (Android o iOS) deve comunicare con un'altra app sullo stesso dispositivo, un metodo semplice e veloce è quello di utilizzare uno schema URL personalizzato.
Gli schemi URL si impostano nelle schermata standalone application settings alla voce custom url scheme:
come vedete dall'esempio, ho inventato la parola appdimax per avere un modo univoco per richiamare l'app. La parola appdimax  in questo caso sarà il nostro URL personalizzato.
Per avviare la nostra app con questo URL personalizzato basterà invocarlo da un'altra app, il codice per farlo è semplicemente:

launch url "appdimax://"

Se noi volessimo anche inviare delle informazioni all'app potremmo metterle dopo; ad esempio se vogliamo inviare il messaggio "Mario è simpatico", potremmo scrivere:

put urlencode("Mario è simpatico") into messaggio
launch url ("appdimax://" & messaggio)

a questo punto dobbiamo solo decidere cosa succede quando l'altra app viene avviata.
Il messaggio URLwakeup si attiva proprio quando l'app si attiva attraverso un URL personalizzato. Ad esempio il codice seguente vi dice cosa ha ricevuto l'app:

on urlWakeUp pURL
   answer "Sono stato attivato col seguente messaggio: " & pURL
end urlWakeUp

Nell'esempio precedente avevamo mandato un messaggio, ma formattandolo correttamente per l'invio come URL, infatti otteniamo:

Sono stato attivato col seguente messaggio: appdimax://Mario+%E8+simpatico

se vogliamo recuperare il messaggio originale, dobbiamo fare il passaggio inverso:

on urlWakeUp pURL
   #leviamo la parte appdimax://
   put char 12 to -1 of pURL into pURL
   #codifichiamo secondo la codifica normale
   put urldecode(pURL) into pURL
   answer "Sono stato attivato col seguente messaggio: " & pURL
end urlWakeUp

In questo modo otteniamo:

Sono stato attivato col seguente messaggio: Mario è simpatico

Altri sistemi per recuperare l'URL è utilizzare la funzione mobileGetLaunchURL(), ad esempio:

put mobileGetLaunchUrl() into tURL