Countdown?

  • BladeRunner schrieb:

    So, mal ein kleines Beispiel hingesaut.
    Och Menno, jetzt haste mich inspiriert...

    BladeRunner schrieb:

    Der Vergleich muss auch mit auf Sekunden gerundeten Werten erfolgen, sonst bleibt die Schleife manchmal hängen.
    Zuerst wollte ich nur diesen Teil ändern, aber dann hab ich gleich die ganzen Umrechnungen entfernt: Meine Version erzeugt durch Addition von TI und 60 eine Alarmzeit, die eine Sekunde in der Zukunft liegt. Ist die Alarmzeit erreicht, wird eine neue Alarmzeit gesetzt und eine separate Countdown-Variable heruntergezählt. Das erspart eine Menge Multiplikationen, Divisionen und INT()s:

    Quellcode

    1. 0 il=60:rem Intervall-Länge in Ticks (= 1 s)
    2. 1 cd=10:rem Startwert für Countdown
    3. 5 print chr$(147);
    4. 10 co=cd:at=ti:rem Starte Countdown
    5. 20 gosub 100
    6. 30 if ti>=at then gosub50
    7. 35 if co>0then20
    8. 40 print"ende"
    9. 45 end
    10. 50 rem Alarmzeit erreicht
    11. 51 at=at+il:rem nächsten Alarm setzen
    12. 52 co=co-1:rem Zähler herunter
    13. 53 print "{home}" co "seconds left..."
    14. 54 return
    15. 100 rem doing stuff
    16. 110 x=rnd(1)*30
    17. 120 y=rnd(i)*23:y=y+1
    18. 130 poke 1024+(y*40)+x,0
    19. 131 poke55296+(y*40)+x,rnd(1)*15
    20. 136 poke53280,rnd(1)*15
    21. 137 poke646,rnd(1)*15
    22. 140 return
    Alles anzeigen
    Das Unterprogramm ab Zeile 50 kann man natürlich auch in eine Zeile quetschen, wenn man denn unbedingt will...

    EDIT: Für diese Countdown-Algorithmen ist es zwar egal, ob TI vorher auf 0, auf 17 oder auf 31337 steht, aber bei einem Überlauf hätte man dennoch Probleme. Also sollte man auf jeden Fall TI$ setzen, z.B. vor dem Start eines neuen Levels.
    Yes, I'm the guy responsible for the ACME cross assembler

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

  • Hallo,
    Hier noch mal ein Code, den ich in dem Thread Warten mit ti veröffentlicht hatte.

    Quellcode
    1. 10 :rem--wart-sekunden(i)
    2. 11 :fori=ti+i*60toi:i=ti:next:return
    Angepasst auf das Beispiel:


    10 :cd=10
    11 :fori=ti+60toi::::i=ti:next:cd=cd-1:printcd:ifcd>0goto11

    Kürzer geht es wohl kaum.

    Schönen Gruß.
  • -trb- schrieb:

    RKSoft schrieb:

    Nachtrag:

    Für dich sind nur 2 Dinge wichtig, um sie einzubauen

    ti$="000000": timer=0: tempvar=0
    if tempvar < ti - 60 then tempvar = ti: timer = timer -1
    Die Variable timer dürfte beim C64 nicht funktionieren, weil sie als die Systemvariable ti interpretiert wird.
    Die 2 Variablen sollten nur Klartext sein und nicht so genutzt werden. Natürlich gehen bei Commodore Rechner maximal nur 2 Ziffern.

    'timer' = Variable für den Timer
    'tempvar' = temporäre Variable
  • RKSoft schrieb:

    Natürlich gehen bei Commodore Rechner maximal nur 2 Ziffern.
    Es "gehen" beliebig viele Zeichen als Variablennamen (zumindest viel mehr als 2, vermutlich 255), nur dürfen in den Variablennamen weder Systemvariablennamen (TI, ST, TI$) noch BASIC-Befehle enthalten sein. TIMER enthält die Systemvariable TI -> "geht" also nicht.
    "Steve Jobs hat User hervorgebracht, Jack Tramiel Experten."
    (Quelle unbekannt)

    "Lege dich nie mit einem Idioten an! Er zieht dich auf sein Niveau hinunter und schlägt dich dann mit seiner Erfahrung!"
    (Volksmund)
  • kinzi schrieb:

    Es "gehen" beliebig viele Zeichen als Variablennamen (zumindest viel mehr als 2, vermutlich 255), nur dürfen in den Variablennamen weder Systemvariablennamen (TI, ST, TI$) noch BASIC-Befehle enthalten sein. TIMER enthält die Systemvariable TI -> "geht" also nicht.
    Das C64-Basic kann Variablen aber nur anhand der ersten beiden Buchstaben unterscheiden.
    Man kann zwar längere Namen verwenden. Aber alle Buchstaben danach werden ignoriert.

    Beispiel:

    10 NAME=123
    20 PRINT NASE

    Ergebnis: 123

    Die Variable NASE liefert den gleichen Wert die die Variable NAME.
    Weil beides mit NA anfängt und für den C64 somit identisch ist.
  • Das ist völlig richtig, das hatte ich vergessen zu erwähnen. Jetzt dürften wir die "Rahmenbedingungen" richtig abgesteckt haben. :thumbup:
    "Steve Jobs hat User hervorgebracht, Jack Tramiel Experten."
    (Quelle unbekannt)

    "Lege dich nie mit einem Idioten an! Er zieht dich auf sein Niveau hinunter und schlägt dich dann mit seiner Erfahrung!"
    (Volksmund)
  • @steril:
    Die Sinnfrage wurde in diesem Zusammenhang natürlich schon des öfteren gestellt und muß jeder Programmierer natürlich auch für sich beantworten.
    Für den einen unverzichtbar und für andere als Beiwerk gesehen.
    Sinnfragen sind allgemein gesagt Fragen, die jeder auch für sich beantworten muß.

    Schönen Gruß.
  • Oder, um es mal mit Fakten zu beantworten:
    Die Doppelpunkte sind überflüssig und für den Programmablauf idR. sogar hinderlich, denn:
    - jeder unnötige Doppelpunkt ist ein verlorenes Byte Basicspeicher
    - jeder unnötige Doppelpunkt muss vom Interpreter dennoch ausgewertet werden, was sinnfrei eine eh schon langsame Sprache noch weiter ausbremst.
    Daher wäre die einzige valide Begründung die Dinger gebündelt zu nutzen wenn man durch die entstehende Verzögerung gewollte Effekte erzielt.
    Die haben also normalerweise nicht nur keinen Sinn sondern sind im Gegenteil sogar völlig unsinnig. Bitte nicht angewöhnen.
    GREETINGS PROFESSOR FALKEN
    A STRANGE GAME.
    THE ONLY WINNING MOVE IS NOT TO PLAY.
    HOW ABOUT A NICE GAME OF CHESS?
  • Man könnte zugute des Entwicklers *hüstel* argumentieren, dass die Doppelpunkte - richtig eingesetzt - evtl. die Lesbarkeit fördern würden.
    Aber dann wird ja eh alles auf einer Zeile zusammengewurstelt, also mehrere Befehle und ohne Leerzeichen, in etwa so:

    11 :fori=ti+60toi::::i=ti:next:cd=cd-1:printcd:ifcd>0goto11


    versus, was lesbarer und nachvollziehbarer wäre, etwa so:
    11 for i = ti + 60 to i
    12 i = ti
    13 next
    14 cd = cd - 1
    15 print cd
    16 if cd > 0 goto 11

    Was dann das Ganze Ad Absurdum führt.


    Ich persönlich habe für BASIC V2 auf dem C64 sogar die UPPERCASE Variante lieber, aber das bin nur ich, weil ich generell auch in anderen Sprachen die Keywords gross mag.
    Lesbar strukturierter Code über Seiten hinweg versuche ich durchzusetzen, weil zu später Stunde das Auge einfach müde ist und es besser lesen kann:

    11 FOR I = TI + 60 TO I
    12 I = TI
    13 NEXT
    14 CD = CD - 1
    15 PRINT CD
    16 IF CD > 0 GOTO 11
    ___________________________________________________________
    Meine Kreationen: Deviant Art | Toonsup | Flickr | Youtube
    | Twitter
    Avatar: Copyright 2017 by Saiki
  • Wer wirklich aus Überzeugung in GASIC programmiert wird selbstverständlich eine Dialekt wählen, der Zeilennummern, Schlüsselwörter und andere Paraphernalia selbsttätig mit Leerzeichen und sonstigen Formatietrungen hervorzuheben. Sinclair-Computer waren da beispielsweise recht gut drin. Keinesfalls wird man jedoch ein BASIC wie das MS-CBM-Gewächs wählen, das noch nicht einmal Variablennamen beherrscht sondern nur den zweistelligen Variablen-Index- mit den oben genannten Konsequenzen.

    EDIT: @BladeRunner: Die Punkte verschlechtern die Lesbarkeit deutlich, und das ist volle Absicht.
  • Da hast Du natürlich Recht. Wie bekomme ich Sinclair-BASIC (oder heißt das GASIC?) auf meinen C64?
    Will nicht noch jemand empfehlen, lieber Assembler zu nehmen oder sich sonst irgendwie wichtig machen? Nein? Gut, dann bitte BTT! :)
    Bitte beachten: Telespielatorgesetz (TspG)
    Verstöße gegen das TspG werden umgehend und gnadenlos von Supererdbeeregeahndet!
  • Nein, das war ein Tippfehler. Das originale Sinclair BASIC mit den automatischen Leerzeichen bekommt man natürlich auf dem PC nur mit einem Emulator (ZX81, Spectrum 48k; QL weiß ich grad nicht wie der mit seinen Token umgeht). Oder mit dem 'Spectrum-Emulator' auf dem C64- wobei das eher ein BASIC-Interpreter mit Spectrum-TAPE-Loader ist, kein Emulator in unserem heutigen Sprachgebrauch.
  • Telespielator schrieb:

    Will nicht noch jemand empfehlen, lieber Assembler zu nehmen
    Ach, das tut doch nich Not - es reicht ja auch C. Oder Pascal. Oder Comal. Oder...

    Telespielator schrieb:

    dann bitte BTT!
    Es ist Dein Thread. Da Du Dich zum ursprünglichen Problem bisher nicht wieder geäußert hast, gibt es dazu auch kaum mehr etwas zu sagen. Kein Wunder, dass das Thema dann abgleitet. Hast Du den Countdown denn jetzt hinbekommen?
    Yes, I'm the guy responsible for the ACME cross assembler
  • Braske schrieb:

    Die Variable TI kann man nur auslesen, aber nicht selber setzen.
    Das stimmt so nicht ganz. Man kann ja auch direkt in die Speicherstellen 160-162 reinschreiben bzw. diese auslesen.

    Hallo @Tele: Soll der Countdown eine echte Zeit-(Sekunden)Anzeige sein oder geht/reicht auch ein Countdown von z. B. 1000 nach 0?

    Man könnte das evtl. ganz witzig über die Speicherstellen 160/161 und ' IF NOT PEEK(16x) GOTO Schleife ' machen. Nur so eine Idee.
    Read'n'Blast my jump'n'stop-text-sprite-scroller Select A Move

    Ex-TLI (The Level 99 Industries) & Ex-TNP (The New Patriots) & Ex-TEA (The East Agents) & ?
  • Naja, es geht um einen Countdown für ein Spiel bei dem eine Runde vielleicht 1-3 Minuten dauern soll. So 100% exakt braucht das natürlich nicht zu sein, nur sollte dann genau bei 0 auch Schluss sein. Bei meinen bisherigen Versuchen kam das ganze erst im negativen Bereich zum Stehen, weil TI so schnell zählt...
    Was genau liegt den in den Speicherstellen 160-162?
    Bitte beachten: Telespielatorgesetz (TspG)
    Verstöße gegen das TspG werden umgehend und gnadenlos von Supererdbeeregeahndet!