Komplexe Abfrage einfach machen

  • GM 8
  • Komplexe Abfrage einfach machen

    Das Leben könnte so einfach sein, wären da nicht die komplexen Wünsche. :P

    Mein Raumschiff kann bis zu 9 Waffen haben, die man zwischen zwei Missionen in einem Shop kaufen kann. Waffe 1 hat das Raumschiff von Anfang an, die 8 weiteren KANN man sich kaufen, muss man aber nicht.

    Im Prinzip ist es einfach. Aktuell kann man mit Ctrl schießen und mit den Zahlen 1-9 schaltet man die Waffen durch. Ob die Waffe da ist, wird durch eine globale Variable geprüft.

    Nun will ich dem Spieler die Möglichkeit geben, mit Alt durch die Waffen zu schalten. Ist Waffe 1 aktiv und der Spieler drückt die Alt(e)-Taste, wird auf die Waffe 2 umgeschaltet, wenn sie vorhanden ist. Und genau das ist das Problem. Bei jeder Umschaltung muss geprüft werden, welche Waffe aktiv ist und welche Waffen der Spieler noch hat, um auf die nächste in der Reihe umzuschalten.

    Es kann also sein, dass der Spieler mit Waffe 2 spielt, umschaltet, Waffe 3 und 4 nicht vorhanden sind und dann die Waffe 5 kommt. Folgt man der Logik, ergibt das sehr lange, sehr komplexe if-Abfragen. Gibt es dafür auch eine einfachere Methode?
  • DU must eine schleife machen.

    ca

    GML-Quellcode

    1. var i=0
    2. do
    3. {
    4. //aktion
    5. i+=1
    6. }
    7. until(i<9)


    Der Knack punkt ist aber das du jedes mal eine andere Variablen testen willst. Hier geht es zu einem link wo ich etwas änliches mal gefragt habe
    Forums Thread--->

    Du must also in jeder Abfrage aus der Variable i, die für deinen Waffenslot steht, eine neuen Variable mit "execute_String bilden.
    Ich bin darin auch nicht der Experte aber ich glaube das war so


    vari = "global.weapon"+string(i)
    vari = execute_string("return("+vari+")");
    wenn waffen 1 geprüft wird müste aus der nun die Variable "global.weapon1" gebildet worden sein

    und du kannst nun in der schleife von oben das abfragen
    und wenn es zutrifft. kommt glaube ich noch ein "exit rein damit die schleife beendet wird.
    i muss dann natürlich beim start auf deinen aktuellen Waffenslot gestellt werden, damit es dort anfängt zu zählen.

    GML-Quellcode

    1. i=0 //oder aktuelle waffe
    2. var vari;
    3. do
    4. {
    5. vari = "global.weapon"+string(i)
    6. vari = execute_string("return("+vari+")");
    7. if vari>0 then //prüft als ob die eben, oben gebildet variabel "global.weapon(i) besetzt ist. ja oder nein (1 oder 0)
    8. {
    9. //deine aktion
    10. exit; // das exit beendet ,glaube ich die schleife das deine bedingung ja gefunden wurde.
    11. }
    12. else i+=1
    13. }
    14. until(i<9)
    Alles anzeigen


    Bestimmt sind hier noch fehler drin aber das ist der ansatz wie es gehen müst. Bei exeute_string muss ich auch immer erst testen bis ich es raus habe
    Meine Signatur hat kein Visum für das GM Forum erhalten.
  • Danke für deine ausführliche Antwort.

    Schleifen also. Au man, dass war noch nie meine Stärke, aber ich habe es befürchtet. 8|

    Edit: So, ich habe noch ein wenig über das Problem gegrübelt. Theoretisch gibt es 362.880 Kombinationsmöglichkeiten. Für if-Abfragen wäre das etwas viel, also komme ich nicht um eine Schleife, auch wenn ich damit (noch) nicht wirklich klar komme.

    Auch um das Problem selber besser verstehen zu können, rolle ich das Problem an der Stelle ausführlicher auf.

    Es gibt 9 Waffen, jede Waffe hat eine Variablen die aus sagt, ob der Spieler die Waffe besitzt, eine andere Variable (waffe) sagt aus, welche Waffe gerade gebraucht wird (Zahl von 1 bis 9). Durch das Drücken auf die Alt-Taste sollen die Waffen, welche der Spieler besitzt, durch geschaltet werden können. Also von 1 bis 9, wenn die Waffe 9 erreicht ist und man drückt noch einmal drauf, kommt die Waffe 1.

    Auf Knopfdruck muss also überprüft werden, welche Waffe der Spieler gerade benutzt. Anschließend wird eine Waffe hoch gezählt und geschaut, ob er die Waffe besitzt. Wenn ja, wird diese ausgewählt, wenn nein, wird weiter hoch gezählt. Besitzt er außer der aktuellen Waffe keine andere mehr, wird der Vorgang abgebrochen oder gar nicht erst durchgeführt.

    Die Variablen lauten global.waffe1 bis global.waffe9 und waffe. Wie bereits geschrieben, global brauche ich (true/false) um zu sagen, ob der Spieler die Waffe besitzt. Mit "waffe" wird nur die Nummer der Waffe durchgegeben, die benutzt wird.

    Jetzt sollte es um den Code gehen, aber da stehe ich absolut auf dem Schlauch. For? While? Do? Until? Bahnhof?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Yamm () aus folgendem Grund: Ergänzungen

  • Also ich würde die Waffen in ein Array reinpacken und dann folgendes, von mir aus dem Kopf verfasstes Skript verwenden:

    GML-Quellcode

    1. //
    2. // arrayFindNext(
    3. // string <array to go over>,
    4. // int [index to start],
    5. // int [index to end],
    6. // int [min value],
    7. // int [max value],
    8. // bool [allow to restart from beginning]
    9. // );
    10. //
    11. var size, index_end, i;
    12. while (variable_local_array_get(argument0, size))
    13. size += 1;
    14. index_end = argument[2];
    15. if (index_end > size || !index_end)
    16. index_end = size;
    17. for (i = argument[1]; i < index_end; i += 1)
    18. if (variable_local_array_get(argument0, i) >= argument[3])
    19. if (variable_local_array_get(argument0, i) <= argument[4] || !argument[4])
    20. return i;
    21. if (argument[5])
    22. arrayFindNext(argument0, 0, argument[1], argument[3], argument[4], false);
    Alles anzeigen


    Kurz gesagt, es iteriert alle Werte in deinem Array durch und checkt obs die Statements erfüllt. Es gibt dann den nächsteren Index der diese erfüllt zurück.
    Wenn Erkärung erwünscht, einfach nachfragen. ^^
  • Ich versuche es dir Schritt für Schritt zu erklären.

    GML-Quellcode

    1. var size, index_end, i;

    Dies deklariert die Variablen size, index_end und i lokal in unserem Skript.

    GML-Quellcode

    1. while (variable_local_array_get(argument0, size))
    2. size += 1;

    Als nächstes erfassen wir mit dieser einfachen while Schleife die Größe des mitgegebenen Arrays. Die Variable size wird dabei hochgezählt, bis im Aufruf unseres Arrays kein Wert mehr (false) zurückgegeben wird.

    GML-Quellcode

    1. index_end = argument[2];
    2. if (index_end > size || !index_end)
    3. index_end = size;

    Da alle Parameter, ausgenommen das zu überprüfende Array optional sind, setzt dieses Statement die Variable index_end entweder direkt auf unseren Parameter oder im Falle eines ungültigen, oder nicht angegebenen Parameters auf das maximale zugreifbare Index unseres Arrays, also size.

    GML-Quellcode

    1. for (i = argument[1]; i < index_end; i += 1)
    2. if (variable_local_array_get(argument0, i) >= argument[3])
    3. if (variable_local_array_get(argument0, i) <= argument[4] || !argument[4])
    4. return i;

    Hier läuft das "Durchsuchen" unseres Arrays ab. Es überprüft nacheinander alle beinhaltenden Werte unseres Arrays und gibt bei Fund einfach den zutreffenden Index zurück.

    GML-Quellcode

    1. if (argument[5])
    2. arrayFindNext(argument0, 0, argument[1], argument[3], argument[4], false);

    Wenn man will, das bei keinem Fund auch am Anfang mit der Suche begonnen werden kann, ruft dies mit den passenden Parametern das eigene Skript rekursiv auf.


    Anwenden könnte man das ganze zum Beispiel in deinem Falle derartig:

    GML-Quellcode

    1. // waffe enthält die Einsen (verfügbaren Waffen) und Nullen
    2. next_weapon = arrayFindNext('waffe', actual_weapon, false, false, false, true);

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

  • Ist garnicht so schwer:
    global.waffe[0]=1;
    global.waffe[1]=0;
    global.waffe[2]=0;
    global.waffe[3]=1;

    global.aktiveWaffe=0;

    Stell dir vor, diese Variablen sind deine Waffen. 0 Bedeutet, du hast sie nicht gekauft. 1 bedeutet, du hast sie gekauft und kannst sie einsetzen.
    In diesem Beispiel hast du Waffe[0] und Waffe[3] gekauft.

    AktiveWaffe ist eine Variable, die sir sagen soll, welche der Waffen du ausgewählt hast. 0 bedeutet, waffe[0] wurde ausgewählt.
    Mit dem drücken der Alttaste könntest du folgendes schreiben:

    GML-Quellcode

    1. if (keyboard_check_pressed(vk_alt))
    2. {
    3. global.vorherigeWaffe=global.aktiveWaffe;
    4. for (i=global.aktiveWaffe; i<4; i+=1)
    5. {
    6. if (global.waffe[i]==1) //ist waffe[i] gekauft worden...
    7. {
    8. global.aktiveWaffe=i; //...wähle die Waffe aus (vorherigeWaffe und aktiveWaffe unterscheiden sich nun)
    9. break;
    10. }
    11. }
    12. if (global.vorherigeWaffe==global.aktiveWaffe) //Ist die erste Schleife durchgelaufen und vorherigeWaffe und aktiveWaffe sind immernoch gleich,...
    13. {
    14. for (a=0; a<4; a+=1)
    15. {
    16. if (global.waffe[a]==1) //...fang bei 0 an zu suchen und finde die nächste freie waffe
    17. {
    18. global.aktiveWaffe=a;
    19. break;
    20. }
    21. }
    22. }
    23. }
    Alles anzeigen

    Dieser Code fängt beim Knopfdruck der Alt-Taste an, deine Waffen nach der nächsten bereits gekauften Waffe zu schauen und wählt diese aus. Ist er beim durchsuchen am Ende deiner Waffen angekommen und hat keine Waffe gefunden, fängt er noch einmal bei 0 an zu suchen. Die zweite Schleife ist dafür da, dass wenn du die letzte Waffe ausgewählt hast, beim Druck der Alt-Taste auf die nächste freie Waffe am Anfang kommst.
    Ich hoffe ich konnte dir damit helfen

    "Make love, not Warcraft"

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von HuRr!cAnE ()

  • Danke an alle für die Hilfe, besonders luky300, welcher bei meinen PNs sehr geduldig war. Jetzt funktioniert es perfekt und die Lösung möchte ich hier zeigen. Wie gesagt, die Waffen kann man in einem Shop zwischen den Missionen kaufen, also habe ich mich dazu entschlossen einige Variablen Global zu machen. Im Shop wird dann auch festgelegt, welche Waffen funktionieren und welche nicht. Bei 9 Waffen sieht es im Shop dann so aus:

    Create
    Spoiler anzeigen

    GML-Quellcode

    1. global.waffen_anzahl = 9; // Die Quantität der verschiedenen Waffentypen festlegen
    2. global.waffen_aktuell = 1; // Die Zahl des aktuellen Waffentyps festlegen
    3. // Welche Waffe ist an, welche aus?
    4. // Werte im Array "global.waffe" festlegen
    5. global.waffe[0] = true;
    6. global.waffe[1] = true;
    7. global.waffe[2] = true;
    8. global.waffe[3] = true;
    9. global.waffe[4] = false;
    10. global.waffe[5] = false;
    11. global.waffe[6] = false;
    12. global.waffe[7] = false;
    13. global.waffe[8] = false;
    Alles anzeigen


    Im Objekt meines Raumschiffs braucht es dann nur noch beim drücken der Alt-Taste folgenden Code:
    Spoiler anzeigen

    GML-Quellcode

    1. var i;
    2. for (i = 0; i < global.waffen_anzahl; i+=1)
    3. {
    4. if (variable_global_array_get('waffe', (global.waffen_aktuell + i) mod global.waffen_anzahl))
    5. {
    6. global.waffen_aktuell = ((global.waffen_aktuell + i) mod global.waffen_anzahl) + 1;
    7. break;
    8. }
    9. }


    Geschossen wird bei mir mit Ctrl. Dort wird schlicht abgefragt, welchen Wert "global.waffen_aktuell" hat und dann mit der entsprechenden Waffe geschossen.

    Außerdem kann man bei mir auch mit den Tasten 1 bis 9 die Waffen gezielt umschalten. Auch wenn der Code hier einfach ist, möchte ich ihn zur Vervollständigung hier rein stellen.

    Spoiler anzeigen
    Beispiel Taste 1:

    GML-Quellcode

    1. if global.waffe[0] = true{
    2. global.waffen_aktuell = 1;
    3. }


    Also, noch einmal Danke. Jetzt kann das Waffendesign weiter gehen. :thumbsup: