Schon wieder eine If Then Schaltung

Es gibt 22 Antworten in diesem Thema, welches 2.321 mal aufgerufen wurde. Der letzte Beitrag (7. Februar 2024 um 00:28) ist von 1570.

  • Hallo Leute,

    allmählich wirds es wirklich Blöd wieder so eine Frage in den Raum zu werfen. Wo ist mein Verstand nur geblieben

    Ich wollte folgende Schaltung realisieren im Basic:

    Nach drücken des Feuerknopf erhält der Sprite ein neues aussehen.

    Und wenn ich wieder auf den Feuerknopf drücke verwandelt sich der Sprite in sein ursprüngliche Version zurück.

    Jo habe ich mir gedacht baust einen Schalter ein und über prüfst ihn mit einer If then Schleife

    In etwa so. Ich benutze hier jetzt nur mal Variabeln um zu sehen wie sich die Schalter verhalten

    Also ich weis das diese Schaltung nicht funktioniert.

    Mein Problem ist, das solang ich auf den Feuerknopf drücker J% immer 128 ist. Also stimmt irgend eine der If then Abfrage immer. Somit springt mein Sprite ständig hin und her.

    Eigentlich möchte ich ja nur wenn ich den Feuerknopf drücke oder auch gedrückt halte, er immer nur eine die If then Abfrage durchläuft.

    Ich zerbreche mir den Kopf schon seit Sonntag früh darüber. Es kann doch nicht so schwer sein das Umzusetzen. Gibt ja genügend Spiele wo das auch so ist.

    AHHHHHHHHHHH :motz:

  • Lassen wir mal außen vor, daß das keine Schaltung und "If-then-Else" eine Verzweigung und keine Schleife ist, aber wenn die erste IF-THEN-ELSE-Konstruktion die Variabe A auf 1 setzt, dann setzt die zweite sie sofort wieder auf 1 zurück. In einer vernünftigen Programmiersprache müßte das zweite IF in den ELSE-Block des ersten.

    [EDIT]

    Habe mal kurz ins Basic.Handbuch des Mega65 geschaut und (im Gegensatz zum C64-Basic) kann man anscheinend Blöcke nach IF bzw. ELSE durch BEGIN und BEND erzeugen.

  • Du hast mehrere Möglichkeiten. Wie @Bitte melde dich an, um diesen Link zu sehen. schon gesagt hat, pack das zweite IF in das ELSE des ersten (wenn das geht).

    Oder überspringe das 2. IF, wenn das erste wahr ist, also sowas wie

    Code
    50 IF J%=128 AND A%=2 THEN A%=1:GOTO 200
    55 IF J%=128 AND A%=1 THEN A%=2

    Oder (die fiese...), setze J% im erste IF um, also sowas:

    Code
    50 IF J%=128 AND A%=2 THEN A%=1:J%=0
    55 IF J%=128 AND A%=1 THEN A%=2

    oder nimm ein (Haupt-)IF und mach sowas:

    Code
    50 IF J%=128 THEN A%=A%+1:IF A%=3 THEN A%=1

    Oder...oder...oder...

    Edit: Was immer du machst, nenne IF-THEN nicht "Schleife". Wann immer jemand das tut, stirbt ein Kätzchen...:D

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

  • Oder mit nur einem IF:

    Code
    IF J%=128 THEN A%=-2*(A%=1)-(A%=2)


    ...aber für sowas gehört man dann auch schon ein bisschen geschlagen...:haue:

    Ich wollte nur mal zeigen, dass auch das ginge. Es ginge auch komplett ohne IF, aber das spare ich mir jetzt mal...

    Edit: Bit Shifter Variante unten ist schöner...:D

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

    Einmal editiert, zuletzt von EgonOlsen71 (5. Februar 2024 um 16:41)

  • Wenn ich nochmal so auf deinen komplette Code gucke, wird dir das alles vermutlich nicht helfen, weil du dann immer noch einen ständigen Wechsel zwischen A%=1 und A%=2 drin hast, solange du den Feuerknopf gedrückt hältst. Ich nehme an, ein "Klick" soll einmal die Richtung ändern und erst der nächste soll die wieder umkehren? Dann brauchst du noch zusätzliche Logik, die z.B. die Abfrage(n) überspringt, solange du den Knopf nicht wieder loslässt.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

  • Wenn ich nochmal so auf deinen komplette Code gucke, wird dir das alles vermutlich nicht helfen, weil du dann immer noch einen ständigen Wechsel zwischen A%=1 und A%=2 drin hast, solange du den Feuerknopf gedrückt hältst. Ich nehme an, ein "Klick" soll einmal die Richtung ändern und erst der nächste soll die wieder umkehren? Dann brauchst du noch zusätzliche Logik, die z.B. die Abfrage(n) überspringt, solange du den Knopf nicht wieder loslässt.

    Korrekt,

    Du hast mein mein Dilemma erkannt

    Und an alle hier:

    Ich werde nie mehr ein If then Block als Schleife bezeichen. :facepalm:

    Ich werde aber eure Tipps durchgehen. Ich sah da einiges woran ich nicht gedacht habe.

  • Sieht in pseudocode so aus.

    if PRESSED

    then

        if a = 1

            a = 2

       else

            a = 1

    endif

    Oder ohne if/else

    if PRESSED

    then

       a = 3 -a

    endif

    Da du deine beiden Abfragen direkt hintereinander geschrieben hast ist die Chance dass beim zweiten IF der Knopf immer noch gedrückt ist recht hoch, also wird die Variable gleich wieder zurückgesetzt.

    Alternativ müsstest du eine Schleife machen, und diesemal wirklich eine Schleife, die darauf wartet dass der Feuerknopf nicht mehr gedrückt ist. Ob du das willst hängt davon ab was du genau machen willst.

  • Leider besitze das Mega65 Basic so einen Befehl nicht womit ich prüfen könnte ob eine Taste gedrückt ist. Da wünsche ich mir wirklich ein MS-VB.

    Gibt es event. Alternavien zu diesen Befehl Pressed :gruebel

    Wie oben beschrieben wollte ich mit dem Feuerknopf ein Art An- Auschalter erstellen.

    z.B der Sprite zieht mit dem Feuerknopf eine Waffe und wenn ich dann wieder auf den Feuerknopf drücke, wird die Waffe wieder zurück gesteckt.

    Hört sich wirklich banal an. Aber wenn man dann über den Programmcode sitzt, ist es dann nicht mehr so einfach.

    Meine Alternative wäre dann, das ich das mit einen Taste löse. Das hemmt aber den Spielfluß,

    Es wird sicherlich ein Lösung gefunden, muß nur noch ein wenig Suchen.

  • Gibt es event. Alternavien zu diesen Befehl Pressed :gruebel

    Für Joystickabfragen eignet sich der JOY-Befehl ganz gut:

    Bitte melde dich an, um diesen Anhang zu sehen.


    Hier mal ein kurzes Beispiel:

    Zeile 10 fragt ab, ob der Feuerknopf vom Joystick in Port 2 gedrückt ist und weist den Zustand entsprechend der Variablen FB% (z.B. "firebutton2_pressed" :) ) zu: FB% = 0 / FALSE falls nicht gedrückt, -1 / TRUE, falls gedrückt.

    Danach reicht ein einfaches IF FB% THEN ... als "PRESSED-Ersatz" aus.

    Bitte melde dich an, um diesen Anhang zu sehen.

  • Leider besitze das Mega65 Basic so einen Befehl nicht womit ich prüfen könnte ob eine Taste gedrückt ist. Da wünsche ich mir wirklich ein MS-VB.

    Gibt es event. Alternavien zu diesen Befehl Pressed :gruebel

    Es gibt keinen Befehl "PRESSED". Wie ich ja geschrieben habe ist das Pseudocode, weil es ja eher darum ging deine IF Abfrage zu formulieren. Das PRESSED steht also stellvertretend für deine Bedingung wie du feststellst ob ein Knopf gedrückt wurde. Das kann ein PEEK() sein oder auch irgendwas anderes. Und in denem Code hattest du ja dieses "IF J%=128" was ja wohl dein PRESSED darstellt, oder?

    Da ich mich mit den Details im BASIC nicht auskenne weiss ich nicht wie man das am M65 am Besten macht, aber das ist für die IF Abfrage auch nicht wesentlich, weil du ja wissen wolltest warum deine Abfrage nicht richtig funktioniert.

    Übrigens solltest du den Feuerknopf nicht mit X=128 abfragen, denn das bedeutet dass die Abfrage nur dann funktioniert wenn NUR der Feuerknopf gedrückt wurde. Es sei denn du willst das so. Wenn du den Joystick in irgendeine Richtung bewegst UND den Feuerknopf gedrückt hältst dann funktioniert es nicht mehr. Du musst Bit 7 ausmaskieren "F = JOY(x) AND 128" oder so wie Snoopy das gemacht hat "IF J > 127".

  • Zeile 10 fragt ab, ob der Feuerknopf vom Joystick in Port 2 gedrückt ist und weist den Zustand entsprechend der Variablen FB% (z.B. "firebutton2_pressed" :) ) zu: FB% = 0 / FALSE falls nicht gedrückt, -1 / TRUE, falls gedrückt.

    Wie kann der Wert hier -1 werden? Welcher Datentyp wäre das? Ich habs gerade am xmu ausprobiert und es wird -1, aber das hätte ich nicht unbedingt erwartet. Eher 0 : FALSE oder 1 : TRUE.

    Macht es einen Unterschied ob man "A%" schreibt oder nur "A"?

  • Zeile 10 fragt ab, ob der Feuerknopf vom Joystick in Port 2 gedrückt ist und weist den Zustand entsprechend der Variablen FB% (z.B. "firebutton2_pressed" :) ) zu: FB% = 0 / FALSE falls nicht gedrückt, -1 / TRUE, falls gedrückt.

    Wie kann der Wert hier -1 werden? Welcher Datentyp wäre das? Ich habs gerade am xmu ausprobiert und es wird -1, aber das hätte ich nicht unbedingt erwartet. Eher 0 : FALSE oder 1 : TRUE.

    Macht es einen Unterschied ob man "A%" schreibt oder nur "A"?

    Im BASIC 65 steht -1 für TRUE und 0 für FALSE.

    Die Variablenart (A% oder A) ist hierfür egal.

  • Das ist in Commodore BASIC (oder Microsoft BASIC allgemein) so. True ist -1, false ist 0. Wobei in einer Abfrage auch 1, 99 oder 4711 als True interpretiert werden. Aber das Ergebnis eines Vergleiches ist immer 0/-1.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

  • Na ja so weit war ich ja schon:

    Hier mein Code noch einmal

    So wenn ich jetzt den Feuerknopf drücke, wird mein Sprite auf das zweite Frame geschaltet (FCSPRFRAME ist ein Befehl von Snoopy Basic-Erweiterung für den Mega65)

    Soweit so gut

    Aber ich möchte auch, wenn ich jetzt erneut auf den Feuerknopf drücke das die Variabel F& wieder auf 1 umgeschaltet werden soll.

    denn wenn ich das so schreibe:

    Code
    100 IF J%>127 AND F&=1  THEN BEGIN
    105    F&=2:FCSPRFRAME 0,F&:FCSPRFRAME 1,F&
    110 BEND
    
    120 IF J%>127 AND F&=2  THEN BEGIN
    125    F&=1:FCSPRFRAME 0,F&:FCSPRFRAME 1,F&
    130 BEND
    300 LOOP

    Würde das Programm ständig zwischen den beiden Frames hin und her schalten, solange ich den Knopf drücke.

    Oder wenn ich schnell genug los lasse, wird er immer der letzten IF THEN Block ab gearbeitet

    Da ja ständig ein IF THEN Block erfüllt wird

    Ich müsste so wie es mir EgonOlsen71 in Post Bitte melde dich an, um diesen Link zu sehen. vorgeschlagen hat die zweiten IF THEN Block mit einen Goto überspringen.

    Aber dann stellt sich die Frage, wann schalte ich denn die Variabel F& wieder auf 1.

    Jedes mal wenn ich das in meinen Gedanken durchspiele, stosse ich immer wieder auf Hinternisse.

    Naja vielleicht fällt mir was im Schlaf heute Nacht ein.

  • Würde das Programm ständig zwischen den beiden Frames hin und her schalten, solange ich den Knopf drücke.

    Du willst unterscheiden lernen zwischen "Knopf ist gedrückt" und "Knopf ist jetzt gedrückt, war es aber vorher nicht". Alles was Du brauchst, ist eine zweite Variable, in der der Joystickzustand des vorigen Schleifendurchlaufs gespeichert ist.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Ach man kann doch auch sowas wie

    Code
    DO
      DO LOOP WHILE JOY(2)=JOY(2)
      IF JOY(2)>127 THEN (code für "feuerknopf wurde jetzt gerade runtergedrückt")
    LOOP

    machen oder? Nicht ganz so effizient, aber wen interessiert's. Und ganz ohne Variablen! ;)

    (naja man sollte hier dann vielleicht nicht z.B. den Joystick mit gedrücktem Feuerknopf bewegen. Ggf. (JOY(2)AND128)=(JOY(2)AND128) als WHILE-Bedingung nehmen)

    Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen.

  • Ach man kann doch auch sowas wie

    Code
    DO
      DO LOOP WHILE JOY(2)=JOY(2)
      IF JOY(2)>127 THEN (code für "feuerknopf wurde jetzt gerade runtergedrückt")
    LOOP

    machen oder? Nicht ganz so effizient, aber wen interessiert's. Und ganz ohne Variablen! ;)

    Aber das setzt doch voraus, dass die Zustandsänderung des Knopfes genau zwischen den beiden JOY-Abfragen stattfindet!? Wenn sie quasi im DO LOOP WHILE-Teil stattfindet, dann bemerkt das eine Änderung nicht. Oder übersehe ich da jetzt was?

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.

    Bitte melde dich an, um diesen Link zu sehen.