Zwei Tasten gleichzeitig abfragen, wie geht das?
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Auf die Gefahr hin, dass wir uns missverstehen bzw. ich Dich, meine eigentlichen Probleme entstehen genau dadurch, dass ich die Tasteneingaben in jeder "Spielrunde" einmalig brauche.
Und genau damit kämpfe ich noch.
Es ist möglich, dass ich mit Deiner Herangehensweise hier andere Möglichkeiten habe, und dann letztlich diese Probleme schneller vom Tisch sind. Aber dann muss ich sie auch wieder allein lösen. Denn das ist ja nicht Bestandteil Deines Codes.
So habe ich jetzt Möglichkeit 1, in meinem eigenen Programm mein Problem zu lösen, mit oder ohne Eure Hilfe, und Möglichkeit 2, mir Deinen Weg zu erarbeiten, und dann dort das Problem mit der schrittweisen Eingabe zu lösen.
Möglichkeit 1 ist für mich verlockender, weil ich das Gefühl habe, dass ich hier meinem Ziel deutlich näher bin.
Sollte ich aber mit meinem Programm letztlich scheitern, dann versuch ich es gerne nochmal mit Deiner Methode.
Vielleicht entstehen meine Probleme durch diese Eventschlange. Und die gibt es bei Dir vermutlich nicht, das könnte helfen.
Meiner Meinung nach ist das Reduzieren auf das Grundproblem zielführender.
So viele Posts inzwischen, und mir scheint es noch nicht gelungen zu sein, mich ausreichend verständlich zu machen, bei aller Mühe.
Gruß OlderCoder
Und genau damit kämpfe ich noch.
Es ist möglich, dass ich mit Deiner Herangehensweise hier andere Möglichkeiten habe, und dann letztlich diese Probleme schneller vom Tisch sind. Aber dann muss ich sie auch wieder allein lösen. Denn das ist ja nicht Bestandteil Deines Codes.
So habe ich jetzt Möglichkeit 1, in meinem eigenen Programm mein Problem zu lösen, mit oder ohne Eure Hilfe, und Möglichkeit 2, mir Deinen Weg zu erarbeiten, und dann dort das Problem mit der schrittweisen Eingabe zu lösen.
Möglichkeit 1 ist für mich verlockender, weil ich das Gefühl habe, dass ich hier meinem Ziel deutlich näher bin.
Sollte ich aber mit meinem Programm letztlich scheitern, dann versuch ich es gerne nochmal mit Deiner Methode.
Vielleicht entstehen meine Probleme durch diese Eventschlange. Und die gibt es bei Dir vermutlich nicht, das könnte helfen.
Meiner Meinung nach ist das Reduzieren auf das Grundproblem zielführender.
So viele Posts inzwischen, und mir scheint es noch nicht gelungen zu sein, mich ausreichend verständlich zu machen, bei aller Mühe.
Gruß OlderCoder
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Nur wie ich bei Deinem Code die Tastenwiederholung abschalte, sodass die Spielfigur nur genau einen Bewegungsschritt macht, egal wie lange man auf den Tasten ist, ist mir noch völlig unklar. Ich muss erst mal verstehen, wie hier aus 4 Tasten 8 Bewegungsrichtungen werden.
Edit: Ich habs versucht. Strukturen verstehe ich nur oberflächlich, das ist mir zu kompliziert. (Deshalb bin ich ja auch im Anfängerforum, aber vermutlich bin ich der Anfänger unter den Anfängern...)
Edit: Ich habs versucht. Strukturen verstehe ich nur oberflächlich, das ist mir zu kompliziert. (Deshalb bin ich ja auch im Anfängerforum, aber vermutlich bin ich der Anfänger unter den Anfängern...)
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
@Mijikai:
Ich hab in Deinen Code mal hier etwas eingefügt, um die Eingabe auf eine Bewegung zu reduzieren.
Die Absicht war, nach der Ausgabe der Spielfigur zu warten, bis garantiert keine Taste mehr gedrückt ist.
Das funktioniert grundsätzlich, allerdings sehr schlecht.
Häufig wird ein Tastendruck gar nicht angenommen, oder aber nur einer bei zwei Tasten.
Warum.. keine Ahnung.
Wie ich es sonst machen soll, weiß ich auch nicht. Mit KeyReleased hat ich auch mal etwas versucht, das ist dann auch gescheitert.
Ich hab in Deinen Code mal hier etwas eingefügt, um die Eingabe auf eine Bewegung zu reduzieren.
Code: Alles auswählen
If StartDrawing(ScreenOutput())
Circle(x,y,5)
Repeat
Until GetAsyncKeyState_(#VK_W)=0 And GetAsyncKeyState_(#VK_A)=0 And GetAsyncKeyState_(#VK_S)=0 And GetAsyncKeyState_(#VK_D)=0
StopDrawing()
EndIf
Das funktioniert grundsätzlich, allerdings sehr schlecht.
Häufig wird ein Tastendruck gar nicht angenommen, oder aber nur einer bei zwei Tasten.
Warum.. keine Ahnung.
Wie ich es sonst machen soll, weiß ich auch nicht. Mit KeyReleased hat ich auch mal etwas versucht, das ist dann auch gescheitert.
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Hallo,
ich habe einen vorhergehenden Code eine anderen noch mal etwas überarbeiten.
So scheint es jetzt sauber zu gehen.
Grüße
ich habe einen vorhergehenden Code eine anderen noch mal etwas überarbeiten.
So scheint es jetzt sauber zu gehen.
Code: Alles auswählen
EnableExplicit
Procedure KeyPressed(_code_)
ProcedureReturn (GetAsyncKeyState_(_code_) & $8000)
EndProcedure
Procedure.i Main()
Protected exit.i
Protected x.f
Protected y.f
Protected mx.f
Protected my.f
Protected WarTastenDruck
Debug "Start"
If InitSprite()
If OpenWindow(0,0,0,960,600,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
If OpenWindowedScreen(WindowID(0),0,0,960,600)
SetFrameRate(60)
x = 480
y = 320
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
exit = #True
Case #Null
Break
EndSelect
ForEver
mx = 0.0
my = 0.0
If WarTastenDruck
Repeat ; nur ausführen wenn wirlich ein Tastendruck erfolgte
Delay(1)
Until GetAsyncKeyState_(#VK_W)=0 And GetAsyncKeyState_(#VK_A)=0 And GetAsyncKeyState_(#VK_S)=0 And GetAsyncKeyState_(#VK_D)=0
WarTastenDruck=0
EndIf
If KeyPressed(#VK_W) Or KeyPressed(#VK_A) Or KeyPressed(#VK_S) Or KeyPressed(#VK_D)
Debug "Taste erkannt"
Delay(100) ; zur sicherheits müssen die Tasten solange gedrückt gehalten werden, so das auch doppelt eingaben gut abgefangen werden
If KeyPressed(#VK_W) Or KeyPressed(#VK_A) Or KeyPressed(#VK_S) Or KeyPressed(#VK_D)
Debug "Taste bestätigt"
WarTastenDruck=#True
; nur durchlaufen wenn die Tasten 100 ms gehalten wurden
If KeyPressed(#VK_W)
my - 10.0
EndIf
If KeyPressed(#VK_A)
mx - 10.0
EndIf
If KeyPressed(#VK_S)
my + 10.0
EndIf
If KeyPressed(#VK_D)
mx + 10.0
EndIf
Else
Debug "abgebrochen"
EndIf
EndIf
;Die diagonale Bewegung ist immer schneller, daher sollte hier noch ein ein Faktor einfließen!
; If mx And my
; mx * 0.6;<- Faktor (hier frei gewählt)
; my * 0.6
; EndIf
x + mx
y + my
ClearScreen($0)
If StartDrawing(ScreenOutput())
Circle(x,y,5)
DrawText(x,y+20,Str(x)+","+Str(y))
StopDrawing()
EndIf
FlipBuffers()
Until exit
EndIf
CloseWindow(0)
EndIf
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Das ist schon seltsam hier. Ich fliege schon nach relativ kurzer Zeit aus diesem Forum. Will ich nach einer Stunde oder so etwas posten oder klicke nur einen Link an, kommt plötzlich wieder die Anmeldemaske (mit Warnung des Firefox, dass meine Daten von jedem einsehbar sind), und ich muss mich schon wieder einloggen. Das ist mir woanders noch nie passiert.
Vielen lieben Dank, ST4242.
Ich hab Deinen Code gleich mal getestet. Er scheint genau das zu tun, was mir die ganze Zeit bisher nicht gelungen ist. Ich hab alle 8 Bewegungsrichtungen getestet und keine Fehler feststellen können. Und mit jeder Tastenaktion genau eine kurze Bewegung. Auch gut, die Bewegung findet nicht erst bei Loslassen der Tasten statt, wie das bei mir gewesen wäre. Ich weiß noch nicht, wie Du es gemacht hast, aber das werde ich herausfinden.
Auf jeden Fall toll!
Jetzt arbeite ich mich mal durch den Code und passe es dann an, damit ich es für mich weiterverwenden kann.
Vermutlich lässt sich das nicht auf die Event-Methode übertragen, die mir lieber wäre, weil ich sie gewohnt bin, aber alles lässt sich lernen.
Und falls es irgendwo klemmen sollte, melde ich mich wieder.
Dankeschön!
Gruß OlderCoder
Edit: Zu meiner Schande muss ich gestehen, dass ich erst jetzt merke, dass KeyPressed kein PB-Befehl, sondern eine Prozedur ist, hinter der wieder GetAsyncKeyState steckt. Vermutlich hab ich oben deshalb den einen oder anderen Müll geschrieben. .
Vielen lieben Dank, ST4242.
Ich hab Deinen Code gleich mal getestet. Er scheint genau das zu tun, was mir die ganze Zeit bisher nicht gelungen ist. Ich hab alle 8 Bewegungsrichtungen getestet und keine Fehler feststellen können. Und mit jeder Tastenaktion genau eine kurze Bewegung. Auch gut, die Bewegung findet nicht erst bei Loslassen der Tasten statt, wie das bei mir gewesen wäre. Ich weiß noch nicht, wie Du es gemacht hast, aber das werde ich herausfinden.
Auf jeden Fall toll!
Jetzt arbeite ich mich mal durch den Code und passe es dann an, damit ich es für mich weiterverwenden kann.
Vermutlich lässt sich das nicht auf die Event-Methode übertragen, die mir lieber wäre, weil ich sie gewohnt bin, aber alles lässt sich lernen.
Und falls es irgendwo klemmen sollte, melde ich mich wieder.
Dankeschön!
Gruß OlderCoder
Edit: Zu meiner Schande muss ich gestehen, dass ich erst jetzt merke, dass KeyPressed kein PB-Befehl, sondern eine Prozedur ist, hinter der wieder GetAsyncKeyState steckt. Vermutlich hab ich oben deshalb den einen oder anderen Müll geschrieben. .
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Vielen Dank, mk-soft.
Mit Deinem Link ist die Verbindung jetzt verschlüsselt.
Den Cache hab ich auch mal gelöscht.
Mal sehen, was es bringt.
Mit Deinem Link ist die Verbindung jetzt verschlüsselt.
Den Cache hab ich auch mal gelöscht.
Mal sehen, was es bringt.
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
@ST4242 :
Ich habe mich jetzt dann doch für meine Code-Variante entschieden. Jetzt weiß ich ja, warum es bei mir Probleme gab. Ich habe zur Tastatur-Abfrage GetAsyncKeyState_ und MenuEvent() zusammen verwendet, und das schafft offensichtlich ein Stück weit Chaos.
Nachdem ich nur noch GetAsyncKeyState_ verwende, gibt es keine Probleme mehr.
Allerdings muss man dann noch den Fokus des Fensters überprüfen, wenn man verhindern will, dass das Spiel weiter auf Eingaben reagiert, auch wenn es z.B. minimiert oder hinter anderen Fenstern verdeckt ist.
Dein Code hat den Vorteil, dass die Reaktion auf die Eingabe nach kurzer Verzögerung kommt. Der Nachteil ist allerdings, dass es möglich ist, dass man eine falsche Eingabe machen kann, wenn man mit der zweiten Taste aus Versehen länger wartet, als die Verzögerung dauert. Und wählt man deshalb die Verzögerung länger, stört sie spürbar.
Mein Code hat den Vorteil, dass eine Falsch-Eingabe unmöglich ist, aber den Nachteil, das die Spielreaktion erst passiert, wenn man alle Tasten loslässt. Da letzteres in diesem Spiel deutlich weniger problematisch ist als eine Falscheingabe, habe ich mich für meinen Code umentschieden.
Allerdings hatte ich bemerkt, dass ab und zu keine Tasten angenommen werden. Schuld scheint eventID = WaitWindowEvent() zu sein. In den Klammern hatte ich anfangs 20, und je höher ich den Wert gewählt habe, desto seltener sind die Tastaturausfälle passiert. Also hab ich den Wert gleich ganz entfernt. Es scheint bisher keine negativen Folgen zu haben. Aber ich weiß zwar, dass das der Timeout-Wert ist, verstehe aber trotzdem nicht so ganz, was das für Auswirkungen hat.
Hier mal der Code, wieder etwas meiner Art angepasst, und er hat als einzige Rückmeldung für die Eingabe bisher das Debug-Fenster. Vielleicht poste ich demnächst mal eine einfache erste Version des fertigen Spiels.
Gruß OlderCoder
Ich habe mich jetzt dann doch für meine Code-Variante entschieden. Jetzt weiß ich ja, warum es bei mir Probleme gab. Ich habe zur Tastatur-Abfrage GetAsyncKeyState_ und MenuEvent() zusammen verwendet, und das schafft offensichtlich ein Stück weit Chaos.
Nachdem ich nur noch GetAsyncKeyState_ verwende, gibt es keine Probleme mehr.
Allerdings muss man dann noch den Fokus des Fensters überprüfen, wenn man verhindern will, dass das Spiel weiter auf Eingaben reagiert, auch wenn es z.B. minimiert oder hinter anderen Fenstern verdeckt ist.
Dein Code hat den Vorteil, dass die Reaktion auf die Eingabe nach kurzer Verzögerung kommt. Der Nachteil ist allerdings, dass es möglich ist, dass man eine falsche Eingabe machen kann, wenn man mit der zweiten Taste aus Versehen länger wartet, als die Verzögerung dauert. Und wählt man deshalb die Verzögerung länger, stört sie spürbar.
Mein Code hat den Vorteil, dass eine Falsch-Eingabe unmöglich ist, aber den Nachteil, das die Spielreaktion erst passiert, wenn man alle Tasten loslässt. Da letzteres in diesem Spiel deutlich weniger problematisch ist als eine Falscheingabe, habe ich mich für meinen Code umentschieden.
Allerdings hatte ich bemerkt, dass ab und zu keine Tasten angenommen werden. Schuld scheint eventID = WaitWindowEvent() zu sein. In den Klammern hatte ich anfangs 20, und je höher ich den Wert gewählt habe, desto seltener sind die Tastaturausfälle passiert. Also hab ich den Wert gleich ganz entfernt. Es scheint bisher keine negativen Folgen zu haben. Aber ich weiß zwar, dass das der Timeout-Wert ist, verstehe aber trotzdem nicht so ganz, was das für Auswirkungen hat.
Hier mal der Code, wieder etwas meiner Art angepasst, und er hat als einzige Rückmeldung für die Eingabe bisher das Debug-Fenster. Vielleicht poste ich demnächst mal eine einfache erste Version des fertigen Spiels.
Code: Alles auswählen
; Abfrage 8 Richtungen
;{ Variablen
EnableExplicit
Global x.b ; enthält die gewünschte Bewegung des Spielers in X-Richtung
Global y.b ; enthält die gewünschte Bewegung des Spielers in Y-Richtung
Global eventID ; Event-Variable
;}
;{ Prozeduren
Procedure Key(_code_) ; vereinfacht die Tastaturabfrage
ProcedureReturn (GetAsyncKeyState_(_code_) & $8000)
EndProcedure
Procedure fenster()
If Not OpenWindow(0,0,0,960,600,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
Debug "Konnte Fenster nicht öffnen!"
End
EndIf
EndProcedure
;}
; Fokus verarbeiten!
; Hauptprogramm
fenster()
Repeat
eventID = WaitWindowEvent()
Select eventID
Case #PB_Event_CloseWindow
End
EndSelect
x=0 : y=0 ; Bewegungsvariablen zurücksetzen
If Key(#VK_W) ; eine der WASD-Tasten gedrückt?
y-1 ; Dann Bewegungsvariablen entsprechend verändern
ElseIf Key(#VK_A)
x-1
ElseIf Key(#VK_S)
y+1
ElseIf Key(#VK_D)
x+1
EndIf
;Gedrückte Tasten auf zusätzlich gedrückte Nachbartasten überprüfen
If y=-1 ; Falls W gedrückt wurd
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_W)=0 Or Key(#VK_D) Or Key(#VK_A) ; bis entweder W losgelassen oder D oder A gedrückt worden ist
If Key(#VK_D) ; wenn zusätzlich D gedrückt wurde
x+1
ElseIf Key(#VK_A) ; wenn zusätzlich A gedrückt wurde
x-1
EndIf
ElseIf x=1 ; Falls D gedrückt wurd
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_D)=0 Or Key(#VK_W) Or Key(#VK_S) ; bis entweder D losgelassen oder W oder S gedrückt worden ist
If Key(#VK_W) ; wenn zusätzlich W gedrückt wurde
y-1
ElseIf Key(#VK_S) ; wenn zusätzlich S gedrückt wurde
y+1
EndIf
ElseIf y=1 ; Falls S gedrückt wurd
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_S)=0 Or Key(#VK_D) Or Key(#VK_A) ; bis entweder S losgelassen oder D oder A gedrückt worden ist
If Key(#VK_D) ; wenn zusätzlich D gedrückt wurde
x+1
ElseIf Key(#VK_A) ; wenn zusätzlich A gedrückt wurde
x-1
EndIf
ElseIf x=-1 ; Falls A gedrückt wurde
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_A)=0 Or Key(#VK_S) Or Key(#VK_W) ; bis entweder A losgelassen oder S oder W gedrückt worden ist
If Key(#VK_S) ; wenn zusätzlich S gedrückt wurde
y+1
ElseIf Key(#VK_W) ; wenn zusätzlich W gedrückt wurde
y-1
EndIf
EndIf
Repeat
Delay(1) ; dann warten, bis alle Tasten losgelassen wurden
Until GetAsyncKeyState_(#VK_W)=0 And GetAsyncKeyState_(#VK_A)=0 And GetAsyncKeyState_(#VK_S)=0 And GetAsyncKeyState_(#VK_D)=0
If x<>0 Or y<>0 ; wenn irgendeine Bewegung stattfand
Debug Str(x)+" "+Str(y) ; stellvertretend bisher einzige Spielreaktion auf die Bewegungseingabe!
EndIf
ForEver
- HeX0R
- Beiträge: 2959
- Registriert: 10.09.2004 09:59
- Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 - Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Du willst also Deine CPU kochen, wenn einer länger auf ne Taste drückt?
{Home}.:|:.{Codes}.:|:.{Downloads}.:|:.{History Viewer Online}
-
- Beiträge: 109
- Registriert: 18.03.2013 12:30
- Wohnort: Bayerland
- Kontaktdaten:
Re: Zwei Tasten gleichzeitig abfragen, wie geht das?
Ok HeXOR, das war lustig .
Ein Blick auf den Taskmanager hat mir gezeigt, dass Deine Bemerkung nicht ganz fehl am Platz ist. die PureBasic_Compilation1.exe geht bei mir immerhin bis auf über 16% CPU-Auslastung. Das muss bei einem solchen winzigen Programm nicht sein.
Jetzt habe ich eine Idee gehabt, auch ohne Deinen bisher nicht mitgelieferten sachdienlichen Hinweis, und in die Warteschleifen auf das Loslassen der Tasten ein Delay(1) eingebaut, wie es ja woanders auch schon gemacht worden ist (das hätte mir auffallen können).
Und siehe da, der Spuk ist weg.
Zufrieden?
Daraus sollte ich wohl lernen, dass man in Schleifen, die nur abwarten, immer ein Delay einbaut, weil sonst die Schleife mit maximaler Geschwindigkeit läuft, was unnötig ist und Leistung frisst.Genauso sinnfrei, wie wenn jemand sein Spiel mit 1000fps laufen lässt....
Mit den Dingen, die ich über PureBasic nicht weiß, könnte man ein dickeres Buch schreiben, als wenn man ein Handbuch über PureBasic schreiben wollte.
Ein Blick auf den Taskmanager hat mir gezeigt, dass Deine Bemerkung nicht ganz fehl am Platz ist. die PureBasic_Compilation1.exe geht bei mir immerhin bis auf über 16% CPU-Auslastung. Das muss bei einem solchen winzigen Programm nicht sein.
Jetzt habe ich eine Idee gehabt, auch ohne Deinen bisher nicht mitgelieferten sachdienlichen Hinweis, und in die Warteschleifen auf das Loslassen der Tasten ein Delay(1) eingebaut, wie es ja woanders auch schon gemacht worden ist (das hätte mir auffallen können).
Und siehe da, der Spuk ist weg.
Zufrieden?
Daraus sollte ich wohl lernen, dass man in Schleifen, die nur abwarten, immer ein Delay einbaut, weil sonst die Schleife mit maximaler Geschwindigkeit läuft, was unnötig ist und Leistung frisst.Genauso sinnfrei, wie wenn jemand sein Spiel mit 1000fps laufen lässt....
Mit den Dingen, die ich über PureBasic nicht weiß, könnte man ein dickeres Buch schreiben, als wenn man ein Handbuch über PureBasic schreiben wollte.