Benutzer:Moerdn/ Module Controller

Beschreibung Bearbeiten

Der Modulcontroller bietet die Möglichkeiten Scripte außerhalb der Blenderdatei zu speichern und Funktionen daraus aufzurufen. Dieser Ansatz für das Scripten der LogicBricks bietet einige Vorteile gegenüber dem einfachen Script Controller und dem internen verwalten von Source Code in den Blenderdateien.

Vorteile Bearbeiten

  • Übersichtlichere Verwaltung des Source Codes durch Anlegen beliebiger Verzeichnisse zum Strukturieren
  • Programmieren bei laufender GameEngine, Änderungen werden sofort sichtbar (Debug Modus) kein Neustarten der GE nötig
  • Python Programme können mit beliebigen Texteditor editiert werden
  • Versionsverwaltung des Sourcecodes sehr einfach, dadurch ist das Arbeiten im Team an gleichen Quelldateien möglich
  • Scripte können geändert werden ohne Blender starten zu müssen
  • keine doppelten Scripte durch Appenden/Linken von Blenderdateien
  • keine nicht änderbaren Scripte durch das Linken von Blenderdateien
  • Module haben vollen Zugriff auf externe Pakete/ Drittanbieter oder eigene Python Module
  • Verwendung von Python Modulen die in C/C++ implementiert sind (Python C Extensions)

Nachteile Bearbeiten

  • Code Vervollständigung für die GameEngine Module nicht/nur schwer benutzbar
  • etwas aufwändigeres Setup der Verzeichnisstruktur
  • Lizenz rechtliche Unklarheiten

Verwendung Bearbeiten

Das Setup für das Verwenden des Modulcontrollers ist etwas aufwändiger als bei intern gespeicherten Scripten. Es muss eine Verzeichnisstruktur für das Spiel erstellt werden. Dies empfiehlt sich aber in jedem Fall. Das Wurzelverzeichnis für das Spiel enthält zumindest die Blenderdatei für das Spiel und einen weiteres Verzeichnis das als Python Modul dient. Diesen Verzeichnis wird im Folgenden Beispiel Src genannten und beinhaltet mindestens zwei Python Scripte.


 
Verzeichnisstruktur mit Source Verzeichnis


Das Python Script __init__.py muss in jedem Fall vorhanden sein und ist dafür zuständig, Funktionen aus dem Script Game.py zu exportieren und für das darüber liegende Verzeichnis Verfügbar zu machen. Um eine Funktion aus der Datei Game.py aufrufen zu können, muss man die volle Modulhierarchie angeben. Von dem Modul über die Datei, bis zur Funktion. Bsp: Src.Game.meine_funktion.

In Blender muss der Python Controller auf Module gesetzt werden und die auszuführende Funktion wie beschrieben mit Modulname.Scriptname.Funktionsname angegeben werden. Damit das Script ausgeführt werden kann muss ein Sensor mit dem Controller verbunden sein. In diesem Fall ein Always Sensor mit Pulse Mode 0. So wird das Script einmal ausgeführt werden.


 
Python Modulecontroller LogicBrick

__init__.py Bearbeiten

Das Script __init__.py enthält ausschließlich import Anweisungen und keinen weiteren Code. Es gibt mehre Möglichkeiten Namen aus Scripten zu exportieren:

  • from Script import foo macht nur die eine Funktion foo verfügbar
  • from Script import * exportiert alle Funktionen, Variablen, Klassen.
  • import Script as Sc macht das Script unter dem Namen Sc verfügbar


# Inhalt von __init__.py

from Src.Game import start 

# END __init__.py


Game.py Bearbeiten

Das Game.py Programm kann alle möglichen Python Konstrukte verwenden und definiert Funktionen die der Modulcontroller ausführen kann. Diesen Funktionen sollte man genau einen Parameter con übergeben. Dieser Parameter stellt den Controller dar und gibt somit Zugriff auf die gesamte LogicBrick. Auf die übliche Anweisung con = GameLogic.getCurrentController() kann hier sehr bequem verzichtet werden.

Wichtig: Man sollte im Script Game.py keine globalen Variablen definieren, die direkt mit dem ausführenden Controller zusammen hängen. variablen wie controller, owner, sensor_X und actuator_Y gehören ausschließlich in die ausführende Funktion, da verschieden Modulcontroller die Funktionen ausführen können, die nicht dem gleichen GameObject angehören.


# Inhalt von Game.py

def start(con):

    own = con.owner
    
    if con.sensors[0].positive:
        # Sensor puls positiv
        # starte Spiel, wechsele State, etc.

        print("Starte Spiel")
        con.activate(con.actuators[0])

# END Game.py


Es können trotzdem globale Variablen in dem Script angelegt werden. Diese sind später per default aber nur lesbar und können so als Konstanten des Moduls verwendet werden:


# Inhalt von Game.py

SPIEL_VERSION = 1.0

def start(con):

    own = con.owner
    
    if con.sensors[0].positive:
        print("Starte Spiel in der Version: ", SPIEL_VERSION)
        
       ##
       # ERROR: SPIEL_VERSION darf nicht geändert werden
       # SPIEL_VERSION += 0.1

# END Game.py


Möchte man globale Variablen in dem Modul ändern, kann man das Schlüsselwort global verwenden. Dies werde ich hier aber nicht empfehlen da globale Variablen einfach böse sind. Jede Funktion die anzahl_leben als globale Variable definiert hat schreibenden Zugriff und kann die verbleibenden Leben des Spielers und kann diese nach belieben ändern.


# Inhalt von Game.py

anzahl_leben = 3

def start(con):

    # anzahl_leben kann nun verändert werden
    global anzahl_leben

    own = con.owner
    
    if con.sensors[0].positive:

        ##
        #  Spieler töten
        anzahl_leben = 0

# END Game.py


Stattdessen gehört die Variable anzahl_leben zu dem Spieler und sollte als Property einer entsprechenden KX_GameObject Instanz gespeichert werden.


# Inhalt von Game.py

def hit(con):

    own = con.owner
    
    if con.sensors[0].positive and 'anzahl_leben' is in con.owner:
        own['anzahl_leben'] -= 1

# END Game.py

Zurück Bearbeiten

zurück zu Benutzer:Moerdn/ GameLogic