Keyboard Abfrage mit Flags

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Keyboard Abfrage mit Flags

Beitrag von Kaeru Gaman »

wird immer wieder gebraucht:
in games dürfen Tasten oft nur auf den ersten antipper reagieren,
z.b. wenn man durch ein Menu blättern will.

für sowas verwendet man Flags, wenn es um mehrere Keys geht praktischer Weise ein Array.

einmal als Macros:

Code: Alles auswählen

; If KeyboardPushed(#Key)
;   If Flag = 0
;     Flag = 1
;     Action()
;   EndIf
; Else
;   Flag = 0
; EndIf

Global Dim KeyFlag.b(255)

Macro KeyCheck( KeyName )
  If KeyboardPushed( KeyName )
    If KeyFlag( KeyName ) = 0
      KeyFlag( KeyName ) = 1
EndMacro

Macro EndKeyCheck( KeyName )
    EndIf
  Else
    KeyFlag( KeyName ) = 0
  EndIf
EndMacro

; Verwendung:

KeyCheck( #PB_Key_Space )
  ; hier der code
EndKeyCheck( #PB_Key_Space )
einmal als Procedure:

Code: Alles auswählen

Procedure.l KeyboardHit( KeyName.l )
  Static Dim KeyFlag.b(255)
  If KeyboardPushed(KeyName)
    If KeyFlag(KeyName) = 0
      KeyFlag(KeyName) = 1
      ProcedureReturn 1
    Else
      ProcedureReturn 0
    EndIf
  Else
    KeyFlag(KeyName) = 0
    ProcedureReturn 0
  EndIf
EndProcedure

; Verwendung:

If KeyboardHit( #PB_Key_Space )
  ; hier der code
EndIf
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

ich habe das oft mit zweifachen keyboard-daten gemacht, einmal für den aktuellen frame, und einmal für den vorhergehenden (wird einfach kopiert).
hab hier ne structure benutzt, aber kann man ja auch arrays nehmen.

Code: Alles auswählen

Structure s_keyb
  left.l
  right.l
  esc.l
  ; ...
EndStructure
Define key.s_keyb
Define keyPrev.s_keyb

Macro keyhit(_KEY_)
  (key\_KEY_ And Not keyPrev\_KEY_)
EndMacro

Repeat
  ExamineKeyboard()
  CopyMemory(@key,@keyPrev,SizeOf(s_keyb))
  key\right = KeyboardPushed(#PB_Key_Right)
  key\esc   = KeyboardPushed(#PB_Key_Escape)
  ; ...
  If keyhit(right)
    ; ACTION
  EndIf
Until quit
my pb stuff..
Bild..jedenfalls war das mal so.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

das mit dem Flags buffern hatte ich auch schon mal überlegt,
ist für ein firstpress bzw. KeyHit nicht unbedingt nötig,
wird aber nötig, wenn man wirklich ein eigenes KeyReleased basteln will.

die idee mit dem CopyMemory ist gut, das könnte man auch für ein zweifaches Array verwenden.
mir ist ein Array lieber als ne Struct, weil ich dort die #PB_Key konstante als Index verwenden kann.

grundsätzlich müssen aber die PB-Internen Keyboard-Befehle schon so etwas ähnliches machen.
der KeyTable ist etwas ganz normales, was von der API ausgespuckt wird,
was man sich auch direkt mit GetKeyboardState_() holen kann.
die Konstanten #PB_Key_Irgendwas sind einfach nur die Indices auf diesen Table,
sogar grundsätzlich die von der API vorgegebenen (deswegen haben die auf LINUX auch andere werte)
und den zweiten buffer kopieren macht dann wahrscheinlich ExamineKeyboard(),
bevor es den aktuellen Buffer von der API erfragt.
dadurch kann dann auch KeybardReleased() einen sinnvollen wert liefern

Code: Alles auswählen

If OldBuf( #Key ) And Not ActBuf( #Key )
..ich hätte gerne mal zugriff auf die beiden buffer, damit ich selber damit rumfuhrwerken kann.

ich hatte auch schon mal den wunsch nach einem KeyboardHit() ins englische Forum gepostet,
is schon ne weile her, vielleicht sollte ich mal suchen, ob irgendwann zwischendurch ne antwort eingetrudelt ist...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Dumme frage aber wieso verwendet ihr nicht einfach
KeyboardMode(#PB_Keyboard_International) ?

Hier ein Beispiel:

KeyboardPushed wirkt sich dann so aus, wie in einem "Textprogramm"
und bei längerem drücken, "ratter" es durch

Code: Alles auswählen

InitSprite()
InitKeyboard() 

xP = 800
yP = 600
OpenWindow(0, 0, 0, xP, yP, "SCREEN", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, xP, yP, 0, 0, 0)
 
Repeat

 WindowEvent()

 ClearScreen(0)

 StartDrawing(ScreenOutput())
  DrawingMode(1)
  Box(x,y,10,10,$FFFFFF) 
 StopDrawing()


 FlipBuffers()

 ExamineKeyboard()
 KeyboardMode(#PB_Keyboard_International)

 If KeyboardPushed(#PB_Key_Escape) : End : EndIf

 If KeyboardPushed(#PB_Key_Up)
  y - 10
 EndIf 
 If KeyboardPushed(#PB_Key_Down)
  y + 10
 EndIf 
 If KeyboardPushed(#PB_Key_Left)
  x - 10
 EndIf 
 If KeyboardPushed(#PB_Key_Right)
  x + 10
 EndIf 

ForEver
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

STARGÅTE hat geschrieben:Dumme frage aber wieso verwendet ihr nicht einfach
KeyboardMode(#PB_Keyboard_International) ?
kenn ich garnicht, ist das neu?
...oder mit Perwoll gewaschen....?
STARGÅTE hat geschrieben:KeyboardPushed wirkt sich dann so aus, wie in einem "Textprogramm"
und bei längerem drücken, "ratter" es durch
steht nicht in der Help, dass sich der Befehl so auswirkt.
ist außerdem grauenvoll, genau das falsche verhalten für ein game.
in nem Menu mag das ja noch angehn, aber bei steuertasten ist sowas tödlich.

ich müsste also dauernd hin- und her switchen, je nachdem welchen mode ich brauche,
und hier steht natürlich auch nicht bei, wann der mode geändert werden kann.
aber wohl kaum innerhalb des selben frames mit einem einzigen ExamineKeyboard.

also, nette idee, ist garnicht dokumentiert...
aber für games imho nutzlos.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

wusste auch nicht das es sich sooooo auswirkt, ich kanns ehrlich gesagt auch nicht gebrauchen, weil dann ja immer nur eine Taste "berücksichtigt" wird....

btw.

kann mir einer sagen wie ich das Zeichen ermitteln kann wnen jemand eine tastenkombination drückt : UMSCHALT+A, Alt-Gr+Q,....
Dabei sollte aber beachtet werden das es bei Deutsch/Englisch unterschiedliche Zeichen sind....
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

keyboardmode() hab ich bisher noch nich benutzt, ich dachte das wirkt sich nur auf die tastatur belegung aus. und kann man den effekt denn auch wieder ausschalten? is mir gerade beim flüchtigen testen nicht gelungen (mit #pb_keyboard_qwerty). die anchlagverzögerung bleibt.

@SG
was meinst'n mit 'zeichen'? wirst wohl für sowas selber ne code-tabelle anlegen müssen o.d.g.
my pb stuff..
Bild..jedenfalls war das mal so.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

zeichen, also, eingabestrings, bekommst du doch mit KeyboardInkey(), oder?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

es soll wohl genau für sowas dasein, aber ich glaub damit kriegst du wieder nur key-releases :roll: ..riechlich doof zum tippen.
(siehe auch hier:http://www.purebasic.fr/english/viewtop ... ight=inkey)
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

@#NULL:
habs ja schon selber gemacht, problem ist dann aber das ICH festlegen muss das die Taste die bei uns Ö ein ö macht, bei eineranderen englischen Tastatur darf da aber kein ö kommen -.-
Ich muss es also von WIN selber holen.

@Kaeru Gaman:
Inkey reicht nicht, da ich ja auch UMSCHALT und AltGr unterstützung habn möchte und die Alt+#Nummer funktion, sowie das aus ´ und danach e drücken ein é wird.

Mir schient so als müsste ich einfach noch bei Sprachauswahl die Zeichentabelle mit liefern. denn wenn ich so überlege was bei der englischen Internat. tastatur alles für zeichen möglich sind :o
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten