Lieber Besucher, herzlich willkommen bei: RPG Studio - Make your World real. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

  • Playm

    RPG Studio Webmaster

    Sie müssen sich registrieren, um eine Verbindung mit diesem Benutzer herzustellen.

316

Eine App schreiben, die RPG Maker Projekte öffnen kann

Bewertung:

Von Playm, Sonntag, 8. Oktober 2017, 17:10

Wer immernoch nicht mitbekommen hat, dass ich gerade an einem Programm schreibe, was den RPG Maker XP um für Spielentwickler nützliche Features erweitern soll nochmal der Hinweis mal ins Forum zu schauen.
Jetzt ist es für dieses Programm (die Kids von heute sagen dazu auch "App") ganz praktisch auf die Ressourcen des Projekts zuzugreifen, für das es gerade Unterstützung liefert. Auf diese Weise kann die App dann nachgucken, welche Weapons gerade in der Database eingetragen sind oder welche Charakter-Grafiken für Events zur Verfügung stehen. Ich hoffe das fixt euch schon an, dass euch selber ganz viele Möglichkeiten einfallen, was man alles anstellen kann, wenn unser Programm ein RPG Maker Projekt öffnen kann. Im heutigen Blogpost beschäftigen wir uns genau damit.

Was bedeutet es ein Projekt "zu öffnen"?
Wir kennen es aus dem RPG Maker XP, wenn wir auf "Projekt öffnen" klicken. Es erscheint der gewohnte Dateidialog, der uns unsere Dateien auf dem Rechner zeigt. Zusätzlich zeigt uns der Dateidialog an, dass ein sogenannter Filter aktiv ist und wir nur bestimmte Dateien gerade sehen - im Falle des Dateidialogs des RPG Makers XP ist der Filter "RPGXP Project (*.rxproj)".

Diese Datei finden wir auch in jedem Maker Projektordner. Aber was ist eigentlich der Inhalt dieser Datei? Text. In der Datei steht nur eine Zeile Text:

Zitat von »Game.rxproj«

RPGXP 1.05
Mehr steht da nicht. Nur die Versionsnummer des Makers mit dem dieses Projekt erstellt wurde.

Jetzt ist die Frage, warum dann diese Datei? Die Antwort ist kurz: Es geht um den Dateipfad. Den Ort auf der Festplatte.
Haben wir erstmal den Dateipfad zu einem Projekt gefunden, können wir coole Dinge tun.
Angenommen der Dateipfad ist der folgende:

Ruby Quellcode

1
"C:/Users/Playm/RPGXP/Project Defender/Game.rxproj"

Dann wissen wir, wir finden die Weapons dieses Projekts genau hier:

Ruby Quellcode

1
2
3
4
5
filename = "C:/Users/Playm/RPGXP/Project Defender/Data/Weapons.rxdata"
File.open(filename, "rb") do |f|
  data_weapons = Marshal.load(f)
  print "We have #{data_weapons.length} weapon entries.\n"
end


Und wir finden die Charaktergrafiken, die das Projekt importiert hat genau hier:

Ruby Quellcode

1
Dir.glob("C:/Users/Playm/RPGXP/Project Defender/Graphics/Characters/*.*")


Um diese Dateipfade uns zusammen zu bauen, schneiden wir vom Dateipfad der Projektdatei einfach das letzte Stück ab:

Ruby Quellcode

1
project_path = File.dirname( "C:/Users/Playm/RPGXP/Project Defender/Game.rxproj" )


Und schon können wir unsere Unterpfade dranhängen:

Ruby Quellcode

1
path_to_weapons = project_path + "/Data/Weapons.rxdata"


Jetzt erstmal die größere Frage: Wie erstelle ich mir eigentlich so einen Dateidialog?

