Seite 1 von 1

Keyboard Abfrage mit Flags

Verfasst: 03.03.2008 23:08
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

Verfasst: 04.03.2008 16:06
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

Verfasst: 04.03.2008 16:21
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...

Verfasst: 04.03.2008 18:21
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

Verfasst: 04.03.2008 18:30
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.

Verfasst: 04.03.2008 18:47
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....

Verfasst: 04.03.2008 19:45
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.

Verfasst: 04.03.2008 19:49
von Kaeru Gaman
zeichen, also, eingabestrings, bekommst du doch mit KeyboardInkey(), oder?

Verfasst: 04.03.2008 19:59
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)

Verfasst: 05.03.2008 04:38
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