Python – Cambiare l’Actuator

In questo breve tutorial spiegherò com’è possibile cambiare un’Actuator in base al risultato di una Property, prima farò un’esempio solo con i Mattoni, poi vedrai come attraverso il Python la stessa procedura è semplificata.

Versione a Mattoni

In questo esempio voglio che il cubo di base ruoti in un senso quando la Property è Vera (True) e nell’altro quando è Falsa (False). 

Aggiungi una property boolean e dagli il nome che vuoi, io l’ho chiamata cambio. Inserisci un Sensor Always e un’Actuator Motion, dagli una rotazione sull’asse Z, collegali con un Controller And. Aggiungi ora un Sensor Keyboard e usa il tasto che vuoi, io ho usato lo spazio, aggiungi ora un’Actuator Property e imposta il Mode a Toggle, seleziona la Property nel campo, collega tutto con un Controller And. Aggiungi ora un Sensor Property, seleziona la Property e scrivi sul campo Value True. Collega il Sensor appena inserito tramite un Controller And ad un’Actuator State e seleziona il secondo State Mask, di default l’operazione è Set State Mask, lasciala così. Ecco uno screenshot di questi mattoni appena inseriti

Nel secondo State Mask devi replicare gli stessi Mattoni, cambiare il verso della rotazione, cambiare il Valore (Value) nel Sensor Property da True a False e lo State Mask nell’Actuator è il primo, eccoti lo screenshot

Prima di verificare se questa logica funziona attiva sia nella Property che negli State Mask il pulsante che mostra i dati in debug, e dal menù Game (in alto nel menù principale) metti la spunta nell’opzione Show Debug Properties. Salva e premi P, per fare partire il motore, come puoi notare immediatamente lo State Mask cambia dal primo di partenza al secondo perché la Property cambio (io l’ho chiamata così) è False, se premi il tasto da te scelto la Property diventa True e lo State Mask passa al primo e si inverte il senso della rotazione. 

Per eseguire questo semplice esempio hai inserito 12 Mattoni complessivamente, 6 per ogni State Mask, solo per far ruotare il cubo in due direzioni diverse. Questo uso degli State Mask è comune quando si vogliono creare delle logiche di tipo switch (interruttore), infatti è molto utile per creare gli interruttori per accendere e spegnere le lampadine nei giochi, anche se non è solo questo, bisogna anche aggiungere il fattore del player se è vicino all’interruttore, ma non è lo scopo di questo articolo.

Versione Python

Diversamente se uso del codice innanzitutto risparmio sull’uso dei Mattoni e non uso gli State Mask. 

Come prima cosa fai un Full Copy della scena, se non sai come fare leggi questa pagina, nella nuova scena elimina tutti i Mattoni nel secondo State Mask, e dal primo elimina i Sensor Always e Property e l’Actuator State. Iniziamo. Sposta l’Actuator Property in alto e collegalo tramite un Controller And al Sensor Keyboard. Adesso aggiungi un’Actuator Motion e impostalo come nel secondo State Mask dell’esempio a mattoni, cioè con la rotazione invertita, collega ora i due Actuators Motion al Sensor Keyboard tramite Controller Python. Eccoti uno screenshot dei Mattoni collassati, ricorda di rinominare sempre tutti i Mattoni

E ora di scrivere il codice. Crea uno script e chiamalo come meglio credi, per questo tutorial non è importante, io l’ho chiamato cambio_act.py. In alto allo script scrivi la chiamata del modulo bge e le solite variabili globali come negli articoli precedenti, così

import bge
    
    ### VARIABILI GLOBALI ###
cont = bge.logic.getCurrentController()
own = cont.owner

Adesso devi dichiarare gli elementi del proprietario cioè la Property e i Mattoni collegati al Controller, se non sai come fare leggi la pagina Blender e Python, in ogni caso inserisco il codice di seguito

# Porperty boolena cambio
bool_cambio = own['cambio']

# dichiarazione Sensor
sens_spazio = cont.sensors['spazio']

# dichiarazione Actuators
actu_pos = cont.actuators['pos']
actu_neg = cont.actuators['neg']

Per verificare se tutto fino ad ora funziona apri la console di sistema, trovi come si fa sempre nella pagina sopra citata, ricorda di selezionare lo script nel Controller Python, fai partire il motore e premi il tasto da te scelto, se nella Console non ci sono errori e la Property in Debug Mode cambia hai fatto tutto bene, in caso contrario rivedi questa parte di tutorial.

Adesso viene il nocciolo di questo tutorial, usando un’istruzione condizionale if (quella che hai usato anche nei tutorial precedenti) diciamo a Blender che “se la Property è True attiva uno degli Actuator, altrimenti attiva l’altro”.
Questo piccolo pseudo codice introduce un nuovo elemento l’attivazione di un’Actuator (se leggi tutta la pagina precedentemente citata trovi alcune righe di codice con l’attivazione e la disattivazione di un’Actuator). In poche parole quando diciamo a Blender di attivare un’Actuator (o più Actuator collegati al Controller Python che esegue lo script che riceve l’impulso positivo dal Sensor collegato, questo è importante) non facciamo altro che inviargli un’impulso positivo, ma a decidere quando attivarlo sei tu; questo aspetto cambia un pò le carte in tavola, mentre con i soli Mattoni una volta partito l’impulso dal Sensor automaticamente (levando alcuni casi specifici) veniva attivato l’Actuator, con uno script puoi anche attivarne uno e cambiare in runtime le sue opzioni, questo però lo vedrai in un’altro articolo. Eccoti il codice

# condizione
if bool_cambio == True:
    cont.activate(actu_pos)
else:
    cont.activate(actu_neg)

Il codice dice semplicemente : ” se la Property (bool_cambio) è True, cioè vera, attiva l’Actuator actu_pos (dichiarato precedentemente), altrimenti attiva l’Actuator actu_neg. “

Salva e fai partire il motore di gioco. Il risultato non è quello voluto ? Sai anche capire il perché ? 

L’errore è intenzionale, per spiegarti che quando premi il tasto il Sensor invia l’impulso al Controller Python che invece di inviarlo ad uno solo degl’Actuator lo invia ad entrambe, questo è un pò inspiegabile perché lo script dovrebbe filtrare l’impulso a seconda dello stato della Property, in realtà non è così, per ovviare a questo inconveniente non devi fare altro che deattivare l’Actuator opposto a quello attivato dal cambio della Property, aggiungi nel codice le righe come mostro sotto

# condizione
if bool_cambio == True:
    cont.activate(actu_pos)
    cont.deactivate(actu_neg)
else:
    cont.activate(actu_neg)
    cont.deactivate(actu_pos)

Quindi se la Property è True attiva actu_pos e deattiva actu_neg, altrimenti fai l’opposto. Salva e fai partire il motore. Come vedi adesso hai ottenuto lo stesso risultato della versione con i Mattoni ma utilizzandone meno, la metà per precisione. 

Con questo piccolo esempio vorrei introdurre nuove specifiche sull’uso del Python nel motore di gioco di Blender, partendo sempre dal fatto che non sono un programmatore e che sto studiando come il programma si interfaccia con il linguaggio per poter dare una visione più ampia della creazione dei giochi con Blender. Quindi ti rimando al prossimo tutorial. Fai diverse prove, sperimenta e fai pratica, perché con la pratica si impara molto.

 Puoi scaricare il file di questo articolo QUA.