Der Dateidialog
Ich will hier mal drei Optionen aufzählen:
  1. Wir könnten uns unseren eigenen Dateidialog von Grund auf bauen. Ruby kann mittels der Klasse Dir den Inhalt eines Ordners anzeigen. Hierbei kann man auch nach Dateiendung filtern - also alles was man braucht wäre da. Der Nachteil ist, dass man sich noch die Anzeige drumherum bauen muss, sprich das Dialogfenster selber und sehr wahrscheinlich nicht an das Design heran kommt, was der jewilige Nutzer von seiner Windows-Version gewohnt ist.
  2. Wir könnten die WinAPI bemühen und den in Windows standartisierten Dateidialog darüber öffnen. Früher konnte man einfach über die Win32API-Klasse die Funktion GetOpenFileName aufrufen und war bedient. Seit Vista ist diese Funktion deprecated und man soll einen CommonItem-Dialog öffnen. Wer sich dafür interessiert hier ist ein grundlegendes Beispiel zur Benutzung von CommonItem Dialogen. Ich habe mich für meine App gegen diesen Weg entschieden, aber prinzipiell ist das ein gangbarer Weg. Erfordert aber, sich etwas in die Materie einzulesen.
  3. Wir können eine Bibliothek benutzen, die bereits diese Funktion enthält. In unserem Fall ist das Qt. Diese erlaubt uns ohne große Schwierigkeiten vom User eine Datei auswählen zu lassen. Nachteil hier ist, dass man zwingend Qt einbinden muss und der Dialog nur aus einer Qt-App heraus aufgerufen werden kann.


Da wir eh Qt für die restlichen Fenster in unserem Programm verwenden habe ich mich für Option 3 entschieden. Allerdings ist da eine Sache zu bedenken. Das Qt-Binding ist in einer Sache sehr speziell, dass es nicht alle Funktionen der Qt-Bibliothek 1:1 in Ruby wiedergibt, sondern einfach guckt, was für eine Methode für eine Klasse aufgerufen wurde, was die Parameter waren und was wohl am ehesten für eine Qt-Funktion dazu passen würde. Dies sorgt dafür, dass

Ruby Quellcode

1
Qt::FileDialog.getOpenFileName( parent, "Titelzeile", "." )

einen NoMethod-Error erzeugt, wenn parent den Wert 0 oder nil hat. Die Funktion kann nur aufgerufen werden, wenn wir für parent ein Objekt der Klasse Qt::Widget oder einer Unterklasse davon übergeben. Wenn man daran nicht denkt und nur mal schnell den Dateidialog testen möchte ist das sehr verwirrend.

Jetzt habe ich euch aber lange genug auf die Folter gespannt. Wie sieht denn so ein Beispielcode aus, um ein RPG Maker Projekt zu öffnen?

Rubyscript, um ein RPG Maker Projekt zu öffnen
Als ob ihr euch Ruby installiert habt. :-P Aber trotzdem hier mal ein vollfunktionsfähiger Beispielcode, um sich ein paar kleine Statistiken über ein RPG Maker Projekt ausgeben zu lassen.
Spoiler: Quellcode

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
require 'Qt'
require_relative 'rpg.rb'
#==========================================================
# ** Open RPG Maker XP Projects and print statistics
#----------------------------------------------------------
#    Example Code by Playm
#==========================================================
class QtApp < Qt::Widget
  #--------------------------------------------------------
  # * Appwindow initialization
  #--------------------------------------------------------
  def initialize
    super
    setWindowTitle( "File dialog" )
    label = Qt::Label.new( "Open RPG XP Projects", self )
    label.setAlignment( Qt::AlignCenter )
    vbox = Qt::VBoxLayout.new self
    vbox.addWidget( label )
    resize 320, 240
    move 300, 300
    show
  end
  #--------------------------------------------------------
  # * Open FileDialog
  #--------------------------------------------------------
  def get_project_filename( start_path="." )
    title  = "Open Project"
    filter = "RPGXP Projekt (*.rxproj)"
    Qt::FileDialog.getOpenFileName( self, title,
                                    start_path, filter )
  end
  #--------------------------------------------------------
  # * Load content of .rxdata-File
  #--------------------------------------------------------
  def load_rxdata( filename )
    File.open(filename, "rb") do |f|
      Marshal.load(f)
    end
  end
  #--------------------------------------------------------
  # * Print Statistics
  #--------------------------------------------------------
  def print_statistics( path )
    data_items = load_rxdata(path+"/Data/Items.rxdata")
    data_weapons = load_rxdata(path+"/Data/Weapons.rxdata")
    data_armors = load_rxdata(path+"/Data/Armors.rxdata")
    # Print all
    print( "Your Project includes ",
           data_items.length,
           " Items and ",
           data_weapons.length,
           " Weapons and ",
           data_armors.length,
           " Armors.\n")
  end
  #--------------------------------------------------------
  # * Click Handler
  #--------------------------------------------------------
  def mousePressEvent event
    project_filename = get_project_filename()
    project_path = File.dirname( project_filename )
    print_statistics( project_path )
  end
