Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Input während Countdown

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
weda



Anmeldungsdatum: 15.06.2011
Beiträge: 6

BeitragVerfasst am: 15.06.2011, 00:50    Titel: Input während Countdown Antworten mit Zitat

Hallihallo,

folgendes Problem:
ich möchte eine Art Quiz programmieren, bei dem man unter Zeitdruck Fragen beantworten muss. Pro Frage 10 Sekunden Zeit.

Die Zeitschlaufe für den Countdown wäre dann:

Code:

dim as integer zeit
for zeit=10 to 1 step -1
sleep 1000
cls
print zeit
next zeit


Mein Problem ist jetzt die Eingabe zu tätigen, ohne die Zeitschlaufe dabei in ihrem Sekundentakt zu stören. Wenn ich mit inkey arbeite, bricht das den sleep-Befehl ab. Wenn ich bei dem aber für 'flag' 1 eingebe, wird die Eingabe erst am Ende der Sekunde abgenommen, was mir eine zu große Verzögerung ist. Wenn ich den input-Befehl benutze, wird bis zur Eingabe gewartet und die Sekundenanzige bleibt stehen.
Hat jemand einen Lösungsvorschlag für mich?

Lieben Gruß, Weda
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 15.06.2011, 01:09    Titel: Antworten mit Zitat

Den Input-Befehl kannst du für solche Zwecke meines Wissens leider nicht verwenden. Hier gibt es (u.a.) folgenden Ansatz:

Du programmierst manuell eine Eingabefunktion

Dafür müsstest du die Wartelogik anders aufbauen, als oberhalb von dir geschrieben. Du könntest z.B. zuerst die aktuelle Zeit mit der Funktion TIMER() in einer Variable zwischenspeichern. In einer Endlosschleife mit einem kurzen Sleep zur Schonung der CPU-Auslastung (z.B. Sleep 10) prüfst du dann ständig, ob Tasten gedrückt worden sind und baust dir aus den einzelnen Tastendrücken selbst den Eingabestring zusammen. Weiters prüfst du ständig in der Schleife die aktuelle Zeit wiederrum mittels Timer() und verlässt die Schleife (Exit Do/While) wenn die Antwortzeit um ist.

//edit: Sebastians Beispiel unterhalb arbeitet nach diesem Schema.

btw: welcome back, Sebastian! zwinkern
wünsch dir, dass der Stress etwas nachlässt
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)


Zuletzt bearbeitet von St_W am 15.06.2011, 01:19, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 15.06.2011, 01:10    Titel: Antworten mit Zitat

Hallo,

das könntest du z.B. ungefähr so lösen: http://www.freebasic-portal.de/porticula/countdown-fuer-quizfrage-minibeispiel-1271.html

Der Trick besteht darin, nicht über SLEEP die Antwortdauer zu steuern, sondern die Systemuhr abzufragen. Zu Beginn der Fragerunde merkt man sich die aktuelle Zeit und ermittelt dann in einer Schleife, wie viel Zeit seit dem vergangen ist.

Viele Grüße!
Sebastian
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
XOR



Anmeldungsdatum: 23.07.2010
Beiträge: 161

BeitragVerfasst am: 15.06.2011, 01:35    Titel: Antworten mit Zitat

Wenn es sich bei der antwort um eine Text handelt und nicht um A,B,C,D Antworten kann man es so machen:
Code:
Dim StartTime As Double
''Anfangszeit der Frage

Dim AktuelleTime As Integer = -1
''Aktuelle zeit, nur da dass man nicht jeden frame die zeit neu schreiben muss

Dim Eingabe As String
''Eingabe = inkey

Dim GesammtEingabe As String
''Der Antwortsting

Const WaitSec = 10
''Zeit einer frage

StartTime = Timer
''Frage beginnt, nehme zeit

Print "Welche Programiersprache ist die beste?"

Locate 3 , 1
''Setzt crusor auf dritte reihe erstes zeichen

Print "Eingabe: "
Do
   ''Schleife
   
   If AktuelleTime <> Int ( Timer - StartTime ) Then
      ''Wenn sich die zeit um eine sec geaenert hat
      
      AktuelleTime = Int ( Timer - StartTime )
      ''AktuelleTime neu setzen
      
      Locate 2,1
      ''Setzt crusor auf zweite reihe erstes zeichen
      
      Print "Time: "+Str ( WaitSec - AktuelleTime ) + " "
      ''Und schreibe die zeit
      
      Locate 4,1
   EndIf
   
   Eingabe = InKey ( )
   ''Eingabe
   
   If Eingabe = Chr ( 255 ) + "k" Then End
   ''Wenn eingabe = fenster schliessen dann beende
   
   Select Case Eingabe
      Case "A" To "Z" , "a" To "z" , "0" To "9"
         ''Wenn eingabe eins dieser zeichen ist,
         
         GesammtEingabe += Eingabe
         ''Zeichen zum String hinzufuegen
         
      Case Chr ( 8 )
         ''Wenn Eingabe = BackSpace dann
         
         GesammtEingabe = Left ( GesammtEingabe , _
         Len ( GesammtEingabe ) - 1 )
         ''Letztes zeichen vom string loeschen
         
      Case Chr(13)
         ''Wenn enter loop beenden
         Cls
         Exit Do
         
   End Select
   
   If Eingabe <> "" Then
      ''Wenn es eine eingabe gab string neu malen
      Locate 3,1
      Print "Eingabe: " + GesammtEingabe + " "
   EndIf
   
   If StartTime + WaitSec < Timer Then
      ''Wenn 10 sec um sind schleife beenden
      Cls
      Print "Time Up"
      Exit Do
   EndIf
   
   Sleep 10 , 1
   ''Um CPU last zu reduzieren
   
Loop

If LCase(GesammtEingabe) = "freebasic" Then
   ''Schauen ob ergebnis richtig ist
   Print "Richtig!!"
Else
   ''Oder Falsch
   Print "Leider Falsch, richtig ist "+Chr(34)+"FreeBASIC"+Chr(34)
EndIf
Sleep
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
weda



Anmeldungsdatum: 15.06.2011
Beiträge: 6

BeitragVerfasst am: 15.06.2011, 01:42    Titel: Antworten mit Zitat

Aah, okay... ja, sowas in der Richtung dachte ich mir schon. Okay, dann probier ich mal auf die Weise weiter...
Danke für die Hilfe und liebs Grüßle!

Weda
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
weda



Anmeldungsdatum: 15.06.2011
Beiträge: 6

BeitragVerfasst am: 16.06.2011, 00:20    Titel: neues problem Antworten mit Zitat

juchei, das problem ist gelöst, stehe jetzt aber vor einem ganz anderen neutral :
ich will während der fragen eine wav im dauerloop abspielen, so im sekundentakt etwa, die pro runde immer etwas lauter wird. das funktioniert auch soweit, nur habe ich massive performance-probleme. sleep-verschnaufpause hab ich mit 100 ms drin, komm ich da mit dem arbeitsspeicher weiter? habe das schon so probiert, aber da ändert sich nüscht... peinlich (vllt auch falsch angewendet.. ?)

ich weiß, das passt jetzt nich zu der überschrift, aber ich wollte nich extra einen neuen fred aufmachen...
danke für erhaltene und hoffentlich erhalten werden werdende hilfe!
gruß, weda
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
XOR



Anmeldungsdatum: 23.07.2010
Beiträge: 161

BeitragVerfasst am: 16.06.2011, 01:11    Titel: Antworten mit Zitat

Hier ein beispiel mit musik.
Am anfang der frage wird keine musik gespielt. Ueber die 10 sec. wird sie hochgedimmt.
Zitat:
sleep-verschnaufpause hab ich mit 100 ms drin, komm ich da mit dem arbeitsspeicher weiter?

Die musik wird in einem systemthread abgespielt, da ist es egal wie lange du sleep drinnen hast.
Ich habe die prodigy.wav benutzt, die findet man im ordner
FreeBASIC\examples\libraries\sound\data
oder benutz deine eigene.
Code:
#Include "windows.bi"
#Include Once "win/mmsystem.bi"
''Header fuer windows funktionene

Dim StartTime As Double
''Anfangszeit der Frage

Dim AktuelleTime As Integer = -1
''Aktuelle zeit, nur da dass man nicht jeden frame die zeit neu schreiben muss

Dim Eingabe As String
''Eingabe = inkey

