Come posso comunicare con un componente IronPython in un gioco C # / XNA?


8

Il mio gioco XNA è orientato ai componenti e ha vari componenti per posizione, rappresentazione fisica, rendering, ecc., Tutti i quali estendono una Componentclasse base . Il giocatore e i nemici hanno anche controller che sono attualmente definiti in C #. Vorrei trasformarli in script Python tramite IronPython (un'implementazione .NET di Python). Il mio problema è che non sono sicuro di come interagire con quegli script.

Gli esempi di Incorporamento di IronPython in un'applicazione C # suggeriscono che dovrei creare qualcosa di simile a un componente Script che compila uno script Python e chiama il metodo Update del controller tramite Python; in sostanza, sarebbe una classe wrapper per C # per interfacciarsi con Python .

Sento che mi manca qualcosa nella mia ricerca. Ci deve essere un modo per caricare uno script, creare un'istanza di un oggetto Python (o nello script Python o in C #) e quindi avere un riferimento diretto a quell'oggetto Python nel mio codice C #.

C'è un modo per lavorare con un oggetto IronPython direttamente , o è un wrapper richiesta?

Risposte:


7

Ho capito come farlo. Come mi aspettavo, dal momento che IronPython si compila fino a CLR, gli oggetti C # e IronPython possono interagire tra loro bene senza alcun trattamento speciale necessario. Ho creato uno script che in realtà crea un nuovo tipo di componente che può essere referenziato bene da C #.

Una breve parola sulla struttura del mio gioco: la sua soluzione ha due progetti: Game e GameEngine. Il gioco è ciò che alla fine viene compilato in un EXE e GameEngine viene compilato in una DLL che si trova nella stessa directory.

Il copione

Attualmente si trova nel progetto di contenuto predefinito, non ha azioni di compilazione e viene copiato nella directory di output.

Nota che la classe Component fa parte di GameEngine e quindi viene compilata in GameEngine.dll . Inoltre non ha nulla a che fare con la classe GameComponent di XNA e i suoi metodi non hanno bisogno di passare un oggetto GameTime.

import clr
clr.AddReferenceToFileAndPath("GameEngine.dll")
from GameEngine import *
# or: from GameEngine import Component

class PyComponent(Component):
    def __new__(self):
        Component.__new__(self)

    def Initialize(self):
        pass

    def Update(self):
        pass

    def Draw(self):
        pass

pc = PyComponent()

Come viene compilato ed eseguito lo script

Solo una volta all'interno del gioco, eseguo questo:

// Engine setup stuff. The scope can work with variables in the script by
// adding references, accessing/removing current references, etc.
// Each script COULD have its own scope but I have no reason to do that yet.
ScriptEngine PythonEngine = Python.CreateEngine();
ScriptScope DefaultScope = PythonEngine.CreateScope();

string filename = @"Content\ScriptTest.py";
ScriptSource script = PythonEngine.CreateScriptSourceFromFile(filename, Encoding.ASCII);
script.Execute(scope);

Quando lo script viene eseguito, crea la propria istanza di un PyComponent.

Ovviamente dovrai fare riferimento alla libreria IronPython e al runtime Microsoft Dynamic. Ho scoperto che ho solo bisogno di queste quattro DLL dalla cartella principale del download IronPython:

  • IronPython.dll
  • IronPython.Modules.dll
  • Microsoft.Dynamic.dll
  • Microsoft.Scripting.dll

Aggiungi questi riferimenti al tuo progetto, quindi queste usingistruzioni al tuo codice (secondo Embedding IronPython in un'applicazione C # ):

using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;

Ottenere un riferimento all'oggetto Python

Non sono sicuro di come ottenere un riferimento direttamente dalla sceneggiatura, ma ho un modo rotatorio per farlo. Nella mia progettazione del motore, tutti i componenti si registrano automaticamente con la raccolta dei componenti del motore, in modo da poter ottenere un riferimento all'oggetto da lì. In un caso più specifico, potresti semplicemente far registrare nuovi oggetti Python con una coda da qualche parte, quindi li crei e poi li recuperi immediatamente.


Il mio ultimo aggiornamento a questo post sarà quando capirò come ottenere direttamente un riferimento all'oggetto python.
doppelgreener,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.