end
#==========================================================
#  Main Run
#==========================================================
app = Qt::Application.new( ARGV )
QtApp.new
app.exec
zum Lesen den Text mit der Maus markieren


Auf eine Zeile will ich noch kurz eingehen:

Ruby Quellcode

2
require_relative 'rpg.rb'

Damit das Script die Database lesen kann, muss es wissen wie die Klassen RPG::Item, RPG::Armor und RPG::Weapon aussehen. Also schnell mal die Makerhilfe aufgemacht, aus der Section "RPGXP Data Structures" die Definitionen der Klassen rauskopiert und in rgb.rb reingespeichert.


Ich hoffe der Blogeintrag war wieder interessant. Diesmal sehr lang und sehr technisch orientiert. Wenn euch das nicht gefällt schreibt es in die Kommentare dann blogge ich nächstes Mal über was lustiges.

Dieser Artikel wurde bereits 42 mal gelesen.


Kommentare (3)

  • 3

    Von Josey (Montag, 9. Oktober 2017, 22:21)

    Oh, woah, das wusste ich noch gar nicht!
    Danke fürs Erklären! :D

  • 2

    Von Playm (Montag, 9. Oktober 2017, 15:20)

    [quote]Auswahl eines Charsets? XD[/quote]
    Mhm. Das könnte man damit umsetzen.

    [quote]Weil bei den ganzen Data-Paths wird die Game.rxproj nicht miterwähnt o.o[/quote]
    Die Methode File.dirname(...) entfernt aus dem String auch den Dateinamen und liefert nur den Pfad zurück.

    pfad = "C:/Users/Playm/RPGXP/Project Defender/Game.rxproj"
    print( File.dirname( pfad ) )

    Gibt das folgende aus: "C:/Users/Playm/RPGXP/Project Defender"
    Und:

    pfad = "C:/Users/Playm/Desktop/Urlaubsfoto.jpg"
    print( File.dirname( pfad ) )

    Gibt "C:/Users/Playm/Desktop" aus.
    Das kannst Du auch mal im Maker ausprobieren.

  • 1

    Von Josey (Montag, 9. Oktober 2017, 00:09)

    Ich sehe, du hast ein Thema gefunden? ;3

    "Ich hoffe das fixt euch schon an, dass euch selber ganz viele Möglichkeiten einfallen, was man alles anstellen kann, wenn unser Programm ein RPG Maker Projekt öffnen kann."
    Auswahl eines Charsets? XD

    "project_path = File.dirname( "C:/Users/Playm/RPGXP/Project Defender/Game.rxproj" )"
    -> Müsste es nicht heißen
    "project_path = File.dirname( "C:/Users/Playm/RPGXP/Project Defender" )"?
    Weil bei den ganzen Data-Paths wird die Game.rxproj nicht miterwähnt o.o

    Ich fands interessant (hab aber wirklich kein ruby XD) und bin gespannt, was dabei rauskommt. Das Ergebnis interessiert mich, aber den Weg zu sehen ist super : D

Blog Navigation

Nächster Artikel

Mit Qt ganz schnell das RTP des Makers laden

Von Playm (Sonntag, 15. Oktober 2017, 18:25)

Vorheriger Artikel

Ein super einfaches Pluginsystem für Ruby-Apps entwickeln

Von Playm (Samstag, 30. September 2017, 22:31)