Dim GesammtEingabe As String
''Der Antwortsting

Dim Musik As UByte Ptr
''Zeiger zur wavedatei

Dim VolumenRechts As UShort
Dim VolumenLinks As UShort
''Volumen

Dim FF As Integer = FreeFile
Open "prodigy.wav" For Binary As #FF
Musik = Callocate(Lof(FF))
Get #FF , , *Musik, Lof(FF)
Close #FF
''Oeffnet die wave

PlaySound(Musik,0,SND_LOOP Or SND_ASYNC Or SND_MEMORY Or SND_NODEFAULT)
''Und spielt sie im dauerloop ab

Const WaitSec = 10
''Zeit einer frage

StartTime = Timer
''Frage beginnt, nehme zeit

Print "Welche Programiersprache ist die beste?"

Locate 3 , 1
''Setzt crusor auf dritte reihe erstes zeichen

Print "Eingabe: "

Do
   ''Schleife
   
   VolumenRechts = (Timer - StartTime)/WaitSec*(2^16-1)
   VolumenLinks = (Timer - StartTime)/WaitSec*(2^16-1)
   waveOutSetVolume(0,VolumenRechts Shl 16 Or VolumenLinks)
   ''Setzt das Volumen. Anfang niedrig speater hoch
   
   If AktuelleTime <> Int ( Timer - StartTime ) Then
      ''Wenn sich die zeit um eine sec geaenert hat
      
      AktuelleTime = Int ( Timer - StartTime )
      ''AktuelleTime neu setzen
      
      Locate 2,1
      ''Setzt crusor auf zweite reihe erstes zeichen
      
      Print "Time: "+Str ( WaitSec - AktuelleTime ) + " "
      ''Und schreibe die zeit
      
      Locate 4,1
   EndIf
   
   Eingabe = InKey ( )
   ''Eingabe
   
   If Eingabe = Chr ( 255 ) + "k" Then
      waveOutSetVolume(0,&HFFFFFFFF)
      PlaySound(NULL, 0, 0)
      DeAllocate(Musik)
      End
   EndIf
   ''Wenn eingabe = fenster schliessen dann beende
   
   Select Case Eingabe
      Case "A" To "Z" , "a" To "z" , "0" To "9"
         ''Wenn eingabe eins dieser zeichen ist,
         
         GesammtEingabe += Eingabe
         ''Zeichen zum String hinzufuegen
         
      Case Chr ( 8 )
         ''Wenn Eingabe = BackSpace dann
         
         GesammtEingabe = Left ( GesammtEingabe , _
         Len ( GesammtEingabe ) - 1 )
         ''Letztes zeichen vom string loeschen
         
      Case Chr(13)
         ''Wenn enter loop beenden
         Cls
         Exit Do
         
   End Select
   
   If Eingabe <> "" Then
      ''Wenn es eine eingabe gab string neu malen
      Locate 3,1
      Print "Eingabe: " + GesammtEingabe + " "
   EndIf
   
   If StartTime + WaitSec < Timer Then
      ''Wenn 10 sec um sind schleife beenden
      Cls
      Print "Time Up"
      Exit Do
   EndIf
   
   Sleep 10 , 1
   ''Um CPU last zu reduzieren
   
Loop

If LCase(GesammtEingabe) = "freebasic" Then
   ''Schauen ob ergebnis richtig ist
   Print "Richtig!!"
Else
   ''Oder Falsch
   Print "Leider Falsch, richtig ist "+Chr(34)+"FreeBASIC"+Chr(34)
EndIf
Sleep

waveOutSetVolume(0,&HFFFFFFFF)
''Volumen auf anfang

PlaySound(NULL, 0, 0)
''Sound beenedn

DeAllocate(Musik)
''WAV loeschen

Ich hoffe das hat geholfen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
weda



Anmeldungsdatum: 15.06.2011
Beiträge: 6

BeitragVerfasst am: 16.06.2011, 01:26    Titel: Antworten mit Zitat

ich bin doch ein holzkopp... man sieht den wald vor lauter bäumen nimmer...
so einfach kanns sein x)
dankschee!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 16.06.2011, 10:21    Titel: Antworten mit Zitat

