Comprendere il python in bge – OOP , programmazione orientata agli oggetti

La programmazione orientata agli oggetti, è un tipo di programmazione che permette di creare oggetti di memoria, permettendo l’interazione tra questi tramite messaggi. 

È particolarmente adatta nei contesti in cui si possono definire delle relazioni di interdipendenza tra i concetti da modellare (contenimento, uso, specializzazione). Un ambito che più di altri riesce a sfruttare i vantaggi della programmazione ad oggetti è quello delle interfacce grafiche.

Altri vantaggi della programmazione orientata agli oggetti sono :

  • fornisce un supporto naturale alla modellazione software degli oggetti del mondo reale o del modello astratto da riprodurre
  • permette una più facile gestione e manutenzione di progetti di grandi dimensioni
  • l’organizzazione del codice sotto forma di classi favorisce la modularità e il riuso di codice

Il game engine, detto in breve, è un framework composto da librerie di oggetti detti moduli, i quali moduli sono composti da classi. Ogni oggetto che vediamo nella viewport quindi deriva dalle classi istanziate in blender.
I moduli standard a nostra disposizione sono elencati a questo indirizzo .

Nella programmazione orientata agli oggetti, ogni oggetto è a se stante ed ha in se delle proprietà valorizzabili (oppure valorizzate di default dalla classe da cui deriva) e dei metodi che possono essere richiamati dagli eventi del game engine.

  • Le proprietà sono variabili di memoria legate all’oggetto e possono essere pubbliche, private oppure protette.
    1. Le proprietà dichiarate pubbliche non hanno nessun prefisso e sono accessibili in lettura\scrittura in qualsiasi punto dello script.
    2. Le proprietà dichiarate private hanno come prefisso il carattere _, sono utilizzabili liberamente all’interno della classe ma possono essere gestite all’interno dello script tramite dei metodi get (lettura) oppure set (scrittura)  .
    3. Le proprietà dichiarate protette hanno come prefisso il carattere __,  sono utilizzabili solo dalla classe e possono essere lette dallo script tramite dei metodi di set (lettura) .
  • I metodi di una classe determinano il comportamento programmatico dell’ oggetto ovvero, diciamo all’oggetto di comportarsi in un determinato modo a seconda degli eventi. Anche i metodi, come le proprietà, possono essere dichiarati pubblici, privati oppure protetti, preponendo e posponendo al metodo _ se è privato oppure __ se è protetto.
  • Gli eventi nel nostro caso sono i mattoni logici sensors .

Successivamente ritorneremo sul concetto di classe ed approfondiremo quanto appena detto. Intanto, riprendendo il filo del discorso , ogni oggetto sarà il proprietario delle proprie logiche di gioco quindi, sarà ricorrente la variabile owner (proprietario).

Ogni script oppure modulo che andremo a programmare, comincerà con il seguente comando :

import bge oppure from bge import * 

il primo comando importa tutti gli oggetti del modulo bge e li rende disponibili nello script in uso mentre il secondo ci da la possibilità di importare dal modulo bge solo gli oggetti strettamente necessari. Questo ci permette di ottimizzare ulteriormente le risorse in quanto, meno oggetti carichiamo in memoria, minore sarà il numero di oggetti che il motore di gioco dovrà gestire e di conseguenza minore sarà il carico di calcolo demandato al sistema.

Il modulo bge, ci permette di accedere alle classi dell’oggetto strettamente legate al motore di gioco.

immagine

Notiamo che il sensor utilizzato è Always quindi questo evento viene sempre eseguito dal motore di gioco se l’activate trigger è impostato su True, altrimenti viene eseguito sempre solo una volta all’avvio del gioco.

Attualmente, ci troviamo nella situazione di dover sapere chi è il proprietario della logica di gioco. Il game engine non ragiona in base all’oggetto selezionato in quanto deve gestire tutti gli oggetti all’interno della scena, ne tantomento possiamo ragionare nei termini “ho solo questo oggetto quindi lo devi sapere”. Il ragionamento che deve essere fatto alla base è quello che ogni script oppure un modulo possono essere riutilizzati all’interno dello stesso progetto, quindi è sempre bene cercare di generalizzare il concetto che si stà per affrontare. Più si generalizza, meno codice si scrive. Meno codice si scrive, più tempo si risparmia.

#importiamo l'oggetto logic dal modulo bge
from bge import logic

#dall'oggetto logic, recupero il proprietaro del controller 
#python in questo caso è l'oggetto a cui è stato assegnato 
#questo controller.
own = logic.getCurrentController().owner

#La variabile own è una variabile locale dello script 
#che allo stato attuale è diventata il nostro 
#oggetto proprietario.
#Piccolo 
#La tecnica di memorizzare un oggetto all'interno
#di una variabile è ricorrente per ogni linguaggio di 
#programmazione... immaginatevi a dovervi ricordare di 
#scrivere ogni volta logic.getCurrentController().owner
#per accedere al proprietario. own è più immediato.
#A questo punto, tutti i metodi e le proprieta del cubo  
#sono accessibili tramite la variabile own e per dimostrarlo 
#, stampo a video il valore contenuto nella proprietà "name" 

print(own.name)

#La funzione dir(), passando come parametro l'oggetto, 
#ci permette di visualizzare tutti i metodi ereditati 
#dalla classe base
print(dir(own))

Ricordate sempre di attivare la toggle system console per visionare gli output che blender stamperà a video.

Vi consiglio, se non l’avete già fatto, di leggere l’articolo riguardante l’architettura del motore di gioco e quello sulle convenzioni