Seite 1 von 4 1234 LetzteLetzte
Ergebnis 1 bis 20 von 71

Thema: [VX-Ace] Script zeigt Bild nicht an

  1. #1

    [VX-Ace] Script zeigt Bild nicht an

    Hallo zusammen ^^

    Ich arbeite gerade an einem Script für ein Memory und habe momentan ein großes Problem, mein Bild wird nicht angezeigt.

    Das Debakel sieht bis nun so aus:
    Code:
    def draw_graphic
          @graphic = Sprite.new
    
          if $modus == 1
            #@graphic.bitmap = Cache.picture("Grundkarte.png") rescue nil
          end
          if $modus == 0
            @graphic.bitmap = Cache.picture("Testkarte.png", 1, $x_1, $y_1, 100, 100,
            255, 0) rescue nil
          end
        
        end
    In den Variablen $x_1 und $y_2 stehen Werte. Eigentlich war es von mir angedacht damit das Bild richtig auf dem Screen zu platzieren. (Habe auch via Konsole geprüft ob in den Beiden was drin steht, tut es und auch der modus ist 0.)

    Mein Versuch "Number" mitzuliefern sieht wie folgt aus:
    Code:
    if $modus == 0
            @graphic.bitmap = Cache.picture[1].show("Testkarte.png", 1, $x_1, $y_1, 100, 100,
            255, 0) rescue nil
          end
    Bekomme aber nur einen schwarzen Bildschirm geliefert.
    Wenn ich das "rescue nil" wegnehme schmiert mir Spiel ab. So dann auch mal zwischendrin die Frage, was macht dieser Befehl überhaut. Habe ihn in anderen Scripten mit Bildern immer wieder gesehen.

    Ein Bild wird mir zudem angezeigt wenn ich einfach sage:
    Code:
    @graphic.bitmap = Cache.picture("Testkarte.png")
    Aber das ist ja nicht das was ich möchte. Dann ist das Bild stumpf oben links in der Ecke und zudem möchte ich ja auch mehrere anzeigen.

    Natürlich kann man so ein Memory auch leicht ohne Script basteln, aber ich möchte es unbedingt mit hinbekommen.

    Wäre super lieb wenn mir hier wer auf die Sprünge helfen könnte.

  2. #2
    Mit der Position hat das Bitmap nichts am Hut, das wird über den Sprite geregelt. Die beiden zusammen kann man sich ein bisschen vorstellen wie eine Leinwand (Sprite) auf die eben was gemalt wird (Bitmap). Die Leinwand mit dem Gemalten wird dann irgendwo platziert.

    Was du machen musst, ist also folgendes:
    Code:
    sprite = Sprite.new
    sprite.bitmap = Cache.picture('Testkarte.png')
    sprite.x = $_x1
    sprite.y  = $_y1
    Cache.picture holt einfach nur ein Bitmap aus dem Cache, wenn es da drin ist, ansonsten wird von der Festplatte geladen. Das spart Zeit und Speicher falls eben dieses Bitmap noch öfters gebraucht wird. Verschiedene Leinwände teilen sich dann quasi ein Gemälde. Wenn du hingegen fünf mal direkt Bitmap.new('Graphics/Pictures/meinbild.png') nutzt, hast du am Ende unnötigerweise fünf Mal ein identisches Bitmap im Speicher, das auch jedes Mal wieder neu von der Festplatte geladen werden muss.

    rescue nil ist übrigens eine dumme Idee, weil du damit den Fehler dort unterdrückst wo er passiert und dann je nach Script ziemlich sicher später an anderer Stelle eine Fehlermeldung bekommst, deren Ursprung auf den ersten Blick nicht zu erkennen ist.



    Edit: Achso, falsch verstanden. Du wolltest wissen, was es mit dem rescue auf sich hat, nicht mit dem Cache?

    Wie gesagt, damit werden Fehler abgefangen.

    In deinem Beispiel ist der Cache.picture-Aufruf fehlerhaft, deshalb wird stattdessen das getan, was hinter dem rescue steht, in deinem Fall einfach ein allein stehendes nil. Dem Sprite wird also nie ein Bitmap zugewiesen, deshalb bleibt der Bildschirm schwarz.

    Geändert von Cepanks (29.03.2015 um 10:32 Uhr)

  3. #3
    Klasse, danke.
    Ein Bild juhu

    Aber... wie bekomme ich jetzt mehrere Bilder auf einmal angezeigt?
    Immer wieder einen neuen sprite[nummer] = Sprite.new erzeugen klappt ja nicht (ja ich habs versucht). Da wird nur ein Bild angezeigt und das Vorherige ausgeblendet.
    Bin sowieso ein wenig verwundert, der Fehler liegt vermutlich weiter oben im Code, aber nach ein paar Sekunden verschwinden mein Bild auch einfach wieder.
    Ich glaube ich brauche noch einen Schubser in die richtige Richtung

  4. #4
    Sprites in RGSS haben keine Nummern. Du musst für jeden Sprite eine neue Variable verwenden, sonst wird der alte überschrieben. Was natürlich auch geht, ist ein Array, so werden auch die Pictures im Maker verwaltet. Das versuchst du scheinbar gerade.

    Um genau sagen zu können warum dein Bild wieder verschwindet, fehlen Informationen. Hast du für dein Memory eine neue Szene erstellt oder versuchst du das irgendwo anders mit reinzuschreiben? Am besten wäre, wenn du mal dein komplettes Script zeigst.

    Ein erster Tipp wäre, dass "sprite" nur eine lokale Variable ist, die wieder verfällt, sobald Ruby mit deiner Methode durch ist, in der der Sprite erstellt wird. (War in meinem Beispiel auch so, aber das war eigentlich nur zur Demonstration von Sprites^^)

  5. #5
    Also bis jetzt sieht das so aus:

    Code:
    class Memory < Scene_Base
    
    #-------------------------------------------------------------------------------
    # Startet nach und nach alle Methoden
    #-------------------------------------------------------------------------------
      def start
        super 
        gegebenheiten
        draw_graphic
      end
    
    #-------------------------------------------------------------------------------
    # Legt die Grundvariablen und Arrays fest. Verteilt zudem die Koordinaten.
    #-------------------------------------------------------------------------------
    
       def gegebenheiten
        # Hier wird der Modus grundlegend bestimmt.
    
        if $game_switches[1] == true
          $modus = 0
        end
        if $game_switches[2] == true
          $modus = 1
        end
        if $game_switches[3] == true
          $modus = 2
        end
        
        # IDs der Spielkarten, ihr Standort in dem Array bestimmt die Position
        # auf dem Spielfeld. Zahlen kommen doppelt vor, da es von jeder Karte
        # 2 gleiche gibt.
        random = [
        0, 0,
        1, 1,
        2, 2,
        3, 3,
        4, 4,
        5, 5,
        6, 6,
        7, 7
        ].shuffle
        # in diese Variablen werden die IDs aus dem Array gespeichert, zwecks 
        # Vergleich.
        # mal schaun ob ich das so brauche
        # $id_1 = 0
        # $id_2 = 0
        
        # Die Koordinaten lauten: 
        # 000 x 000 | 136 x 000 | 272 x 000 | 408 x 000
        # 000 x 104 | 136 x 104 | 272 x 104 | 408 x 104
        # 000 x 208 | 136 x 208 | 272 x 108 | 408 x 108
        # 000 x 312 | 136 x 312 | 272 x 312 | 408 x 312
        xy = [
        0, 0, 
        136, 0, 
        272, 0, 
        408, 0,
        #
        0, 104, 
        136, 104, 
        272, 104, 
        408, 104,
        #
        0, 208, 
        136, 208, 
        272, 208, 
        408, 208,
        #
        0, 312, 
        136, 312, 
        272, 312, 
        408, 312
        ]
        i = 0
        j = 0
        r = 0
        # Hier kommt zusammen was zusammen gehört!
        while i < 15 do
          $xi = xy[j]
          j = j + 1
          $yi = xy[j]
          j = j + 1
          $r = random[r]
          r = r + 1
          
          if i == 0
            $id_0 = $r
            $x_0 = $xi
            $y_0 = $yi
          end
          if i == 1
            $id_1 = $r
            $x_1 = $xi
            $y_1 = $yi
            p $x_1
            p $y_1
          end
          i = i + 1
        end
      end
    
    #-------------------------------------------------------------------------------
    # Sorgt für das Anzeigen der Bilder
    #-------------------------------------------------------------------------------
      
      def draw_graphic
          sprite = Sprite.new
          sprite1 = Sprite.new
    
          if $modus == 1
            
          end
          if $modus == 0
            sprite.bitmap = Cache.picture("Testkarte.png")
            sprite1.bitmap = Cache.picture("Spinne1.png")
            sprite.x = $x_0
            sprite.y = $y_0
            sprite1.x = $x_1
            sprite1.y = $y_1
          end
        
        end
    end
    Aufgerufen wird es mit dem Befehl halt
    Code:
    SceneManager.call(Memory)
    Bis jetzt noch seeeehr umständlich geschrieben, aber erstmal soll es ja laufen, verfeinern kann man ja immer noch :3

  6. #6
    Hi,

    du musst die Sprites "am Leben halten". Wenn du sie in lokale Variablen abspeicherst, werden sie irgendwann vom GarbageCollector gelöscht und die Grafik wird nicht mehr angezeigt.

    Hierfür verwendest du am besten Instanzvariablen (also die mit dem @).

    Globale Variablen solltest du möglichst vermeiden. Nimm am besten die globalen Variablen die die RGGS selbst definiert und füge dort deine eigenen Attribute hinzu.

    Überhaupt macht es Sinn deinen Code mehr in Klassen zu organisieren, sonst wirst du schnell den Überblick verlieren.

    Hier mal ein Beispiel wie das aussehen könnte:
    Code:
    class Game_Memory
      # hier kommen alle Attribute rein die dein Spiel so hat
      
      # filenames of the pictures of your cards
      attr_accessor :figure_names
      
      def initialize
        @figure_names = []
        @positions = []
        # number of cards horizontal
        @max_number_of_cols = 4 
        # size of cards
        @card_width = 64
        @card_height = 64
        # distance between cards
        @margin = 12
      end
      
      # returns x, y coordinates as well as the image name of
      # the card with the given index
      def get_card index
        [card_x(index), card_y(index), card_image(index)]
      end
    
      # return all cards
      def get_cards
        # create a new array with elements
        # for all indizes from 0 upto @positions.size
        (0...@positions.size).map do |index|
          # each element contains the result value of
          # get_card
          get_card index
        end
      end
      
      # x coordinate for a given card index
      def card_x index
        col_num = index % @max_number_of_cols
        col_num * (@card_width + @margin)
      end
      
      # y coordinate for a given card index
      def card_y index
        row_num = index / @max_number_of_cols
        row_num * (@card_height+@margin)
      end
      
      # filename of card image
      def card_image index
         @figure_names[@positions[index]]
      end
      
      # number of different figures/cards
      def number_of_pictures
        @figure_names.size
      end
       
      # add 2 cards for each figure into the field
      # shuffle the positions of all cards
      def shuffle_cards
        @positions.clear
        # this loop is invoked as often as the number
        # of different cards
        number_of_pictures.times do |picture_id|
          # for each invocation, two cards are added
          # into the array 
          @positions << picture_id << picture_id
        end
        # shuffle the array at the end
        @positions.shuffle!
      end
      
    end

    Das ist deine Game-Logik Klasse. Die verwaltet alle Attribute des Memory-Spiels sowie die Spiellogik dahinter. Was sie nicht macht ist das Anzeigen der Grafik und das entgegennehmen von Nutzereingaben. Das regelst du über die Scene. Als nächstes speicherst du dieses Memory-Objekt in ein bestehendes globales Objekt ab. z.B. Game_System

    Code:
    class Game_System
      # füge Memory als Attribut hinzu
      attr_accessor :memory
    end
    Jetzt kannst du ein neues Memory-Spiel mit
    Code:
    $game_system.memory = Game_Memory.new
    anlegen.

    Als nächstes legst du deine Szene-Klasse an. Hier musst du dir klar machen das Grafiken in einer Szene einen Lebenszyklus haben: Jede Grafik muss angelegt, geupdatet und am Ende der Szene wieder gelöscht werden. Dafür legst du entsprechend drei Funktionen an:
    Code:
    def initialize_graphics
      # for each card in the game
      @card_sprites = $game_system.memory.get_cards.map do |x, y, image|
        # create a new sprite
        sprite = Sprite.new
        # set its graphic and coordinates
        sprite.bitmap = Cache.picture(image)
        sprite.x, sprite.y = x, y
        # and "return" the sprite into the array
        sprite
      end
    end
    
    def update_graphics
      # update attributes of all sprites
      @card_sprites.each_with_index do |sprite, index|
        x, y, image = $game_system.memory.get_card(index)
        sprite.bitmap = Cache.picture(image)
        sprite.x, sprite.y = x,y
      end
    end
    
    def dispose_graphics
      @card_sprites.each do |sprite|
        sprite.dispose
      end
    end
    Das updaten ist erstmal nicht so wichtig, solange du die Positionen der Karten nicht änderst. Wenn du aber neue Funktionen einfügst, wie z.B. das der Nutzer Karten entfernen kann, müssen diese Aktionen Auswirkungen auf das Anzeigen der Grafiken haben. Das regelst du in dem Update-Zyklus. Sprich: Wenn der Nutzer eine Karte abhebt änderst du die Variablen in $game_system.memory. Beim nächsten Updaten der Grafiken werden diese Änderungen dann sichtbar.

    Ich hoffe ich hab dir nicht zu viel "vorgesagt". Aber ich denke es gibt noch genug zu tun. So ein Memory-Spiel ist eine gute Übung für das Scripten in der RGSS.

    Ein paar Vorschläge was man noch bessern könnte:
    - wenn du viele Grafiken verwalten musst, legt für diese eine neue Klasse Spriteset_Memory an. Dann musst du weniger Code in deine Szene-Klasse legen.
    - genauso macht es evtl. Sinn die Logik hinter den Spielkarten in eine eigene Game_MemoryCard Klasse auszulagern. Die Klasse Game_Memory verwaltet dann einen Array von Game_MemoryCard Objekten, die Methoden zum Abfragen der Position etc. haben
    - genauso kannst du eine Klasse Sprite_GameCard schreiben die eine Referenz auf Game_MemoryCard hat und weiß wie sie grafisch angezeigt werden

  7. #7
    Danke euch Zwei so weit, aber ich glaube ich noch was an dem Code von -KD- falsch verstanden.

    Zum Verständnis...
    In das Array
    Code:
    @figure_names = []
    kommen alle Bilder rein die ich anzeigen möchte oder?
    zum Beispiel sehe das dann so aus
    Code:
     @figure_names = ["Testkarte.png"]
    oder?

    Sollte das so weit stimmen, anderes Verständnisproblem.
    Code:
    def initialize_graphics
      # for each card in the game
      @card_sprites = $game_system.memory.get_cards.map do |x, y, image|
        # create a new sprite
        sprite = Sprite.new
        # set its graphic and coordinates
        sprite.bitmap = Cache.picture(image)
        sprite.x, sprite.y = x, y
        # and "return" the sprite into the array
        sprite
      end
    end
    .

    Muss ich das für jede Karte machen? Bis jetzt kam es mir so vor, als würde das der Code für alle schon regeln, glaube aber hier etwas arg falsch verstanden zu haben.
    Momentan kommt mir der dumpfe Gedanke... dass die Zeile
    Code:
     @card_sprites = $game_system.memory.get_cards.map do |x, y, image|
    so aussehen müsste:
    Code:
    @card_sprites = $game_system.memory.get_cards.map do |0, 0, "Testbild.png"|
    Wobei ich mich dann natürlich auch wieder frage, wofür ich vorher
    Code:
    @figure_names
    und
    Code:
    @positions
    habe. Mir war so genau diese müssten dafür da sein.
    Natürlich lagen die beiden Array in einer Klasse, wodurch das zusammenhängen kann das ich das noch einmal machen muss, dennoch bin ich momentan arg verwirrt, da ich stark davon ausgehe dass der Code von -KD- garantiert so funktioniert... unter Voraussetzung man setzt ihn richtig ein.
    Kompelieren tut er... nur wie immer sehe nichts XD ... wegen weil falsche Bedienung meinerseits.

    Hilfe ^^"

  8. #8
    Hi,

    ich hab den Code nicht ausprobiert. Gut möglich das da was noch nicht funktioniert.

    Zitat Zitat
    In das Array kommen alle Bilder rein die ich anzeigen möchte oder?
    Jap

    Zitat Zitat
    Muss ich das für jede Karte machen? Bis jetzt kam es mir so vor, als würde das der Code für alle schon regeln, glaube aber hier etwas arg falsch verstanden zu haben.
    Nein, das macht es automatisch für alle Karten. Die map Funktion bildet einen Array (oder eine beliebige andere Collection) auf einen neuen Array ab, in dem es eine Funktion auf jedes Element des Arrays ausführt.
    Beispiel: Du hast eine Liste von Zahlen [1,2,3,4,5] und wendest darauf ein map mit der Quadrat-Funktion an. Dann bekommst du eine Liste [1,4,9,16,25] zurück. Vom Code her würde das folgendermaßen aussehen:
    Code:
    zahlen = [1,2,3,4,5]
    # entweder
    quadratzahlen = zahlen.map {|x| x**2 }
    # oder
    quadratzahlen = zahlen.map do |x| 
      x**2 
    end
    
    # das ist exakt dasselbe wie
    quadratzahlen = []
    for zahl in zahlen do
      quadratzahlen << zahl**2
    end
    Ob du geschweifte Klammern oder do...end benutzt ist egal. Was da zwischen den |...| steht sind die Parameter der Funktion, die du map übergibst.

    In dem Beispielcode
    Code:
    # for each card in the game
    @card_sprites = $game_system.memory.get_cards.map do |x, y, image|
      # create a new sprite
      sprite = Sprite.new
      # set its graphic and coordinates
      sprite.bitmap = Cache.picture(image)
      sprite.x, sprite.y = x, y
      # and "return" the sprite into the array
      sprite
    end
    sagst du: Lege einen Array an: für jede Karte, die $game_system.memory.get_cards zurückliefert, erzeuge einen Sprite, setze dessen x und y Koordinaten auf die Koordinaten der Karte, sowie seine Grafik auf die Grafik der Karte. Füge diesen Sprite dann in den Array ein. Setze am Ende die Variable @card_sprites auf diesen Array.

    Der Code ist gleichbedeutend zu
    Code:
    @card_sprites = []
    for x, y, image in $game_system.memory.get_cards do
      # create a new sprite
      sprite = Sprite.new
      # set its graphic and coordinates
      sprite.bitmap = Cache.picture(image)
      sprite.x, sprite.y = x, y
      # and "return" the sprite into the array
      @card_sprites << sprite
    end

    map gehört zu den Iteratorfunktionen (in anderen Sprachen auch Funktoren genannt). Das sind Methoden, die eine Funktion (also ein Stück ausführbaren Code) als Parameter bekommen.

    In meinen Codebeispielen sind noch zwei weitere Iteratorfunktionen: each führt eine Funktion für jedes Element des Arrays aus (ohne dabei aber einen neuen Array zu erzeugen).

    each ist identisch mit der For-Schleife.
    Code:
    zahlen = [1,2,3,4,5]
    zahlen.each do |zahl|
      print zahl
    end
    # ist gleichbedeutend zu
    for zahl in zahlen do
      print zahl
    end
    n.times führt eine Funktion n Mal aus. Sie entspricht einer Zählerschleife in anderen Sprachen.
    Code:
    5.times do
      print "Hallo Welt"
    end
    # ist gleichbedeutend mit
    for i in 1..5 do
      print "Hallo Welt"
    end
    
    # times darf auch die Index-Variable als Parameter bekommen
    5.times do |i|
      puts "dies ist die #{i}te Wiederholung
    end
    # ist gleichbedeutend mit
    for i in 0..4 do
      puts "dies ist die #{i}te Wiederholung
    end
    Das Tutorial ist sehr veraltet und bezieht sich noch auf Ruby 1.8 (und den RPGMaker XP), aber evtl. hilft dir die dortige Erklärung zum Verständnis von Iteratorfunktionen: http://www.rpg-studio.org/scientia/R...2_-_OOP_Teil_2

  9. #9
    Hey ^^

    Ich befinde mich gerade auf Fehlersuche und bin schwerst verwirrt.
    Der scheint nur in die erste Methode einer Klasse zu gehen. Muss ich die anderen Klassen wie in meinem alten Code noch mal alle extra aufrufen?

    Jedenfalls... er geht soweit ich das sehe nur in die Methode "initialize" (immer und immer wieder) und in die Klasse "Game_System", genau einmal.

    Edit:
    Wie ich es im alten Code gemacht habe funktioniert es leider nicht... warum geht der denn nicht in die anderen Methoden rein Oo
    ... oder sehe ich das einfach nur nicht... der müsste mir doch mit:
    Code:
    irgendwas = 99
    p irgendwas
    den Wert von "irgendwas" in der Konsole ausgeben. Egal wo ich mich befinde.

    Geändert von Elster (02.04.2015 um 14:28 Uhr)

  10. #10
    Ja, vermutlich wird die Stelle im Code nicht erreicht. <initialize> wird immer dann aufgerufen, wenn ein neues Objekt der Klasse angelegt wird. Hast du beispielsweise die Klasse Auto und schreibst: auto = Auto.new, dann wird <initialize> von Auto einmal aufgerufen. Die anderen Methoden der Klasse werden dann aufgerufen, wenn du im Code explizit auto.[Name der Methode] schreibst.

  11. #11
    Automatisch geht er in keine Methode rein. Wie Kelven schon gesagt hat: die initialize Methode wird aufgerufen sobald du Klasse.new schreibst.

    Während das Spiel läuft wird ständig SceneManager.scene.main aufgerufen. Dadurch das du SceneManager.call(Memory) geschrieben hast, wird die Klasse Memory als aktive Szene gesetzt und zuerst die initialize Methode und danach die main Methode von Memory aufgerufen.
    Da deine Memory Klasse von Scene_Base erbt, übernimmt sie deren main Methode. Wenn du also wissen willst, was main macht, musst du in die Klasse Scene_Base reinschauen. Dort siehst du, dass main erst die Methode start aufruft, und danach in einer Schleife die Methode update aufruft bis die Scene beendet wird. Danach wird die Methode terminate aufgerufen.

    In der start-Methode hast du dann dein draw_graphic aufgerufen.

    Du müsstest jetzt noch die update Methode überschreiben und dort update_graphics aufrufen, sowie die terminate Methode überschreiben und dort dispose_graphics aufrufen (und wichtig dabei: in den Methoden immer am Anfang das Schlüsselwort super schreiben, damit die gleichnamige Methode der Superklasse Scene_Base aufgerufen wird).

  12. #12
    Also... wenn ich das richtig verstanden habe... muss jetzt bei Scene_Base folgendes tun.

    Code:
    def update
        update_basic
        update_graphics
      end
    Selbiges halt bei "terminate" mit dem anderen Befehl.
    So weit so gut, weiterhin, wenn ich -KD- richtig verstanden habe, jede meiner Methoden mit "super" ausstatten.
    Wobei das nicht für update_graphics und dispose_graphics zu gelten scheint.
    So weit so gut und verstanden... hoffe ich. Oder soll ich "update_basic" rauswerfen O_O (kann ich mir eigentlich nicht vorstellen... das braucht man sicherlich.)

    Weiterhin, wenn ich es richtig verstehe, brauche ich "def start" nicht mehr, oder?

    Sooo... sollte ich nun alles richtig haben, nahezu überall super drin, in terminate und update die beiden Befehle eingefügt... dann kann mir sicher noch wer erklären was dieser Fehler zu bedeuten hat.
    Zitat Zitat
    Script 'Memory' line 135: no MethodError occurred.
    undefined Method `each_with_index' for nil:NilClass
    Diese Meldung taucht sofort beim Starten des Spiels auf. Hab das extra noch mal in ein neues Projekt gepackt um zu schauen ob es mit anderen Scripten Reibereien gibt.
    Aber anscheinend mag er da was gar nicht... was jedoch verstehe ich nicht, soweit ich mir "each_with_index" angeschaut habe, ist es genau für diesen Fall gedacht. Einen hash aus einem Objekt und seinem Index zu bilden. http://apidock.com/ruby/Enumerable/each_with_index
    Habe ich doch bei den "leichten" Schritten was mal wieder falsch verstanden?

  13. #13
    Zitat Zitat
    Also... wenn ich das richtig verstanden habe... muss jetzt bei Scene_Base folgendes tun.
    An Scene_Base solltest du gar nichts verändern. Nur deine Memory Klasse muss geändert werden.

    Schau dir mal dieses Diagramm an: http://www.multimediaxis.de/attachme...1&d=1428157342

    Das zeigt in welcher Reihenfolge die Methoden aufgerufen werden. Die Schreibweise Klasse#methode bedeutet: die Methode ist eine Instanzmethode der jeweiligen Klasse. Die Schreibweise Klasse.methode bedeutet: Die Methode ist eine Klassenmethode (kann also direkt aufgerufen werden, wie SceneManager.call).

    Wenn du eine eigene Scene-Klasse anlegst, die von Scene_Base erbt, kannst du Methoden überschreiben. Das heißt: Schreibst du in deiner Klasse eine update Methode, so wird diese anstelle der update Methode in Scene_Base aufgerufen. Die Methoden in Scene_Base sind aber wichtig, sie sorgen zum Beispiel dafür das Tastatureingaben abgefragt und der Bildschirm neu gezeichnet wird. Aus dem Grund musst du, wann immer du eine Methode von Scene_Base überschreibst, darin super aufrufen. super bedeutet: rufe die Methode der Superklasse (also Scene_Base) auf.

    Beispiel: Du schreibst in deiner Memory Klasse eine update Methode mit dem Inhalt:
    Code:
    def update
      mache_dies
      super
      mache_jenes
    end
    Dann passiert folgendes:
    1. Zuerst wird Memory#mache_dies aufgerufen
    2. Danach wird Scene_Base#update aufgerufen.
    3. Danach wird Memory#mache_jenes aufgerufen

    Wenn du nun in Scene_Base#update schaust, siehst du, dass dort update_basic aufgerufen wird (diese Methode zeichnet den Bildschirm neu und nimmt Tastatureingaben entgegen). Du musst also update_basic nicht selbst aufrufen, wenn du mit super bereits die update Methode der Superklasse aufgerufen hast.

    Zitat Zitat
    Diese Meldung taucht sofort beim Starten des Spiels auf. Hab das extra noch mal in ein neues Projekt gepackt um zu schauen ob es mit anderen Scripten Reibereien gibt.
    Aber anscheinend mag er da was gar nicht...
    Der entscheidende Teil der Fehlermeldung ist for nil:NilClass. Das bedeutet soviel wie: Die Variable, mit der du each_with_index aufrufst, ist leer.

    In meinem Beispiel wäre das die Variable @card_sprites. Dieser Variable wurde noch kein Wert zugewiesen, zu dem Zeitpunkt wo each_with_index aufgerufen wird.

    In meinem Beispiel wird die Variable @card_sprites in der Methode initialize_graphics angelegt. Offenbar rufst du diese Methode nicht auf. Sie sollte innerhalb von start aufgerufen werden.

    Lege also eine Methode Memory#start an, rufe dort mit super die gleichnamige Methode von Scene_Base auf und danach die Methode initialize_graphics.

    Zitat Zitat
    Dwas jedoch verstehe ich nicht, soweit ich mir "each_with_index" angeschaut habe, ist es genau für diesen Fall gedacht. Einen hash aus einem Objekt und seinem Index zu bilden. http://apidock.com/ruby/Enumerable/each_with_index
    Habe ich doch bei den "leichten" Schritten was mal wieder falsch verstanden?
    Mit each_with_index kannst du über eine Collection (z.B. einen Array) iterieren (also eine Schleife bauen), wobei du in jedem Schritt sowohl das jeweilige Element als auch dessen Position/Index bekommst.


    Falls du mit Ojektorientierter Programmierung noch nicht vertraut bist, kannst du dir ja mal diesen Teil des Tutorials durchlesen: http://www.rpg-studio.org/scientia/R...2_-_OOP_Teil_1

    Geändert von -KD- (04.04.2015 um 16:40 Uhr)

  14. #14
    Erneut muss ich mit Kleinigkeiten nerven... langsam tut es mir echt leid...

    Ich habe nun folgende Methoden angelegt:

    Code:
    def start
      super 
      initialize_graphics
    end
    Code:
    def update
      super
      update_graphics
    end
    Code:
    def terminate
      super
      dispose_graphics
    end
    start ist gleich die erste Methode und ich habe sie am Ende von "initialize" aufgerufen, da "initialize" ja nun mal immer zuerst startet.
    Nun habe ich das grandiose Problem, dass sich folgende Fehlermeldung kommt.

    Zitat Zitat
    Script 'Game_Interpreter' line 1411: NoMethodError occurred.
    super: no superclass method `start' for #<Game_Memory:0xe80c074>
    Habe auch aus Frust versucht das in eine Klasse zu stecken, dass sah dann so aus:

    Code:
    class Memory < Scene_Base
      def start
        super 
        initialize_graphics
      end
    end
    Gab dann aber auch nur eine Fehlermeldung:

    Zitat Zitat
    Script 'Game_Interpreter' line 1411: NameError occurred.
    undefined local variable or method `start' for
    #<Game_Memory:0xe294c7c>

    Ich kann mir das gerade nur so erklären, dass ich a) beim Aufruf von start was falsch mache oder die Bedingungen für start nicht stimmen.
    Bin auch nebenher dabei mir das über objekt orientierte Programmierung durchzulesen (weiß ich eigentlich alles... aber ich kann auch alles falsch verstanden haben.)
    Irgendwo in meinen Gedankengängen scheint echt der Wurm drin zu sein...

    PS -KD- : Der erste Link geht nicht.

  15. #15
    Der erste Fehler kommt daher, dass super in diesem Fall versucht, die Methode start von der übergeordneten Klasse aufzurufen, die hier anscheinend Game_Memory ist. Wenn ich alles richtig verstanden hab, soll aber deine Klasse Memory von Scene_Base erben, also ist class Memory < Scene_Base eigentlich richtig. Der zweite Fehler kommt dann her, dass jemand anderes trotzdem noch versucht, start vom Game_Memory aufzurufen.

  16. #16
    Zitat Zitat
    start ist gleich die erste Methode und ich habe sie am Ende von "initialize" aufgerufen, da "initialize" ja nun mal immer zuerst startet.
    "start" - und auch alle anderen Methoden, die am Ablauf der Szene beteiligt sind, also "update", "terminate", "perform_transition" etc. - müssen von dir gar nicht selbst aufgerufen werden, darum kümmert sich der SceneManager eigentständig, wenn du ihm mittels SceneManager.call oder SceneManager.goto sagst, dass jetzt ein Szenenwechsel stattfinden soll.

  17. #17
    Zitat Zitat von Elster Beitrag anzeigen
    PS -KD- : Der erste Link geht nicht.
    Das ist ja echt ärgerlich. Hab irgendwie noch nicht gerafft wie man Bilder an den eigenen Post anhängt. Hab ein Diagramm hochgeladen, aber das wurde danach prompt von der Forensoftware gelöscht.

    Egal, dann eben in Textform:

    Was ich mit dem Diagramm eigentlich zeigen wollte, ist welche Methoden in welcher Reihenfolge aufgerufen werden. Das ist in einem fertigen Spiel nicht immer so leicht herauszufinden und erschwert natürlich die Fehlersuche, wenn dir gar nicht klar ist, warum welche Methode wann aufgerufen wird.

    Das ganze Spiel beginnt im "Main" Script mit der Zeile
    Code:
    rgss_main { SceneManager.run }
    rgss_main ist eine Funktion der RGSS die sagt: Führe den Codeblock einmal aus. Drückt der Spieler dabei die F12 Taste, wird der Codeblock von neuem ausgeführt (ergo, das Spiel neugestartet). Ist also erstmal nicht so wichtig. Wichtig ist: SceneManager.run wird ausgeführt.

    Als nächstes guckst du also was SceneManager.run macht.
    Code:
    module SceneManager
      # ...
      def self.run
        DataManager.init
        Audio.setup_midi if use_midi?
        @scene = first_scene_class.new
        @scene.main while @scene
      end
    end
    Okay, SceneManager.run ruft zuerst DataManager.init auf. Die Definition dazu findest du im Script "DataManager". Kurz zusammengefasst: DataManager.init liest die Datenbank des Makers ein (die Datenbank sind alle Einstellungsmöglichkeiten die du im Maker hast, wenn du F9 drückst, z.B. Helden, Monster, Items etc.). Danach werden alle Game-Objekte angelegt. Kleiner Exkurs: Alle Game-Objekte haben einen Klassennamen der mit Game_ anfängt. Sie enthalten den aktuellen Zustand des Spiels. Du kannst dir leicht merken: Alles was in einen Spielstand abgespeichert werden muss (was beim Neuladen also wieder verfügbar sein muss) ist Teil eines Game-Objektes. Denn nur Game-Objekte werden gespeichert. Dem gegenüber gibt es Daten-Objekte. Daten-Objekte fangen alle mit RPG:: an, z.B. RPG::Actor. Sie enthalten die statischen, unveränderlichen Inhalte, die du im Maker definiert hast. Sie müssen nicht im Spielstand abgespeichert werden, weil sie konstant für alle Spielstände sind. Kleines Beispiel: RPG::Actor enthält für jedes Level die zugehörigen Lebenspunkte. Game_Actor enthält die tatsächlichen Lebenspunkte des Helden, mit Inbegriffen also auch Lebenspunkte die man durch Trinken eines Zaubertranks o.ä. erhält. RPG::Actor enthält den Namen des Helden in der Datenbank. Game_Actor enthält den tatsächlichen Namen des Heldens (der sich im Spiel z.B. durch Umbenennung ändern kann). Darum macht es Sinn für dein Minispiel eine Klasse Game_Memory anzulegen, die die veränderlichen Zustände deines Memory-Spiels enthält (welche Karten liegen auf dem Tisch, welche Karten wurden gezogen, wie viele Punkte hat der Spieler usw.).

    Zurück zum Spielfluss: Nach dem Aufruf von DataManager.init wird mit
    Code:
    @scene = first_scene_class.new
    die erste Scene angelegt und in die Variable @scene gespeichert. first_scene_class ist eine Methode, die die Klasse zurückgibt mit deren Scene das Spiel beginnen soll (z.B. Scene_Title). @scene ist eine Variable, welche die aktuelle Scene des Spiels beinhaltet.

    Danach kommt
    Code:
    @scene.main while @scene
    Achtung: Das ist eine Schleife. Die Methode @scene.main wird jetzt solange ausgeführt solange die Variable @scene nicht nil ist. An diesem Punkt befinden wir uns in der Hauptschleife des Spiels. Jetzt wird immer @scene.main aufgerufen, bis das Spiel beendet wird. Das Beenden des Spiels geschieht durch den Aufruf von SceneManager.exit. Wenn du in die Methodendefinition guckst, siehst du, dass diese Methode einfach die Variable @scene auf nil setzt (und damit die Schleifenbedingung verletzt, wodurch die Schleife abbricht).

    Jede Scene-Klasse im Spiel erbt von Scene_Base. Wenn du wissen willst was @scene.main macht schaust du also am besten erstmal dort hinein:

    Code:
    class Scene_Base
      # ...
      def main
        start
        post_start
        update until scene_changing?
        pre_terminate
        terminate
      end
      # ...
    end
    Zuerst wird Scene_Base#start aufgerufen. Danach Scene_Base#post_start. Dann kommt wieder eine Schleife: Solange die Hauptscene nicht geändert wird (du also nicht SceneManager.call oder SceneManager.exit aufrufst) wird die Methode Scene_Base#update aufgerufen. Wird die Scene beendet, so werden pre_terminate und terminate_aufgerufen.

    Was hat es mit dem start und post_start bzw. pre_terminate und terminate auf sich? Hier geht es darum einen Übergang zwischen zwei Scenen zu erzeugen. Wenn du z.B. von der Map ins Menü wechselst, so geht das nicht abrupt, sondern die Map wird langsam ausgeblendet und das Menü wird langsam eingeblendet. start zeichnet den neuen Bildschirm der neuen Scene. post_start erzeugt den Übergang. Wenn du post_start überschreibst und eigenen Code einfügst, so wird dieser erst ausgeführt, nachdem die Scene eingeblendet wurde. Alles was in start steht wird ausgeführt, bevor die Scene eingeblendet wird. Dasselbe gilt für pre_terminate und terminate. In terminate wird der Bildschirm eingrefroren, so dass die nächste Scene gezeichnet werden kann. Alles was in pre_terminate reinkommt, wird noch sichtbar für den Spieler bevor die Scene ausgeblendet wird.
    In der Regel brauchst du post_start und pre_terminate nicht.

    Zuletzt noch update: update ruft erstmal nur update_basic auf. update_basic zeichnet den Bildschirm neu und fragt Tastatureingaben ab. update_basic brauchst du nicht überschreiben. In der Regel überschreibst du update und rufst als allererstes super auf um Scene_Base#update aufrufen (die dann update_basic aufruft).

    Nochmal zusammengefasst:
    1. Spiel startet mit SceneManager.run
    2. Dieser ruft in einer Schleife immer wieder @scene.main auf
    3. Diese führt start aus um sich zu initialisieren
    4. und danach update in einer Schleife (solange die Scene existiert) auf
    5. wird die Scene beendet ruft sie vorher noch terminate auf

    Schreibst du eine eigene Scene so überschreibst du 3 Methoden: start, update und terminate. Alle drei überschriebenen Methoden sollten als allerersten Aufruf ein super enthalten, um die gleichnamige Methode der Superklasse aufzurufen. Eine Scene sollte den Ablauf eines Scriptes koordinieren. Sie regelt im Grunde genommen drei Elemente: Das Zeichnen aller Grafiken, Abspielen von Soundeffekten/Musik und das Abfragen von Tastatureingaben. Wird der grafische Teil sehr komplex, lagert man ihn in der Regel nochmal in eine eigene Klasse aus.
    Die Spieldaten und Spielmechanik schreibt man in eine eigene Klasse. In der Regel nennt man sie Game_XYZ, z.B. Game_Memory. Hier kommt alles rein was einen Zustand deines Scriptes darstellt, der in einem Spielstand abgespeichert werden muss. In einem Memory-Spiel wären das: die Karten auf dem Spielbrett, die Karten auf der Hand des Spielers. Eine Instanz dieser Klasse packt man dann in eine bestehende Game_XYZ Klasse, z.B. Game_System. Danach kann man darauf z.B. mit $game_system.memory zugreifen.

    Ich weiß nicht wie dein Code gegenwärtig aussieht. Aber ich vermute mal das dein Problem noch darin liegt zu erkennen, welcher Code in Game_Memory und welcher in Scene_Memory gehört (du nennst letztere Memory, aber es ist besser eine Scene Klasse mit dem Prefix Scene_ anfangen zu lassen).

  18. #18
    Ein wenig entwirren konnte ich bis jetzt das Ganze.... ok ein ganz klein wenig.
    Ich hatte noch den alten Code wo stehen, so dass ich Klassen doppelt hatte, womit das Script versucht hat die Klasse Memory aus meinem alten Code zu starten.
    Beeindruckender Weise hat das irgendwann funktioniert wodurch ich diesen Fehler erst realisiert habe o_o
    Mittlerweile habe die Klasse auch unbenannt...

    Nun nachdem ich diesen Fehler weg habe, hänge ich wieder.
    Und zwar hänge ich am Methodenaufruf.

    Beispiel:
    Code:
    A)
    class Scene_Memory < Scene_Base
      def start
        super
        initialize_graphics
      end
    end
    
    B)
    class Scene_Memory < Scene_Base
       def self.start
          super
          initialize_graphics
       end
    end
    Wenn ich nun in der Klasse Game_Memory, in der Methode initialize am Ende folgenden Befehl aufrufe "SceneManager.call(Scene_Memory.start)" wird ja aus der Klasse "Scene_Memory" die Methode "start" aufgerufen. Ja... und hier komme ich zu meinem Knackpunkt. Bei A) gilt die Methode als nicht initialisiert, bei B) kann ich kein super darauf anwenden, da nun start von Scene_Memory erbt. Dafür komme ich in die Methode rein, nützt mir nur nicht viel, da nun die Methode "get_cards" die in "initialize_graphics" aufgerufen wird, nicht initialisiert ist oder leer ist.

    Ich habe in der Methode initialize schon mit verschiedensten Aufrufen versucht an die Methode start zu kommen. Unter anderem "SceneManager.call(Scene_Memory.start.new)" was auch geht... nur eben mit den selben Problemen. Auch ein einfacher Aufruf aller "start" oder "Scene_Memory.start" bringt mich in die selbe Lage.
    Mein Versuch einfach "SceneManager.call(Scene_Memory)" aufzurufen ... lief darauf hinaus, dass er nicht in die Methode rein ging... habe auch nichts anderes erwartet.

    Ich poste hier einfach noch mal Alles rein, großartige Änderungen zum Code von -KD- gibt es noch nicht, ich will erstmal das es so weit läuft. Klar... im Nachhinein andere Sachen einbauen ist nie die klügste Idee... aber wenn es nicht läuft ist es auch doof groß dran herumzuschrauben.

    Bei dieser Variante des Codes handelt es sich um jene, wo er keine Daten in get_cards findet.

    Code:
    class Game_Memory
      # hier kommen alle Attribute rein die dein Spiel so hat
      @modus = 0
      @move = 50
      
      # filenames of the pictures of your cards
      attr_accessor :figure_names
    
      def initialize
        @figure_names = ["Spinne1.png", "Spinne2.png", "Spinne3.png", "Spinne4.png", 
        "Spinne5.png",
        "Spinne6.png", "Spinne7.png", "Spinne8.png", "Spinne9.png", "Spinne10.png", 
        "Spinne11.png",
        "Spinne12.png", "Spinne13.png", "Spinne14.png", "Spinne15.png", "Spinne16.png"]
        
        @positions = [
        0, 0, 
        136, 0, 
        272, 0, 
        408, 0,
        #
        0, 104, 
        136, 104, 
        272, 104, 
        408, 104,
        #
        0, 208, 
        136, 208, 
        272, 208, 
        408, 208,
        #
        0, 312, 
        136, 312, 
        272, 312, 
        408, 312
        ]
        # number of cards horizontal
        @max_number_of_cols = 4 
        # size of cards
        @card_width = 64
        @card_height = 64
        # distance between cards
        @margin = 12
        p @positions
        SceneManager.call(Scene_Memory.start.new)
        #Scene_Memory.start
        #SceneManager.call(Scene_Memory.start)
      end
    
      # returns x, y coordinates as well as the image name of
      # the card with the given index
      def get_card index
        [card_x(index), card_y(index), card_image(index)]
      end
    
      # return all cards
      def get_cards
        # create a new array with elements
        # for all indizes from 0 upto @positions.size
        (0...@positions.size).map do |index|
          # each element contains the result value of
          # get_card
          get_card index
          end
      end
      
      # x coordinate for a given card index
      def card_x index
        col_num = index % @max_number_of_cols
        col_num * (@card_width + @margin)
      end
      
      # y coordinate for a given card index
      def card_y index
        row_num = index / @max_number_of_cols
        row_num * (@card_height+@margin)
      end
      
      # filename of card image
      def card_image index
         @figure_names[@positions[index]]
      end
      
      # number of different figures/cards
      def number_of_pictures
        @figure_names.size
      end
       
      # add 2 cards for each figure into the field
      # shuffle the positions of all cards
      def shuffle_cards
        @positions.clear
        # this loop is invoked as often as the number
        # of different cards
        number_of_pictures.times do |picture_id|
          # for each invocation, two cards are added
          # into the array 
          @positions << picture_id << picture_id
        end
        # shuffle the array at the end
        @positions.shuffle!
      end
      
    end
    
    class Game_System
      # füge Memory als Attribut hinzu
      attr_accessor :memory
    end
    
    def initialize_graphics
      # for each card in the game
      @card_sprites = $game_system.memory.get_cards.map do |x, y, image|
        # create a new sprite
        sprite = Sprite.new
        # set its graphic and coordinates
        sprite.bitmap = Cache.picture(image)
        sprite.x, sprite.y = x, y
        # and "return" the sprite into the array
        sprite
      end
    end
    
    def update_graphics
      # update attributes of all sprites
      @card_sprites.each_with_index do |sprite, index|
        x, y, image = $game_system.memory.get_card(index)
        sprite.bitmap = Cache.picture(image)
        sprite.x, sprite.y = x,y
      end
    end
    
    def dispose_graphics
      @card_sprites.each do |sprite|
        sprite.dispose
      end
    end
    
    # Erbebt von Scene_Base
    class Scene_Memory < Scene_Base
      #class << self 
    #-------------------------------------------------------------------------------
    # Überschreibt start von Scene_Base
    #-------------------------------------------------------------------------------
      def self.start
        #super
        initialize_graphics
        update
      end
      
    #-------------------------------------------------------------------------------
    # überschreibt  terminate Scene_Base
    #-------------------------------------------------------------------------------
      def terminate
        super
        dispose_graphics
      end
      
    #-------------------------------------------------------------------------------
    # überschreibt update Scene_Base
    #-------------------------------------------------------------------------------
      def update
        super
        update_graphics
      end
    
    #end
    end
    #end
    Die Fehlermeldung lautet um genau zu sein:
    Zitat Zitat
    Script 'Game_Interpreter' line 1144: NoMethodError occurred.
    undefined method `get_cards' for nil:NilClass
    Ergo wurde wohl wieder etwas noch nicht aufgerufen, wodurch ich noch nicht an die Daten komme.
    Der Methode zufolge sollte es sich hierbei ja um get_card und den index davon handeln.
    Jedoch kann das so wie es da ist, sowieso noch nicht stimmen, immerhin kann ich kein "super" ausführen.
    Wie merkt meine Klasse, dass die Methode da ist, ohne das ich self.start schreiben muss?
    Das würde dann hoffentlich auch die Folgeprobleme beheben...

  19. #19
    Zitat Zitat
    Code:
    B)
    class Scene_Memory < Scene_Base
       def self.start
          super
          initialize_graphics
       end
    end
    Wenn du self.xxx bei einer Methodendefinition schreibst, wird die Methode zur Klassenmethode (du kannst sie also über Klassenname.methodenname aufrufen). Klassenmethoden können ihrerseits keine Instanzmethoden aufrufen, sie beziehen sich nur auf die Klasse. Klassenmethoden braucht man eher selten. In deinem Fall brauchst du sie jedenfalls gar nicht. Also weg mit den self.

    Zitat Zitat
    Code:
    class Game_Memory
      # hier kommen alle Attribute rein die dein Spiel so hat
      @modus = 0
      @move = 50
    Dieser Code macht was völlig anderes als du wahrscheinlich vermutest. Instanzvariablen, die du in den Klassenblock schreibst, werden zu Klassenvariablen (die du dann innerhalb einer Klassenmethode nutzen kannst). Das ist eigentlich NIE das was du willst. Daher gleich abgewöhnen! Instanzvariablen schreibst du in die Initialize-Methode rein.

    Zitat Zitat
    Code:
    p @positions
        SceneManager.call(Scene_Memory.start.new)
        #Scene_Memory.start
        #SceneManager.call(Scene_Memory.start)
    Das hat nichts in der initialize Methode zu suchen. Wenn du deine Memory-Szene starten willst, mache das entweder über ein Event im Spiel (mit dem Call Script Befehl). Oder, wenn du willst das das Spiel direkt mit dem Memory-Spiel beginnt, du schreibst
    Code:
    module SceneManager
      # hier ist das self. ausnahmsweise mal erlaubt...
      def self.first_scene_class
        Scene_Memory
      end
    end
    Das Problem warum dein Code nicht funktioniert ist, dass die Methoden initialize_graphics, update_graphics und dispose_graphics nicht in der Scene_Memory Klasse stehen. Du hast sie einfach lose in den Scripteditor eingefügt.

  20. #20
    Entschudige bitte -KD- das ich hier so lange geschwiegen habe ^^" Mein Rechner hat den Geist aufgegeben... teilweise -.-
    Danke so weit für deine großartige Hilfe ^^

    Ich hab mit hier noch mal das Meiste durchgelesen um mit meinem jetzigen Problem klar zu kommen.
    Habe brav die Methoden in die Klasse ingepflegt und "start" ganz nach unten gepackt. Mir Videos zu Programmierung mit Ruby im Verbindung mit dem VX Ace angeschaut (speziell zu Verbung) und aaaaah ... ich glaube ich scheitere am Aufruf.

    Code:
    $game_system.memory = Game_Memory.new
    Ist ja der Code mit dem ich über Event -> Script halt Game_Memory starte.

    So und mit:
    Code:
    SceneManager.call(Scene_Memory)
    sollte ich rein theoretisch doch Scene_Memory starten können oder?

    Also im Prinziep sollte es insgesammt wie folgt aussehen.
    In einem Event mit dem Script Befehl folgendes ausführen:
    Code:
    $game_system.memory = Game_Memory.new
    SceneManager.call(Scene_Memory)
    Joar... Game_Memory wird dann auch einmal gestartet... was dann passiert verwundert mich jedoch etwas.
    Folgende Fehlermeldung taucht dann auf:
    Zitat Zitat
    Script 'Game_Interpreter' line 1411: NoMethodError occurred.
    undefined method `memory='for nil:NilClass
    Was natürlich auch noch sein kann ist, dass er meint in der Klasse stünde nichts drin.
    Bedeutet ich müsste vermutlich am Ende der Klasse "start" aufrufen.
    Also wie folgt:
    Code:
    b = Scene_Memory.new
    b.start
    Wobei er sich dann über folgenden Codeteil beschwert.
    Code:
     @card_sprites = $game_system.memory.get_cards.map do |x, y, image|
    Da kommt dann folgende Fehlermeldung.
    Code:
    Script 'Memory_3' line 118: NoMethodError occurred.
    undefined method `memory' for nil:NilClass
    memory scheint aus der Klasse Game_System zu kommen.

    Code:
    class Game_System
      # füge Memory als Attribut hinzu
      attr_accessor :memory
    end
    muss ich das auch noch irgendwie starten und wenn ja wo?

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •