Re:Redefine Keys

BlitzMax Forums/BlitzMax Beginners Area/Re:Redefine Keys

Joe90bigrat90(Posted 2011) [#1]
Ive got 2 players and i want to redefine keys when you press 0.

Theres 5 keys for each player. player1 defaults are
UP(W), DOWN(S), LEFT(A), RIGHT(D) and FIRE(G).
player2 defaults are
UP(up arrow), DOWN(down arrow), LEFT(left arrow), RIGHT(right arrow) and FIRE(left CTRL)

Ive written a small program that accepts input when running in graphics mode. However i want an example so when you press 0 it clears the screen. Asks for input for all 5 keys for player 1 and ask for input for all 5 keys for player 2
cls
DrawText "Input up Key:> " + Player1_UP:String, 700, 500
DrawText "Input Down Key:> " + Player1_DOWN:String, 700, 500
etc etc for all keys
c=GetChar()

how can i do this properly. Ive worked out a way of storing strings
but i cant seem to figure out how to accept 1 character. so if the user types more than 1 character the length of the string stays at 1.

Do i need to ask for input 5 times with the lines above.
Store the character pressed and then ask for the next key and once player 1 has entered keys it then asks 5 times for player 2 keys.

There must be an easy way to do this. This is what ive got for my string input if you want to change player1's name.

Function GetPlayer1Name() 
	FlushKeys
	Local done = 0
	Local c
	Repeat
		Cls		
		DrawText "Input Player 1 Name:> " + player1name:String, 700, 500
		c = GetChar() 
		If c <> 0
			If c = 8
				If Len(player1name:String) > 0 Then player1name:String = Left:String(player1name:String, Len(player1name:String) - 1) 
			EndIf
			Select c
				Case 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72,  ..
					73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,  ..
					97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,  ..
					110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122
						player1name = player1name + Chr(c) 
			End Select
		EndIf
		
		If KeyHit(KEY_ENTER) 
			FlushKeys
			done = 1
		End If
		Flip
	Until done = 1
End Function


But I havent a clue as to how to accept 5 inputs. Surely i can do this in one function rather than 5 seperate functions for each key.

Any help much appreciated.

Cheers

Kind Regards
Joe


Czar Flavius(Posted 2011) [#2]
Keep accepting input until the length of the string is 5 and then set done to true.

I would use If c >= 48 or c <= 122, you don't need to specify every value.

To clear a string, mystring = ""

An alternative to get the length of a string is mystring.length (no brackets)

Last edited 2011

Last edited 2011


Midimaster(Posted 2011) [#3]
I would do it in a sequence of 10 questions. You display a text and wait for one keystroke, then display the next text and wait for the next keystroke. after 10 texts you will be finished:

this is an easy to understand solution (it could be made more compact, but harder to understand)
Graphics 600,400
Global KeyLeftOne% , KeyTopOne%',.....

'Defaults
KeyLeftOne=Asc("A")
KeyTopOne=Asc("W")
'.... repeat code 8 times...	

ReDefineKeys

DrawText "Finished",100,350
Flip
WaitKey()
End


Function ReDefineKeys()
'
	DrawText "Set Key for Player 1 LEFT: ", 100,100
	Flip
	KeyLeftOne = ExpectKey()
	DrawText Upper(Chr(KeyLeftOne)), 350,100
'
	DrawText "Set Key for Player 1 TOP:", 100,120
	Flip
	KeyLeftOne = ExpectKey()
	DrawText Upper(Chr(KeyTopOne)), 350,120
'
	'.... repeat code 8 times...	
End Function



Function ExpectKey%()
	Local locKey%
	Repeat
		locKey% = GetChar()
	Until locKey<>0 
	Return locKey
End Function


and here is a more compact solution:
SuperStrict
Graphics 600,400
Global KeyLeftOne% , KeyTopOne%',.....

'Defaults
KeyLeftOne=Asc("A")
KeyTopOne=Asc("W")
'.... repeat code 8 times...	

KeyLeftOne = DefineKey("LEFT",1,0)
KeyTopOne = DefineKey("TOP",1,1)
'.... repeat code 8 times...	

DrawText "Finished",100,350
Flip
WaitKey()
End


Function DefineKey%( Text$ , Player%, Pos% )
	Local ReturnKey%
	DrawText "Set Key for Player "+Player + " " + Text, 100,100+Pos*20
	Flip
	ReturnKey = ExpectKey()
	DrawText Upper(Chr(ReturnKey)), 350,100+Pos*20

	Return ReturnKey
End Function



Function ExpectKey%()
	Local locKey%
	Repeat
		locKey% = GetChar()
	Until locKey<>0 
	Return locKey
End Function


You should also think about a way to prevent users double inpute of the same key:

SuperStrict
Graphics 600,400
Global KeyLeftOne% , KeyTopOne% , KeyRightOne% , KeyBottomOne% , KeyFireOne% 
Global KeyLeftTwo% , KeyTopTwo% , KeyRightTwo% , KeyBottomTwo% , KeyFireTwo% 


'Defaults
KeyLeftOne=Asc("A")
KeyTopOne=Asc("W")
'.... repeat code 8 times...	

KeyLeftOne = DefineKey("LEFT",1)
KeyTopOne = DefineKey("TOP",1)
KeyRightOne = DefineKey("RIGHT",1)
KeyBottomOne = DefineKey("BOTTOM",1)
KeyFireOne = DefineKey("FIRE",1)
'
KeyLeftTwo = DefineKey("LEFT",2)
KeyTopTwo = DefineKey("TOP",2)
KeyRightTwo = DefineKey("RIGHT",2)
KeyBottomTwo = DefineKey("BOTTOM",2)
KeyFireTwo = DefineKey("FIRE",2)

DrawText "Finished",100,350
Flip
WaitKey()
End


Function DefineKey%( Text$ , Player%)
	Local ReturnKey% , offX% , X%, Y%
		
	Select Text 
		Case "LEFT"
			x=-1
		Case "TOP"
			Y=-1
		Case "RIGHT"
			X=1
		Case "BOTTOM"
			Y=1
	End Select	

	DrawText "Set Key for Player "+Player, 30+(Player-1)*300 , 100
	DrawText Text, 100+(Player-1)*300+X*70 , 200+Y*50
	Flip
	
	Repeat
		ReturnKey = ExpectKey()
	Until AlreadyUsed(ReturnKey)=0
	
	DrawText Text + "=" + Upper(Chr(ReturnKey)), 100+(Player-1)*300+X*70 , 200+Y*50
	Return ReturnKey
End Function



Function ExpectKey%()
	Local locKey%
	Repeat
		locKey% = GetChar()
	Until locKey<>0 
	Return locKey
End Function


Function AlreadyUsed%(NextKey%)
	Global UsedKeys%[11], i%
	Print "Testing used Keys"
	For  i=0 To 10
		Print " used " + usedkeys[i]
 		If UsedKeys[i]=0 Then Exit 
		
		If NextKey = UsedKeys[i] Then Return 1
	Next	
	Print i
	UsedKeys[i]=NextKey
	Return 0
End Function


Last edited 2011


Joe90bigrat90(Posted 2011) [#4]
Thats pretty cool. Thanks for that. ill maybe make a few adjustments and try and use parts of this in my program.
By the way i want the user to be able to press space for a key and the arrow keys and right control.
How do you actually use the arrow keys cos if you press an arrow key nothing happens. I guess you need to convert (KEY_LEFT) to a key code.
and then print the words "LEFT". Im not sure about the space bar though. If use presses space bar then get the key code for the key and print text SPACE.


Midimaster(Posted 2011) [#5]
GetChar() is the wrong function for this. You better use WaitKey(). This also works on special keys like arrows:

Function ExpectKey%()
	Local locKey%=WaitKey()
	Return locKey
End Function


But this brings no visible results on DrawText. So you have to car about words that represent the keys without own characters

Function DefineKey%( Text$ , Player%)
	Local ReturnKey% , offX% , X%, Y%
...

...
	Repeat
		ReturnKey = ExpectKey()
	Until AlreadyUsed(ReturnKey)=0

	If ReturnKey=32 Then 
		DisplayText = "[SPACE]"		
	ElseIf ReturnKey=37
		DisplayText = "[ARROW LEFT]"		
	ElseIf....

	Else
		DisplayText = Upper(Chr(ReturnKey))	
	EndIf	
	
	DrawText Text + "=" + DisplayText, 100+(Player-1)*300+X*70 , 200+Y*50

	Return ReturnKey
End Function