 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
weda
Anmeldungsdatum: 15.06.2011 Beiträge: 6
|
Verfasst am: 15.06.2011, 00:50 Titel: Input während Countdown |
|
|
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 |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 15.06.2011, 01:09 Titel: |
|
|
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!
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 |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
 |
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 15.06.2011, 01:35 Titel: |
|
|
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 |
|
 |
weda
Anmeldungsdatum: 15.06.2011 Beiträge: 6
|
Verfasst am: 15.06.2011, 01:42 Titel: |
|
|
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 |
|
 |
weda
Anmeldungsdatum: 15.06.2011 Beiträge: 6
|
Verfasst am: 16.06.2011, 00:20 Titel: neues problem |
|
|
juchei, das problem ist gelöst, stehe jetzt aber vor einem ganz anderen :
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... (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 |
|
 |
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 16.06.2011, 01:11 Titel: |
|
|
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 |
|
 |
weda
Anmeldungsdatum: 15.06.2011 Beiträge: 6
|
Verfasst am: 16.06.2011, 01:26 Titel: |
|
|
ich bin doch ein holzkopp... man sieht den wald vor lauter bäumen nimmer...
so einfach kanns sein x)
dankschee! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 16.06.2011, 10:21 Titel: |
|
|
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 |
|
 |
weda
Anmeldungsdatum: 15.06.2011 Beiträge: 6
|
Verfasst am: 20.06.2011, 20:24 Titel: |
|
|
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 |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 20.06.2011, 20:47 Titel: |
|
|
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 |
|
 |
weda
Anmeldungsdatum: 15.06.2011 Beiträge: 6
|
Verfasst am: 20.06.2011, 23:09 Titel: |
|
|
perfekt
danke! |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 21.06.2011, 08:55 Titel: |
|
|
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 )
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 |
|
 |
|
|
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.
|
|