Die Methode ist ein glatter Schuss ins Bein:
- Dank fehlendem Handle wird die Lautstärke Systemweit gesetzt
- Zum Schluss wird die Lautstärke auf die volle Lautstärke und nicht die Anfangslautstärke gesetzt
- Es ist nicht garantiert, dass das Ausgabegerät eine hohe Präzision für das Setzen der globalen Laustärke besitzt (ich erinnere mich noch an genau Soundkarten, wo das nur in groben Schritten möglich ist).

Sinnvoller wäre es, BASS oder FMOD zu benutzen, wo man auch vollautomatisch einen Volume Slide im Hintergrund durchführen kann.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
weda



Anmeldungsdatum: 15.06.2011
Beiträge: 6

BeitragVerfasst am: 20.06.2011, 20:24    Titel: Antworten mit Zitat

hi,
-verstehe ich nicht. systemweit heißt doch für das gesamte OS, oder? wenn ich während der programmausführung andere soundausgebende programme laufen hatte, waren die aber nie betroffen... läuft sogesehen so, wie es soll.
-ist angekommen
-eine so hohe präzision ist für meine zwecke eh nicht erforderlich
dass es mit bass und fmod sinnvoller ist, glaube ich dir sofort, nur ists auch umständlicher und da das ganze eher gag als programmhauptbestandteil ist, bleib ich, glaube ich, erstmal bei der lösung. aber trotzdem danke.

dafür komm ich aber mal wieder mit nem neuen problemchen:
ich will jede 30 sekunden eine aktion ausführen lassen. jetzt brauch ich einen term für "jede 30 sekunden", also jede zahl, die durch 30 glatt teilbar ist. auf meinem programmierbaren taschenrechner gibts da das "@", das jede ganze zahl ausgibt (also in meinem fall dann @30=30, 60, 90 usw.), gibts sowas auch bei freebasic oder muss ich mir da echt erst ein sub schreiben, das prüft ob eine zahl durch eine andere glatt teilbar ist? würde paar zeilen sparen...
danke und lg, weda
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 20.06.2011, 20:47    Titel: Antworten mit Zitat

Hallo,

das könntest du z.B. so machen:
Code:
Const Intervall As Integer = 30
Dim   Zeit      As Single  = Timer
Dim   Eingabe   As String

Print "Waehrend des Wartens zur Ablenkung A oder B druecken."
Print "Zum Abbrechen eine andere Taste druecken."
Print "---"
Print

color 12
Print Time & " Los geht's!"
color 7

Do
   
    Sleep 100
   
    ' ... Irgendetwas tun...
    ' z. B. auf Tastendruck pruefen:
    Eingabe = Inkey
    If Eingabe <> "" Then
        Select Case UCase(Eingabe)
        Case "A": Print "Wer A drueckt, kann auch B druecken."
        Case "B": Print "B gedrueckt."
        Case Else: Exit Do
        End Select
    End if
    ' ...
   
    ' Sind seit dem Start bzw. der letzten Zeitnahme
    ' <Intervall> viele Sekunden (im Bsp.: 30) vergangen?
    If (Abs(TIMER-Zeit) > Intervall) Then
        Color 12
        Print Time & " Es sind soeben " & Intervall;
        Print " Sekunden vergangen."
        Color 7
        Beep
        Zeit = Timer
    End If
   
Loop

End


Viele Grüße!
Sebastian
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
weda



Anmeldungsdatum: 15.06.2011
Beiträge: 6

BeitragVerfasst am: 20.06.2011, 23:09    Titel: Antworten mit Zitat

perfekt
danke!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 21.06.2011, 08:55    Titel: Antworten mit Zitat

Zitat:
oder muss ich mir da echt erst ein sub schreiben, das prüft ob eine zahl durch eine andere glatt teilbar ist

Da gibt es schon was: die Teilbarkeit durch eine Zahl lässt sich leicht mit MOD prüfen (die mathematische Funktion, nicht der Forenbenutzer grinsen )
Code:
IF (zahl MOD 30) = 0 THEN PRINT zahl; " ist ohne Rest durch 30 teilbar!"

Bei TIMER ist das, was Sebastian im obigen Beispiel macht, natürlich wesentlich besser bzw. meines würde so gar nicht richtig funktionieren (macht sowieso nur bei Ganzzahlen wirklich Sinn); das war nur der Vollständigkeit halber.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz