Zahlen im Array ablegen und wieder leeren

  • GM 6

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Zahlen im Array ablegen und wieder leeren

    Hi,

    ich hab mal wieder ein Problemchen und komme nicht weiter.

    Im Prinzip geht es um folgendes:

    Ich erstelle ein Array im Create Event:

    GML-Quellcode

    1. global.selected=0
    2. //erstelle array
    3. for (i=0;i<=4;i+=1)
    4. {
    5. for (j=0;j<=4;j+=1)
    6. {
    7. global.units[i,j]=0
    8. }
    9. }
    10. //setze alarm
    11. alarm[0] = 30
    Alles anzeigen


    Im Alarm will ich nun die Zahlen die von global.selected random 0-25 erstellt werden ins Array schicken. Mit einer Besonderheit. Jede Array Variable darf nicht größer als 1 sein.

    GML-Quellcode

    1. //setze random global.selected
    2. global.selected = floor(random(25));
    3. //übergebe global.selected anzahl an array <- hier komm ich nicht weiter!!!
    4. global.unit[i,j]=1//<- keine ahnung wie ich es ins array bekomme
    5. //restarte alarm
    6. alarm[0] = 30;


    Zu guter letzt die Ausgabe via DrawEvent:

    GML-Quellcode

    1. draw_text(150,10,string(global.selected));//<-für mich nur zur info
    2. //zeichne array
    3. for (i=0;i<=4;i+=1)
    4. {
    5. for (j=0;j<=4;j+=1)
    6. {
    7. draw_text(10+i*16,10+j*16,string(global.units[i,j]));
    8. }
    9. }


    Aussehen tut es im Moment so:
    00000
    00000
    00000
    00000
    00000
    Wenn nun von global.selected beispielsweise 4 ausgewählt wird, möchte ich, das es so aussieht:
    11110
    00000
    ..usw.

    Wenn global.selected = 0 ist, sollten sich dann auch alle Array Variablen auf 0 setzen können.

    Ich hoffe ich hab mich verständlich genug ausgedrückt und finde hier Hilfe.

    Vielen Dank schonmal im Vorraus.
    Es gibt viel zu tun, packen wir´s an !!!
    Für Rechtschreibfehler sind die verantwortlich, die sie entdecken :P.
  • RE: Zahlen im Array ablegen und wieder leeren

    Hallo Black-Mask

    Black-Mask schrieb:

    Im Alarm will ich nun die Zahlen die von global.selected random 0-25 erstellt werden ins Array schicken. Mit einer Besonderheit. Jede Array Variable darf nicht größer als 1 sein.

    GML-Quellcode

    1. //setze random global.selected
    2. global.selected = floor(random(25));
    3. //übergebe global.selected anzahl an array <- hier komm ich nicht weiter!!!
    4. global.unit[i,j]=1//<- keine ahnung wie ich es ins array bekomme
    5. //restarte alarm
    6. alarm[0] = 30;
    Kleiner fehler nebenbei: Du willst das global.selected zwischen 0-25 sein kann, dafür musst du

    GML-Quellcode

    1. global.selected = floor(random(26))

    schreiben, denn
    random(x) Returns a random real number between 0 and x. The number is always smaller than x.

    aus der Game Maker Hilfe
    Zu der Stelle wo du nicht weiter kommst:

    GML-Quellcode

    1. //setze random global.selected
    2. global.selected = floor(random(26));
    3. // i = Spalten -
    4. // j = Reihen |
    5. // Wenn global.selected 12 ist, so prüfe ob
    6. // Reihe 0 * 5 (da eine Spalte 5 Zellen hat)
    7. // + 0 < 12 ist
    8. // 0+0 < 12 = true => units = 1
    9. // Spalte 3 in der 2 Reihe, also:
    10. // 0 0 0 0 0
    11. // 0 0 x 0 0
    12. // So rechne: 2*5+3 < 12 = false => units = 0
    13. for (i = 0; i <= 4; i += 1)
    14. for (j = 0; j <= 4; j += 1)
    15. if j*5+i < global.selected
    16. then global.units[i,j] = 1;
    17. else global.units[i,j] = 0;
    18. //restarte alarm
    19. alarm[0] = 30;
    Alles anzeigen


    Kleiner Tipp noch von mir, was ich dir auf jedenfall empfehlen würde, auch wenn es jeder selber wissen muss:
    Es wäre sehr ratsam meines erachtens nach, wenn man grundsätzlich alle Schleifenvariablen mit den Wort "var" deklariert. Dies hat den Vorteil, das anderes als bei normaler Deklaration, die Schleifenvariable nur für diese "Piece of Code" Aktion Lebt, und danach sozusagen "stirbt". Dies kann oftmals Fehler vorbeugen, und man verbraucht weniger Speicher.

    Spoiler anzeigen
    Sometimes you want variables only within the current piece of code or script. In this way you avoid wasting memory and you are sure there is no naming conflict. It is also faster than using global variables. To achieve this you must declare the variables at the beginning of the piece of code using the keyword var.

    aus der Game Maker Hilfe


    So genug der Worte.

    Gruß,
    Mokuyobi
    木曜日 (Mokuyōbi)
  • Hi Mokuyobi,

    erstmal vielen Dank an dich für die gute Erklärung und Aufklärung.
    Das mit random(x) hab ich nun "endlich" auch verstanden :) .

    Zu der var-Deklarierung muss ich sagen, das wusste ich bisher nicht. Denn ich dachte eigentlich, dass i und j eh nur für den jeweiligen Code-Schnipsel gelten, und beim löschen bzw. Nichtgebrauch der Instanz automatisch wieder freigegeben/gelöscht werden. Was ja bei globalen variablen nicht passieren soll, damit ich sie anderweitig weiter verwenden kann. Oder seh ich da was falsch? Ich werde dennoch versuchen das in Zukunft zu berücksichtigen.

    Ich hatte gestern bzw. heut morgen noch soviel versucht und dachte mir schon, dass ich das über noch eine weitere for-schleife machen muss, aber die "Formel" wollte mir einfach nicht einfallen. Da muss ich noch etwas üben schätze ich.

    Nochmals ein großes Danke an dich :thumbsup:

    Gruß BM
    Es gibt viel zu tun, packen wir´s an !!!
    Für Rechtschreibfehler sind die verantwortlich, die sie entdecken :P.
  • Lebensdauer und Gültigkeitsbereich von Variablen

    Hallo Black-Mask,
    ich wollte dich nochmal schnell genauer über Variablen Deklaration aufklären. Ich möchte dazu gerne aus einem sehr guten C++ Buch Zitieren, das an dieser Stelle zwei wichtige Wörter
    erläutert:
    Ein wichtiger
    Punkt wurde bisher ausgeklammert: der Gültigkeitsbereich und die Lebensdauer von Variablen. Lebensdauer heißt hier, wie lange eine Variable überhaupt existiert. Der Gültigkeitsbereich bestimmt, ob auf eine Variable während ihrer Existenz zugegriffen werden kann, man spricht von ihrer Sichtbarkeit.

    aus "C++ Objektorientiertes Programmieren von Anfang an" von Helmut Erlenkötter, Seite 85, Abschnitt 3.3.3. Gültigkeitsbereich und Lebensdauer
    Der Game Maker kennt beide Begriffe. Ob der Programmierer sie kennt ist etwas anderes ;)
    Beide Bereiche werden von der Deklaration der Variable bestimmt, also ob sie ohne Schlüsselwort, mit var/local, oder mit global./globalvar.

    Globale Variable:

    GML-Quellcode

    1. globalvar i; // Deklaration
    2. global.i = 10; // Deklaration mit Initialisierung
    3. global.i; // Zugriff

    Eine globale Variable lebt das ganze Spiel lang, bist zum beenden des Spiels. Der Gültigkeitsbereich ist sozusagen "überalle", denn jede Instanz eines jeden Objektes kann auf sie zugreifen.

    Objekt-Variablen

    GML-Quellcode

    1. i = 10; // Deklaration nur mit Initialisierung möglich
    2. i; self.i; objectname.i; id.i; // Zugriffsmöglichkeiten

    Eine Objekt-Variable lebt nur für die Instanz des Objektes, und ihr Speicher wird Freigegeben wenn die Instanz zerstört wird. Somit kann (fast) nur die Instanz des Objektes selber auf diese Variable zugreifen. Außnamen gibt es aber, man kann während ihrer Existenz auch außerhalb auf sie zugreifen, sie also für andere Instanzen anderer Objekte sichtbar machen, indem man "objektname." Vorschreibt. Dies ändert in jeder Instanz von dem Objekt die Variable. Mit der ID kann man eine einzelne Instanz ansprechen, um nicht von jedem Objekt die Objekt-Variable zu verändern. Bei einer Kollision kann man das Schlüsselwort "other." nehmen, um auf die Variablen zuzugreifen. Was es mit self.i auf sich hat, kommt nun bei den Lokalen Variablen (man könnte jedoch theoretisch jede Variable mit "id.x" aufrufen, oder "self.x" jedoch ist einfach nur "x" viel kürzer und hat den gleichen Effekt ^^)

    Lokale Variablen

    GML-Quellcode

    1. var i; // Deklaration
    2. local.i = 10; // Deklaration mit Initialisierung
    3. i; // Zugriff

    Eine lokale Variable lebt nur für den "Piece of Code" oder den Skript, indem sie Deklariert wird. der Gültigkeitsbereich ist damit auch sehr klein: nur für diesen Code. Vorteile bringt es jedoch dadurch, das es den Speicher nach gebrauch sofort wieder Freigibt. Zugreifen kann man auf eine lokale Variable erstmal wie bei ganz normalen Objekt Variablen, indem man einfach nur "i" oder "x" beispielsweiße schreibt. Sollte nun der Falle sein das das Create Event so aussieht:

    Irgendein Create Event:

    GML-Quellcode

    1. // Deklariere meine Objekt Variablen mit Default Werten
    2. xyz = 100;


    und mein Room Start Event sieht so aus:

    GML-Quellcode

    1. // Gebe xyz aus
    2. show_message(string(xyz));
    3. // Mache aus Spaß einfach eine lokale Variable mit gleichen Namen
    4. local.xyz = 200;
    5. // Gebe den Wert von xyz aus
    6. show_message(string(xyz));
    7. // Gebe den Wert von id.xyz / self.xyz aus
    8. show_message(string(id.xyz)+"/"+string(self.xyz));


    Was würde passieren?
    Es gibt drei Möglichkeiten:
    1.) Nichts - Es kommt eine Error Meldung da zweimal eine Variable xyz genannt wurde, und wie oben steht kann auf lokale Variablen wie auf Objektvariablen einfach per Name zugegriffen werden. Der Game Maker hat einen Namenskonflikt und beendet das ganze lieber.
    2.) Die Ausgabe würde lauten: 100, 200, 100/100
    3.) Die Ausgabe würde lauten: 100, 200, 200/200

    Spoiler anzeigen
    Richtig ist Antwort 2!

    Doch warum?
    Das ganze Spielt mit dem Gültigkeitsbereich zusammen, eine Variable ist sichtbar und unsichtbar für andere Teile des Codes, je nachdem wie ihr Gültigkeitsbereich erschaffen ist. Die Objektvariable xyz ist im ganzen Objekt gültig. Man kann sich dafür auf ein Blatt papier beispielsweiße einen großen Kreis zeichnen. Dann wird nur im Room Start Event eine lokale Variable deklariert und initialisiert, aber deswegen ist dieLebensdauer der Objektvariable nicht zuende, sie wird nur unsichtbar! Die lokale Variable kann ein kleinerer Kreis in mitten dieses großen Kreises sein. Für diesen Piece of Code in Room Start wird standartmäßig also immer nur der kleinere Kreis benutzt, da er nur dort Gültig ist, die Objektvariable aber für das ganze Objekt, somit muss für diesen Pice of Code wohl die lokale Variable wichtiger sein. Natürlich kann man nicht einfach die Objektvariable löschen, den großen Kreis radieren, man baut einfach eine Schutzmauer auf (kleiner Kreis) und so wird die Objektvariable unsichtbar. Um diese für diesen Piece of Code sichtbar zumachen, muss man den Game Maker sagen, das man auf die Objektvariable zugreifen möchte, indem man self. oder id. benutzt. Da die Zugriffsmöglichkeiten nur der Objektvariable zustehen, erkennt der Game Maker auf welche der beiden Variablen man zugreifen möchte. Wenn man einfach nur per Name aufruft, was beide können, nimmt der Game Maker die
    Variable mit der geringeren Lebensdauer, da sie in diesem Teil wichtiger ist, und somit die andere Objektvariable für ihn unsichtbar wird.

    Oh man, soviel wollte ich gar nicht schreiben, ich glaube habe mich auch einige male wiederholt. Kann da nur hoffen das jemand das ganze auch liest sonst war ja alles umsonst :rolleyes:

    Gruß,
    Mokuyobi
    木曜日 (Mokuyōbi)
  • Hi Mokuyobi,

    ich hab natürlich alles gelesen ;) .
    Aber mir stellt sich noch immer die Frage, warum ich var i; deklarieren muss. Ich tu dieses doch in der for-Schleife (i=0;...).

    Das verwirrt mich dann doch noch etwas :P

    Gruß BM
    Es gibt viel zu tun, packen wir´s an !!!
    Für Rechtschreibfehler sind die verantwortlich, die sie entdecken :P.
  • Du musst es nicht machen, es ist nur ein kleiner Tipp. Natürlich zwingt dich der Game Maker anfangs die Variable zu initialisieren (anderes als in C++) aber es gibt ja auch nicht nur die for Schleife ;) (do . . .until). Ich wollte dich nur drauf aufmerksam machen, wenn du gut damit klar kommst, sagt ja nichts dagegen :).
    Bei zwei kleinen Zahlen sollte der reservierte Speicher auch nur so gering sein, das heutige PC´s diesen mit sicherheit so gut wie nicht merken, auch wenn mehrere Instanzen des Objektes vorhanden sind.

    Gruß,
    Mokuyobi
    木曜日 (Mokuyōbi)
  • Okay,

    ich versuch mir das zu merken, und es zukünftig einzubauen. Ich bin ja eh noch Anfänger was das Programmieren betrifft und habe von Speicherauslastung bezüglich Variablen und Co. keine Ahnung :P .

    Hab allerdings nochmal eine Frage zu meinem Array. Funktioniert das auch mit Instanzen von Objekten die ich an einem Grid in selbiger Reihenfolge ausrichten möchte (allerdings dann im StepEvent)? Also das ich global.selected selbst bestimme(durch markieren) und dann wenn ich einen Mausklick mache, diese Instanzen sich an der geklickten Stelle ausrichten?

    Gruß BM
    Es gibt viel zu tun, packen wir´s an !!!
    Für Rechtschreibfehler sind die verantwortlich, die sie entdecken :P.
  • Das ist um etwas schwerer, da der Instanz gesagt werden muss, welche Position einnehmen soll, und diese auch Absolut frei ist.

    Da ich nur den Game Maker 8 besitze, kann ich dir keine Game Maker 6 Datei geben, und in diesem Thread wurde das Ganze schonmal besprochen, anscheind gab es dabei ein Problem mit den Game Maker 7, wie gesagt habe nur den GM8. Ob das ganze mit den GM6 funktionieren wird, ist fraglich.
    Allerdings hat Mapman auch ein Lösungsweg der Funktionieren sollte, im Forum mit GML-Tags geschrieben, der für Anfänger sicher einfacher ist. Solltest dir einfach mal angucken ;)

    Gruß,
    Mokuyobi
    木曜日 (Mokuyōbi)
  • RE: Lebensdauer und Gültigkeitsbereich von Variablen

    Mokuyobi schrieb:

    GML-Quellcode

    1. globalvar i; // Deklaration
    2. global.i = 10; // Deklaration mit Initialisierung
    3. global.i; // Zugriff
    Mmmmmhhhhhhhhhmmmmm..... nicht ganz richtig. Funktioniert, ja, aber ich glaube du hast was falsch verstanden.
    global und local solltest du als einfach Spezialinstanzen ansehen. globalvar und var verändern nur die Bedeutung der Variablennamen innerhalb eines Skriptes:

    GML-Quellcode

    1. obj_spieler.x = 42;
    2. global.test = 3;
    3. show_message(string(obj_spieler)); // ID von obj_spieler.
    4. show_message(string(global)); // ID von global.
    5. show_message(string(local)); // ID von local.
    6. // Das kannst du mit allen Spezialinstanzen machen, wie self, all und noone.
    7. (-5).test = 4; // Hihi.
    8. globalvar test;
    9. // Wenn du jetzt test verwendest, greifst
    10. // du eigentlich auf global.test zu:
    11. show_message(string(test)); // Gibt 4 aus.
    12. // Das gleiche gilt fuer local/var:
    13. local.test = 3;
    14. var test;
    15. test *= 2;
    16. with (obj_spieler) { // Normale Instanzvariablen wären hier drinnen nicht verfügbar.
    17. show_message(string(test)); // Gibt 6 aus.
    18. }
    Alles anzeigen

    Der Unterschied ist wahrscheinlich selbstverständlich. Globale Variablen sind überall verfügbar und lokale nur innerhalb von einem Stück Code bzw. Skript. Mit lokale meine ich hier ausnahmsweiße nicht die Instanzvariablen.

    EDIT: Okay, nicht ganz richtig. Die Bedeutung einer Variable mit globalvar zu verändern ist permanent. So kannst du globale Variablen überall verfügbar machen, ohne jedes mal global. davor zu schreiben. Sollte dich an lives, score etc. erinnern, die sind auch einmalig.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von copyboy ()