In alcuni progetti possono essere utili delle selezioni più dettagliate di quanto visto nella lezione precedente.
Per esempio, supponiamo di voler costruire un menu 3D per la navigazione di un sito web, oppure di voler mostrare determinate immagini sulla faccia di un oggetto in base alla selezione.
Le facce di un oggetto 3D possono avviare lo stesso tipo di evento dell'oggetto stesso, ma, invece, di associare i listener all'oggetto andiamo ad associarli alle singole facce; il modo più semplice per fare questo è inserire i riferimenti alle facce in un array e poi aggiungere i listener tramite un ciclo for.
Come per l'esempio degli oggetti, mostriamo una diversa skin a seconda dello stato della faccia.
Andiamo a modificare la funzione createScene()
in questo modo:
Listato 73. Inserisce le facce in un array e imposta gli eventi del mouse
// Ricava le facce e le mette in un array
faces = cube.getFaces();
faces = faces.concat( pyramid.getFaces() );
// Il ciclo abilita gli eventi, associa i listener e ricava le skin originali
for ( var i = 0; i < faces.length; i++ ){
var face = faces[i];
// Impostiamo gli eventi
face.enableEvents(true);
face.addEventListener( ObjectEvent.onRollOverEVENT, this, setRollOverSkin );
face.addEventListener( ObjectEvent.onRollOutEVENT, this, setRollOutSkin );
// Aggiungiamo la skin della faccia
skins[face.getId()] = face.getSkin();
}
Come vediamo nel codice, per prima cosa, inseriamo tutte le facce in un array, sfruttando il comando getFaces()
, quindi grazie al metodo concat
degli array andiamo a unire le facce del cubo (6) e quelle della piramide (5) in un unico array.
Il numero di facce varia in base al metodo di creazione usato per l'oggetto, come abbiamo visto nelle parti precedenti.
Ora abbiamo la lista completa delle facce e con il ciclo for, associamo dei comandi a ognuna di esse; nel nostro caso inseriamo i listener, abilitiamo gli eventi e memorizziamo la skin originale di ogni singola faccia.
Le funzioni relative agli eventi saranno diverse dalle precedenti, così:
Listato 74. Imposta le azioni da eseguire in base agli eventi del mouse
// Azioni da eseguire al MouseOver
function setRollOverSkin( e:ObjectEvent ){
var obj:TriFace3D = e.getTarget();
var id = obj.getId();
faceText.text = id;
obj.setSkin( markSkin );
camera.rotateX(0);
}
// Azioni da eseguire al MouseOut
function setRollOutSkin( e:ObjectEvent ){
var obj:TriFace3D = e.getTarget();
var id = obj.getId();
obj.setSkin( skins[id] );
}
Ogni faccia in Sandy ha un suo ID univoco che la identifica.
Notiamo come il target degli eventi ora sia un oggetto TriFace3D
(e non Object3D
).
Ecco il risultato
Selezione di una singola faccia
Una variante interessante potrebbe consistere nel rendere le facce selezionabili tramite click del mouse:
Selezione di una singola faccia tramite click
Il metodo della selezione può dare qualche problema al mouse over: in particolare, mentre nel caso di oggetti statici questa soluzione funziona senza problemi, in caso di oggetti in movimento la situazione è decisamente peggiore, poichè l'oggetto si sposta sotto il mouse, cambiando di fatto continuamente la selezione; inoltre possiamo vedere, nel primo esempio, che se clicchiamo sulla faccia, spostiamo il mouse fuori da essa e rilasciamo il pulsante del mouse, la faccia rimane selezionata, perchè non viene intercettato l'evento onRollOutEVENT
.
Per questo motivo, in diversi casi, preferiamo l'utilizzo dell'evento onPressEVENT
(come nel secondo esempio): così l'utente può selezionare e deselezionare la faccia desiderata cliccandoci sopra.
Per quanto riguarda l'associazione del listener, il codice va cambiato in questo modo:
face.addEventListener(ObjectEvent.onPressEVENT, this, onPress);
Mentre la funzione ha questo codice:
Listato 75. Imposta le azioni in base agli eventi del mouse
function onPress(e:ObjectEvent){
var obj:TriFace3D = e.getTarget();
var id = obj.getId();
if ( obj.getSkin() == markSkin ){
obj.setSkin(skins[id]);
}
else{
obj.setSkin(markSkin);
faceText.text = id;
}
camera.rotateX(0);
}
"© Petit Publications 2006" - diritti riservati