 |
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 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 12:50 Titel: Text 5 Sekunden anzeigen(Timer zurücksetzen) |
|
|
Hi
Ich möchte einen Text genau 5 Sekunden anzeigen lassen, dazu habe ich folgende Function geschrieben:
Code: | Dim As Double zeit=Timer
'...
Sub Message(text As String)
Dim As Integer textl=Len(text)
Dim As Integer yt=768/2-64
Dim As Integer xt=1024/2-(textl*4)
Dim As Integer cl=0
If Timer<zeit+5 Then
Color RGB(255,255,cl)
Draw String(xt,yt),text
End If
Color RGB(255,255,255)
End Sub |
Allerdings funktioniert diese Function nur einmal, da die Bedingung "If Timer<zeit+5" ja nicht mehr gültig ist. Nun meine Frage: Wie kann ich es mache, dass ich diese Function mehr als einmal nutzen kann? Geht es vielleicht ohne "Timer" ? |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 13:17 Titel: |
|
|
Wenn die Sub diese Aufgabe übernehmen soll, wozu brauchst du die Zeit dann außerhalb der Sub? Mach doch alles direkt innerhalb:
Code: | ScreenRes 1024, 768, 32
'...
Sub Message(text As String)
Dim As Integer textl = Len(text)
Dim As Integer yt = 768/2 - 64
Dim As Integer xt = 1024/2 - (textl*4)
Dim As Integer cl = 0
Dim As Double zeit = Timer 'Zeit speichern
Color RGB(255, 255, cl) 'Text schreiben
Draw String (xt, yt), text
Do While Timer < (zeit + 5) 'Warten
Sleep 1 'Auslastung senken
Loop
Color RGB(0, 0, 0)
Draw String (xt, yt), text 'Verschwinden lassen
End Sub
Message("foobar")
Message("Hallo Welt")
Sleep
|
|
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 13:22 Titel: |
|
|
Ich lasse die Messages in einer Schleife anzeigen, also kann ich in der Sub nicht noch eine Schleife haben -> Programm reagiert nur alle 5 Sekunden.  |
|
Nach oben |
|
 |
nixsager
Anmeldungsdatum: 16.08.2007 Beiträge: 70
|
Verfasst am: 22.05.2011, 13:23 Titel: |
|
|
Ein Nachteil hat aber diese Methode.
In der Zeit wo die Routine läuft, läuft nichts anderes.
Eind zusätzlich Möglichkeit wäre noch, eine globale Variabel mein eine generelle Loop-Schleife zu nutzen.
Die Zeit wird einfach in der Loop-Schleife hochgesetzt und zusätlich kann die Schleife noch andere Befehle abarbeiten.
Edit:
Nutze den Timer nicht direkt, sonnder übergeben ihn an eine Variabel und nutze diese dann. _________________ ICH HASSE ES WENN ICH WERVIRRT WERDEN!!! |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 13:29 Titel: |
|
|
nixsager hat Folgendes geschrieben: | Eind zusätzlich Möglichkeit wäre noch, eine globale Variabel mein eine generelle Loop-Schleife zu nutzen. |
Ich verstehe deinen Satz nicht.  |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 13:38 Titel: |
|
|
Gut, das musst du natürlich dazusagen. Allerdings müsstest du die Sub in der Zeit ständig mitstarten wenn du das in einer Schleife lösen willst. Das erzeugt einiges an Overhead. Besser wäre da die Möglichkeit eines Threads.
Der läuft dann parallel zur normalen Eingabe und schließt sich nach der Zeit automatisch. |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 13:44 Titel: |
|
|
Eigentlich dachte ich daran, einfach den Timer zurückzusetzen. Geht das vielleicht auch? |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 13:45 Titel: |
|
|
Nein, zumal das Problem mit der Dauerschleife für die Sub bleiben würde. |
|
Nach oben |
|
 |
nixsager
Anmeldungsdatum: 16.08.2007 Beiträge: 70
|
Verfasst am: 22.05.2011, 13:49 Titel: |
|
|
Sorry ich nutze FB nicht.
1. Du brauchst ein Schleife die immer durchläuft und eine global Variabel.
Code: |
Do
TextAnzeigen(Text,AnzeigeZeit)
Loop
|
2. Dann den Code
Code: |
Function TextAnzeigen(Text as String, AnzeigeZeit as Integer) as Integer
If GlobaleVariabel = AnzeigeZeit then
Text = ""
GlobaleVariabel=0
Exit Function
End if
GlobaleVariabel = GlobaleVariabel + 1
End Function
|
So in etwa habe ich das gemeint.
Hast du mich jetzt verstanden? _________________ ICH HASSE ES WENN ICH WERVIRRT WERDEN!!! |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 14:08 Titel: |
|
|
Ja, jetzt versteh ich dich, allerdings funktioniert dein Code nicht:
Code: | Sub Message(text As String,tim As Integer =300)
Dim As Integer textl=Len(text)
Dim As Integer yt=768/2-64
Dim As Integer xt=1024/2-(textl*4)
Dim As Integer cl=0
If zeit=tim Then
text=""
zeit=0
Exit Sub
End If
Color RGB(255,255,cl)
Draw String(xt,yt),"Zeit: "+Str(zeit)+"| tim: "+Str(tim)
Color RGB(255,255,255)
zeit=zeit+1
End Sub |
"zeit" ist hier die globale Variable und "tim" die Anzeigedauer. Wenn nun zeit=tim ist, dann wird allerdings zeit auf 0 gesetzt und die Bedingung stimmt nicht mehr und die Sub wird auch nicht verlassen. |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 22.05.2011, 14:54 Titel: |
|
|
Nur mal so als Versuch:
Code: | DECLARE SUB Message(text AS STRING)
DO
' tue irgendwas
Message(neueMeldung)
' tue noch mehr tolle Sachen
LOOP UNTIL abbruchbedingung
SUB Message(text AS STRING)
STATIC zeit = TIMER
' Variablen dimensionieren
IF TIMER < zeit+5 THEN
' Textausgabe
END IF
IF zeitSollZurueckgesetztWerden THEN
zeit = TIMER
END IF
END SUB |
Ich weiß nicht, ob das genau das macht, was du willst, aber mal so als Anregung. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 15:30 Titel: |
|
|
ich denke dass die Threadmethode hier immer noch die beste Lösung ist.
Beispielcode:
Code: | Dim As Any Ptr thread
Dim As String text
ScreenRes 1024, 768, 32
Sub Message(text As ZString Ptr)
Dim As Integer textl = Len(*text)
Dim As Integer yt = 768/2 - 64
Dim As Integer xt = 1024/2 - (textl*4)
Dim As Integer cl = 0
Dim As Double zeit = Timer 'Zeit speichern
Color RGB(255, 255, cl) 'Text schreiben
Draw String (xt, yt), *text
Do While Timer < (zeit + 5) 'Warten
Sleep 1 'Auslastung senken
Loop
Color RGB(0, 0, 0)
Draw String (xt, yt), *text 'Verschwinden lassen
End Sub
text = "Hallo Welt"
For i As Integer = 0 To 80
Print "Schau mal her"
If i = 15 Then
thread = ThreadCreate(Cast(Any Ptr, @Message), StrPtr(text))
EndIf
Sleep 100
Next
Print "Warte..."
ThreadWait(thread)
Print "Ende..."
Sleep
|
|
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 16:38 Titel: |
|
|
@nemored:
Code: | Sub Message(text As String,tim As Integer =300)
STATIC zeit
zeit = TIMER
Dim As Integer ruck
Dim As Integer textl=Len(text)
Dim As Integer yt=768/2-64
Dim As Integer xt=1024/2-(textl*4)
Dim As Integer cl=0
IF TIMER < zeit+5 THEN
Color RGB(255,255,cl)
Draw String(xt,yt),"Zeit: "+Str(zeit)+"|Ruck:"+Str(ruck)
End If
If Timer>=zeit+5 Then ruck=1
Color RGB(255,255,255)
IF ruck=1 THEN
zeit = TIMER
END IF
End Sub |
So sähe der Code dann aus, allerdings funktioniert dieser nicht.
@MOD:
Mein Programm hängt sich auf, wenn ich es mit deinem Code probiere.
Außerdem funktioniert das mit dem "Alle 5 Sekunden" bei dir schlecht, da ich ja immer in der Schleife prüfen muss, wann die Zeit bei 5 Sekunden liegt und ich kann diese Zeit immernoch nicht zurücksetzen. |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 22.05.2011, 17:04 Titel: |
|
|
Code: | Sub Message(text As String,tim As Integer =300)
STATIC AS DOUBLE zeit
zeit = TIMER
[...]
|
macht natürlich nicht das, was du willst, weil du ja jetzt zeit immer wieder neu setzt und der Effekt des STATIC verloren geht. Offenbar muss bei der Erstzuweisung jedoch der Zuweisungswert eine Konstante sein, deswegen müsste das anders laufen, vielleicht so:
Code: | Sub Message(text As String,tim As Integer =300)
STATIC AS DOUBLE zeit
IF zeit = 0 THEN zeit = TIMER
[...]
|
_________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 17:10 Titel: |
|
|
Aufhängen sollte sich aber nichts, da machst du wohl beim Übertragen irgendeinen Fehler.
Wenn du mehrere 5 Sekunden Texte hintereinander schalten willst, kannst du aus dem Thread natürlich den nächsten starten. Die Texte übergibst du dann einfach als Linked List und wenn in der Liste keine Texte mehr sind, hört die Reihe auf. |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 17:26 Titel: |
|
|
@nemored
Dann steht der Text 5 Sekunden da, allerdings auch nur einmal. Beim nächsten Aufruf von Message steht wieder nichts da.
@MOD
Das ist mir viel zu kompliziert. Ich möchte nur einen Aufruf von "Message", damit eine Nachricht 5 Sekunden da steht. |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 17:50 Titel: |
|
|
Ok, letzter Versuch, danach hab ich keine Lust mehr dir Threads schmackhaft zu machen:
Code: | ScreenRes 1024, 768, 32
#Ifndef FALSE
#Define FALSE 0
#Define TRUE (Not FALSE)
#EndIf
Dim Shared As Integer messageON
Dim Shared As Integer threadCount
Sub ThreadSub(text As ZString Ptr)
Dim As String temp = *text
DeAllocate text
Dim As Integer textl = Len(temp)
Dim As Integer yt = 768/2 - 64
Dim As Integer xt = 1024/2 - (textl*4)
Dim As Integer cl = 0
Dim As Double zeit = Timer
Color RGB(255, 255, cl)
Draw String (xt, yt), temp
Do While Timer < (zeit + 5)
Sleep 1
Loop
Color RGB(0, 0, 0)
Draw String (xt, yt), temp
threadCount -= 1
If messageON = TRUE And threadCount = 0 Then
messageON = FALSE
EndIf
End Sub
Sub Message(text As String)
Dim As Any Ptr thread
Dim As ZString Ptr temp = Callocate(Len(text) + 1, 1)
*temp = text
thread = ThreadCreate(Cast(Any Ptr, @ThreadSub), temp)
threadCount += 1
If messageON = FALSE Then
messageON = TRUE
EndIf
End Sub
Message("Hallo Welt")
Do While messageOn = TRUE
Sleep 1
Loop
Message("foobar")
Do While messageOn = TRUE
Sleep 1
Loop
Print "Ende..."
Sleep |
Mit messageOn kannst du prüfen ob was angezeigt wird. Vorm Beenden des Programms solltest du aber unbedingt darauf achten, dass messageOn = FALSE ist. |
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 18:08 Titel: |
|
|
Hm ...
So?
Code: | Screenres 1024,768,32',,&h01
Graphics3D 1024,768,32',1
#Ifndef FALSE
#Define FALSE 0
#Define TRUE (Not FALSE)
#EndIf
Dim Shared As Integer messageON
Dim Shared As Integer threadCount
Sub Message(text As String)
Dim As Any Ptr thread
Dim As ZString Ptr temp = Callocate(Len(text) + 1, 1)
*temp = text
thread = ThreadCreate(Cast(Any Ptr, @ThreadSub), temp)
threadCount += 1
If messageON = FALSE Then
messageON = TRUE
EndIf
End Sub
Sub ThreadSub(text As ZString Ptr)
Dim As String temp = *text
DeAllocate text
Dim As Integer textl = Len(temp)
Dim As Integer yt = 768/2 - 64
Dim As Integer xt = 1024/2 - (textl*4)
Dim As Integer cl = 0
Dim As Double zeit = Timer
Color RGB(255, 255, cl)
Draw String (xt, yt), temp
Do While Timer < (zeit + 5)
Sleep 1
Loop
Color RGB(0, 0, 0)
Draw String (xt, yt), temp
threadCount -= 1
If messageON = TRUE And threadCount = 0 Then
messageON = FALSE
EndIf
End Sub
'In der Hauptschleife:
If messageON= True Then Message("Test") |
Weil jetzt wird auch keine Nachricht angezeigt  |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 22.05.2011, 18:26 Titel: |
|
|
Nein, erster Fehler: Ohne Deklaration der Subs musst du sie schon so anordnen wie ich das gemacht habe, sonst kennen die sich ja nicht.
Zweiter Fehler: Wie soll messageOn = TRUE sein wenn du vorher keine Message abgesetzt hast - du kannst also eher prüfen ob messageOn = FALSE.
Dritter Fehler: Ich habe extra erwähnt, dass du vor dem Ende eine Schleife einbauen sollst damit der Thread nicht abgewürgt wird. Klar das so nix angezeigt wird.
Hier die richtige Version (deinen Graphics3D-Befehl hab ich mal eben rausgenommen):
Code: | Screenres 1024,768,32',,&h01
#Ifndef FALSE
#Define FALSE 0
#Define TRUE (Not FALSE)
#EndIf
Dim Shared As Integer messageON
Dim Shared As Integer threadCount
Sub ThreadSub(text As ZString Ptr)
Dim As String temp = *text
DeAllocate text
Dim As Integer textl = Len(temp)
Dim As Integer yt = 768/2 - 64
Dim As Integer xt = 1024/2 - (textl*4)
Dim As Integer cl = 0
Dim As Double zeit = Timer
Color RGB(255, 255, cl)
Draw String (xt, yt), temp
Do While Timer < (zeit + 5)
Sleep 1
Loop
Color RGB(0, 0, 0)
Draw String (xt, yt), temp
threadCount -= 1
If messageON = TRUE And threadCount = 0 Then
messageON = FALSE
EndIf
End Sub
Sub Message(text As String)
Dim As Any Ptr thread
Dim As ZString Ptr temp = Callocate(Len(text) + 1, 1)
*temp = text
thread = ThreadCreate(Cast(Any Ptr, @ThreadSub), temp)
threadCount += 1
If messageON = FALSE Then
messageON = TRUE
EndIf
End Sub
'In der Hauptschleife:
If messageON= false Then Message("Test")
Do While messageOn = TRUE
Sleep 1
Loop
|
|
|
Nach oben |
|
 |
