Ich versuche gerade mein Konstrukt im Kopf zu entwirren...
Also jetzt wo ich da alles so schön bei sammen habe, rufe ich ja die Klasse "Memory_Picture_Changer" auf, um dort eben die Bilder zu aktualisieren. Leider habe ich dort weder die Namen noch die IDs zur Verfügung welche ich mitlerweile in der Klasse "Memory_Game_Navigate" relativ einfach herraussuchen kann. Wäre es nicht an und für sich logischer das in einem Rutsch zu erledigen, oder ist es besser das in verschiedenen Klassen zu lassen?
So wie ich es nun gedacht habe, also mit getrennten Klassen, stolpere ich wiedermal darüber, dass ich an Werte von Variablen rankommen muss (@pic_ID1 und @pic_ID2). Um dann die Werte der beiden Variablen wieder auf -1 und -2 zu setzen wenn ich kein Paar gefunden habe und sie an "Memory_Game_Navigate" senden muss. (für mich als Anfänger klingt das nach viel böser Arbeit...)
Hinzukommt... das ich eh "update_graphics()" aufrufe um mein Array zu aktualisieren, wobei ich mich da auch gerade frage... arbeite ich da überhaupt auf dem "richtigen" Array? So wie ich das bis jetzt verstanden habe, würde das Array der Methode nicht die Bohne verstehen was ich eigentlich von ihm will und einfach das ausgeben, was es eh schon die ganze Zeit über hatte, unverändert versteht sich.
Ich hab ja auch mit dem Gedanken gespielt einfach "Memory_Picture_Changer" von "Memory_Game_Navigate" erben zu lassen, dann sollte ich ja an die aktuellen Werte rankommen.... dachte ich. Hilft mir leider auch nicht dabei weiter, wie ich "Memory_Game_Navigate" sage, dass die beiden Variablen nun wieder ihre Ursprungswerte haben.
Kann jemand meinen armen Kopf entwirren?
Momentan sieht das Ganze wie folgt aus:
(Klar, das wirft noch Fehler wenn man was anklickt, weil Variablen in der Klasse "Memory_Picture_Changer" fehlen.)
Bin gerade nicht so fit, deshalb habe ich deinen Text nur kurz überflogen. Ich hoffe, ich habe es richtig gelesen.
Die @pic-Variablen setzt du zwar in der Navigate Klasse, brauchst die dort aber praktisch gar nicht, wenn ich das richtig überflogen habe.
Wie wäre es, wenn du die ID einfach übergibst? Du könntest deine "change_card"-Methode anpassen:
Die Methode rufst du dann in deiner Navigate-Klasse so auf:
Edit:
Bezüglich der Klassen:
Du kannst tatsächlich auf weniger Klassen zugreifen. Generell ist es ein guter Gedanke, Dinge in einzelne Klassen zu packen. Der Maker macht es ja auch so:
Für einzelne Ausgaben gibt es Window_Klassen. Für die Steuerung über diese Menüs dann die Scene_Klassen.
Wenn du allerdings an einen Punkt kommst, an dem du nicht mehr weiter kommst, du permanent Werte hin- und herschieben musst und jegliche Übersicht verlierst, solltest du vielleicht ein bisschen weniger auslagern.
Hm ne, ich denke nicht dass das so geht.
Ich habe dann ja am Anfang der Methode (pID1 und pID2) in denen "nil" drin steht, wodurch das Programm abschmieren wird. (Habe es auch ausprobiert, dass Programm schmiert ab)
Zudem hast du recht, ich brauche in meiner "Memory_Game_Navigate" Klasse die pic_ID1 und pic_ID2 nicht, ermittel sie jedoch dort um sie an "Memory_Picture_Changer" zu senden um dort mit den Werten arbeiten zu können.
Ergo... müsste ich dann nicht auch einen Aufruf aller:
machen, damit ich mit den aktuellen Werten in "Memory_Picture_Changer" arbeiten kann?
Weil ich brauche ja dort die Werte.
Edit:
hum, er schmiert ab... unschön. "wrong number of arguments" ... habs mir wohl leichter gedacht als es ist....
Edit2:
Gut, hätte es mir denken können, ich arbeite ja nun nur mit "nil"... weil ja nirgends irgendwo etwas drin steht. Bedeutet, ich müsste es einmal mit den -Werten in Navigate anlegen und mir dann eine Variable anlegen, die ich erhöhe wenn ich Werte in pic_ID1 und pic_ID2 stehen habe.
Dann arbeite ich mit einer if-Abrage um mir am Anfang die Minuswerte wieder zu holen... und setze die Variable wieder auf 0 oder so...
Irgendwie kommt es mir so vor als hätte ich noch einen Denkfehler darin.
Sicher, dass es nicht ging? In der Intial-Methode hast du @pic_ID1 und @pic_ID2 auf Minuswerte gesetzt (hier dein Code):
Dadurch sind die Variablen ja erst einmal gesetzt.
Nun rufst du die Changer-Methode "change_card" auf, und übergibst ja die IDs. Dementsprechend sind diese Variablen nicht nil. Sicher, dass es dewesegen abgeschmiert ist? Wenn ich mir deinen Code anschaue, sind dort einige andere Fehler drin, die das Programm zum Abschmieren bringen können (update_graphics() rufst du im change_card auf, obwohl diese Methode gar nicht der Klasse Pic_Changer bekannt ist....).
Welche Fehlermeldung hast du erhalten, als du versucht hast die Werte zu übergeben? Gib mir mal den Code davon, dann schaue ich mir das heute nach der Arbeit mal an.
Edit:
Noch einmal kurz als Erklärung. Du ermittelst in Klasse A die Variablen ID1 und ID2 und brauchst diese in Klasse B. Wenn du von Klasse A aus die Klasse B aufrufst (in deinem Fall die MEthode change_pic), macht es dann sinn, die Variablen an dieser Stelle zu übergeben. Daher rufst du von deiner Klasse aus die "change_pic" Methode mit den Variablen auf (change_pic(ID1,ID2)). Und nicht umgekehrt.
Zu dem Aufruf. Sollte der dann nicht eigentlich so aussehen?
Weil change_card gibt ja @pID1 und pID2 zurück, oder sind die Bezeichner der Variablen in so fern irrelevant und Ruby weiß schon was es tun soll?
Wobei ich andere Fehler je nach Variante bekomme...
Wenn ich [@pic_ID1,@pic_ID2 = @pic_changer.change_card(@pic_ID1,@pic_ID2)] nutze, dann bleibt oben links in der Ecke mein Mauszeiger kleben... zumindest Einer. Einen anderen kann ich munter über die Karten bewegen.
Klicke ich dann etwas an, findet er in Zeile 423 einen Fehler (Wrong number of arguments (0 for 2)).
Das wäre dann der Befehl "@pic_changer.change_card()" in der Methode "def navigate".
Wenn ich [@pic_ID1,@pic_ID2 = @pic_changer.change_card(@pID1,@pID2)] nutze, dann bekomme ich eine mja... gravierendere Fehlermeldung.
"line288 type error occurred. no implicit conversion from nil to integer".
Dabei handelt es sich dann um die Zeile "@c = f_names[pID1]" aus der Methode "change_card". Kann natürlich mit einem vorher falsch ausgeführten Befehl zusammen hängen.
Momentan sieht der Code wie folgt aus:
Sorry dass der Code erst jetzt kommt
Ich esse jetzt gleich erst einmal und bin noch was unterwegs, schaue mir das aber später noch an und editiere es hier rein. Erst einmal zur ersten Zeile vorab:
Beim Aufruf einer Methode, übergibst du nicht die Variable an sich, sondern den Wert, den sie besitzt. Beispiel:
Das ist bei Methoden mit Rückgabenwerte auch so. Es ist "egal", wie die Variablen in der aufrufenden Methode heißen.
Edit:
Was mir direkt aufgefallen ist,du hast anstelle einer Init-Methode deine ganzen Befehle in die navigae Methode gehauen. D.h, immer wenn die Methode aufgerufen wird, erstellst du neue Game_Memory, Memory_Picture_Changer Objekte. Das sieht falsch aus. Pack das mal in eine Init-Methode. Ich kann es aber wie gesagt später noch korrigieren, wenn ich die Zeit dafür habe.
Edit2:
So, gerade fertig gegessen. So sollte deine Navigate Klasse dann mit den Korrekturen aussehen (warum du plötzlich in allen Methoden Objekte der "Memory_Klasse" anlegst, habe ich übrigens nicht verstanden):
Danke für die schönen Änderungen in meiner Klasse Linkey :3
@Edit 2:
Öhm... teilweise zum herumprobieren. Zudem muss ich ja zumindest in der Methode "change_card" auf die Methode "update_graphics" zugreifen, welche in Game_Memory liegt.
Mag sein das da wieder ein Denkfehler meinerseits vorhanden ist.
Mjoar, hm, aber was ich gerade wirklich nicht verstehe ist ein Fehler in folgender Zeile:
Da soll jetzt irgndwo was "nil" sein, also irgendwo herrscht gähnende Leere... ich sehe aber rein gar nichts, dass hier leer sein könnte.
Zitat
undifined method `map!' for nil:NilClass
...
Was ich mir noch vorstellen könnte wäre, dass das Programm nicht so ganz mit "map" klar kommt.
Dann stellt sich aber bei mir die Frage, wie überschreibe ich denn dann die Einträge in dem Array?
@f_wrapper selbst ist nil. In deiner Methode "navigate" sehe ich eigentlich auch nur eine lokale Variable f_wrapper, also ohne @. Wo kommt denn der Aufruf, der im Code-Block steht?
Wie Kelven schon sagt, setzt du die Variable als lokale Variable (ohne @) hier:
f_wrapper sollte funktionieren - @f_wrapper ist nicht deklariert, also nil.
Bezüglich des mehrfachen anlegens von Game_Memory:
Die Game_Memory-Klasse sollte exakt ein Objekt für das Spiel verwenden (zumal du in Game_Memory dein Array mischst. Dadurch hat ja jede neuangelegte Instanz der Klasse ein anderes Array).
Du hast ja das erstellte Game_Memory Objekt bereits global im Zugriff:
$game_system.memory
D.h. wenn du nun die Update-Methode von Game_Memory verwenden willst, kannst du es wie folgt machen:
Noch was. Das "flatter" sollte vermutlich flatten heißen? Außer du hast irgendwo eine Methode "flatter" für die Array-Klasse geschrieben, dann passt es.
--
"Banjo, you're a BEAR... and I will teach you... THESE MOVES!"
@Cepanks
jab, meinte "flattern" ... kommt davon wenn man in den Weiten des Internets sucht und halbwegs richtige Lösungen für sein Problem findet ^^
@Linkey
Ich habe das mal an den entsprechenden Stellen eingefügt, jetzt mosert aber das Programm herum, dass die Methode nicht für Game_Memory definiert sei.
Liegt vermutlich daran, dass update_graphics in der Klasse "Scene_Memory" liegt.
Dann geht der Code wohl so nicht und ich müsste ein neues Objekt von Scene_Memory anlegen... oder?
super, habe kurz noch einmal auf dein Coding geschaut. Du brauchst die update_graphic-Aufrufe gar nicht.Deine Scene_Memory wird ja permanent geupdated. Und in der Update-Methode hast du folgendes:
Du rufst update_graphics also permanent auf. Es ist also nicht nötig, diese Methode noch mehrmals aufzurufen, wenn diese eh schon permanent aufgerufen wird.
Nimm den Befehl aus deinen anderen Klassen daher ganz raus.
Edit:
Kurz noch einmal drüber geflogen, dein Rückgabewert in der navigate-Methode ist nicht nötig. Du gibst dort "id1 und id2" zurück, was keinen sinn macht. Die Methode wird ja von der Scene_Memory über die Update-Methode aufgerufen.
Was du aus performance Gründen noch eventuell machen könntest, dass du von der Navigate-Methode ein "true" zurückgibst, wenn Input: aktiviert wurde und die Methode an sonsten ein false zurück gibt (die letzten Zeilen der Navigate Methode sollten dann ungefähr so aussehen:
Dann könntest du in der Scene_Memory Update-Methode folgendes machen:
Dadurch wird update_graphics nur ausgeführt, wenn Enter gedrückt wurde. Die Kartenbilder müssen ja nicht jede Sekunde geupdated werden, sondern nur bei Änderungen, welche ja eigentlich nur bei "Enter" geschehen können.
Gut, sieht schon mal besser aus, danke.
Nur... wenn ich etwas anklicke, habe ich wieder den zweiten Mauszeiger, oben links in der Ecke.
Auch wird das Bild an der Koordinate nicht geändert.
ebenso dachte ich, ich würde schon abfangen, dass man Karten nicht doppelt anklicken kann =/
Gut, sollte eigentlich auch mit:
funktionieren... nur werden eben die Karten im Array nicht geändert...
Eigentlich sollten das doch folgende Codezeilen hinbekommen oder?
Was mir auch noch Sorgen bereitet, das Memory findet Paare nicht. Nur wenn ich zwei mal auf die selbe Stelle klicke, meint es ich hätte was passendes gefunden, dabei sollte es doch gleiche Kartennamen erkennen.
Wenn... ich mir aber meinen Code anschaue.... oh mist.... ich arbeite mit den IDs bezüglich der Paarfindung... dann kann das natürlich nicht gehen.
Also haut meine Werte Abfrage...
... tatsächlich nur dann hin... wenn ich zweimal auf die selbe Stelle klicke... (warum ist mir das nicht eher aufgefallen? *facepalm*)
Hab ich auch mal einen Fehler gefunden..... und tatsächlich beseitigt bekommen O_O
Naja aber die anderen bereiten mir echt Kopfzerbrechen...
Momentan sieht der Code im Ganzen so aus und... läuft auch... nur eben mit "n" Mauszeigern und keiner Bildanpassung.
das Problem mit den mehrfachen Zeigern, du erstellst - unnötig - ein Objekt der Navigate Klasse direkt in der change Methode. Diese musst du rausnehmen:
Edit:
So, habe mir den Rest mal schnell überflogen. Folgendes Problem hast du noch in deiner change_pic Methode:
Die folgende Zeile:
Geht über das Array und prüft dann jedes Element auf "pID1". Die Elemente sind aber alle "Grundkarte.png" und daher ist die Abfrage nie richtig.
Richtig lautet es wie folgt:
Durch den Zusatz "with_index" wird der Index der Position des Arrays mit gegeben. Diese wird durch die Variable "i" dann im Befehl festgehalten und du prüft dann pID1 auf i. So klappt es dann, dass pID mit der Array-Position verglichen wird.
Das musst du in den anderen ".map!"-Verwendungen in der Change_Pic-Methode so anpassen.