Temple of The Roguelike Forums
Development => Programming => Topic started by: Shaggy on October 02, 2012, 09:47:42 PM
-
For some unknown reason, the select-case used for my player input started acting up today. It still works perfectly for all of the UI Menus (inventory, dropping, etc), but refuses to work for movement (any of the NumPad keys).
I added a debugging line of code to write the console.readkey.key value to the console's title if an extra key was pressed. Even after I manually added the integer values for the keys (IE "or 39 or 102"), the player does not get moved, instead it always ends up at the last "Case else".
Module modInput
Public Sub TakeInput()
Dim keyInput As ConsoleKeyInfo
Dim ThisActionsCost As Integer = 0
Dim InputIndex As Integer
Dim bContinue As Boolean
bContinue = True
keyInput = Console.ReadKey(True)
'Processing
Select Case keyInput.Key
Case ConsoleKey.Escape
If Player.State = "OnMap" Then
bContinue = False
End
Else
InputIndex = 0
End If
Case ConsoleKey.NumPad7 Or 36
If Player.State = "OnMap" Then
Player.Move("NW")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 27
End If
Case ConsoleKey.NumPad8 Or 38 Or 104
If Player.State = "OnMap" Then
Player.Move("N")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 28
End If
Case ConsoleKey.NumPad9 Or 33
If Player.State = "OnMap" Then
Player.Move("NE")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 29
End If
Case ConsoleKey.NumPad4 Or 37 Or 100
If Player.State = "OnMap" Then
Player.Move("W")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 30
End If
Case ConsoleKey.NumPad6 Or 39 Or 102
If Player.State = "OnMap" Then
Player.Move("E")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 31
End If
Case ConsoleKey.NumPad1 Or 35
If Player.State = "OnMap" Then
Player.Move("SW")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 32
End If
Case ConsoleKey.NumPad2 Or 40 Or 98
If Player.State = "OnMap" Then
Player.Move("S")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 33
End If
Case ConsoleKey.NumPad3 Or 34
If Player.State = "OnMap" Then
Player.Move("SE")
ThisActionsCost = 10
bContinue = False
Else
InputIndex = 34
End If
Case ConsoleKey.A
InputIndex = 1
Case ConsoleKey.B
InputIndex = 2
Case ConsoleKey.C
InputIndex = 3
Case ConsoleKey.D
If Player.State = "OnMap" Then
Scene_Drop()
ThisActionsCost = 5
bContinue = False
Else
InputIndex = 28
End If
Case ConsoleKey.E
InputIndex = 5
Case ConsoleKey.F
InputIndex = 6
Case ConsoleKey.G
If Player.State = "OnMap" Then
GetItem(Player.X, Player.Y)
ThisActionsCost = 5
bContinue = False
Else
InputIndex = 28
End If
'DEBUGGING
Case ConsoleKey.F1
Generate()
'find stairs up, set as starting pos
For intX = 0 To 41
For intY = 0 To 69
If Map.Tiles(intX, intY).ID = 6 Then
Player.X = intX
Player.Y = intY
End If
Next
Next
Console.Clear()
Map.Display()
Refresh()
bContinue = False
Case ConsoleKey.F2
If Player.State = "OnMap" Then
Scene_MsgHistory()
bContinue = False
End If
Case ConsoleKey.H
InputIndex = 8
Case ConsoleKey.I
If Player.State = "OnMap" Then
Scene_Inventory()
bContinue = False
Else
InputIndex = 28
End If
Case ConsoleKey.J
InputIndex = 10
Case ConsoleKey.K
InputIndex = 11
Case ConsoleKey.L
InputIndex = 12
Case ConsoleKey.M
InputIndex = 13
Case ConsoleKey.N
InputIndex = 14
Case ConsoleKey.O
InputIndex = 15
Case ConsoleKey.P
InputIndex = 16
Case ConsoleKey.Q
InputIndex = 17
Case ConsoleKey.R
InputIndex = 18
Case ConsoleKey.S
InputIndex = 19
Case ConsoleKey.T
InputIndex = 20
Case ConsoleKey.U
If Player.State = "OnMap" Then
Scene_UseItem()
ThisActionsCost = 5
bContinue = False
Else
InputIndex = 28
End If
Case ConsoleKey.V
InputIndex = 22
Case ConsoleKey.W
InputIndex = 23
Case ConsoleKey.X
InputIndex = 24
Case ConsoleKey.Y
InputIndex = 25
Case ConsoleKey.Z
InputIndex = 26
Case Else
Console.Title = keyInput.Key & " / " & Player.State
End Select
If bContinue = False Then
Player.SpeedPoints = Player.SpeedPoints - ThisActionsCost
Else
'Off-Map Actions
Select Case UCase(Player.State)
Case "INDETAILS"
'does things (taken out so it's not so lengthy.)
Case "INDROP"
'does things (taken out so it's not so lengthy.)
Case "INHISTORY"
'does things (taken out so it's not so lengthy.)
Case "ININVENTORY"
'does things (taken out so it's not so lengthy.)
Case "INUSEITEM"
'does things (taken out so it's not so lengthy.)
End Select
End If
End Sub
-
Numlock? ;)
-
That ended up being the problem, but I still don't understand why none of the OR statements caught it. I got those integer values from the "else, console.title = keyinput.key" statement, yet they were ignored.
-
'Or' does not work with 'Case', at least not the way you probably expected. Use comma instead, for instance:
Case ConsoleKey.NumPad3, 34
-
I've never used VB.Net but I did use VB6 and I vaguely recall you could use the Or keyword for both logical or bitwise or and the compiler decided which based on context.
I don't know if it's the same with VB.Net, but in this case it does look like the Or operator in a case statement is bitwise. There's another operator OrElse for logical or.
So the line:
Case ConsoleKey.NumPad8 Or 38 Or 104
is basically getting resolved as
Case 110
because 38 bitwise or 104 is 110:
100110 = 38
1101000 = 104
----------------------- OR
1101110 = 110
So the case block would have never hit because 110 was never coming through (110 is ConsoleKey.BrowserBack)
Perhaps OrElse would have worked, although I don't know if VB.Net allows logical or in case statements, I don't think c# does.
Case ConsoleKey.NumPad8 OrElse 38 OrElse 104
As for why it didn't work originally, I don't know but I would guess that with numlock on Console.ReadKey() returns ConsoleKey.NumPad0 thru NumPad9 for those keys but with numlock off it returns ConsoleKey.D0 thru D9 (or perhaps the otherway round)
-
Ahhh. That does make sense. Sometimes programming languages make me forget that the hardware still looks at everything on a binary level :p
I'll check whether or not I can do OrElse in a case statement, but I think you're correct in saying I can't.