Westbeam

Anmeldungsdatum: 22.12.2009 Beiträge: 760
|
Verfasst am: 22.05.2011, 18:42 Titel: |
|
|
Zitat: | Nein, erster Fehler: Ohne Deklaration der Subs musst du sie schon so anordnen wie ich das gemacht habe, sonst kennen die sich ja nicht |
Ich habe die Subs deklariert. Ich hielt es nur für unnötig, dies auch in meinem Code zu schreiben, weil es ja eigentlich klar ist, dass sie deklariert werden.
Zitat: | Zweiter Fehler: Wie soll messageOn = TRUE sein wenn du vorher keine Message abgesetzt hast - du kannst also eher prüfen ob messageOn = FALSE.
Dritter Fehler: Ich habe extra erwähnt, dass du vor dem Ende eine Schleife einbauen sollst damit der Thread nicht abgewürgt wird. Klar das so nix angezeigt wird. |
Wie soll ich dann während einer Schleife eine Message absetzen? Ich glaube, du hast mein Problem nicht ganz verstanden:
Ich möchte in meinem Programm in einer Hauptschleife, in der noch viel anderes passiert, verschiedene Messages zu verschiedenen Zeiten anzeigen lassen. Also müsste mein Code so aussehen(Pseudocode):
Code: | Do
If a=1 Then Message("Blablub",5)
If b=2 Then Message("Blubbla",5)
'...
Loop Until ende
End
Sub Message(text,anzeigedauer)
If zeit<5 Then
Draw String(x,y),textl
End If
End Sub
|
|
|
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.
|
|