Building a roguelike in F# from scratch - Multi Key Commands
Introduction
Recursion really is a thing of beauty :)
I have updated the player command generator so it will handle commands that take multiple key presses. The working commands are now:
- W - Up
- A - Left
- S - Down
- D - Right
- Space - Idle
- O + [WASD] - Open the door in that direction
- C + [WASD] - Close the door in that direction
Reading the keyboard
The change to implement this was so simple in the end. There is a new function called handleKeyPress, this handles all the building. It is called initially with a None command builder.
- If W,A,S,D or Space are pressed it calls selectActorCommand, which you saw last time.
- If O or C are pressed it calls back into itself with the related builder. Next time if W,A,S or D are pressed it will build the Open or Close command in that direction.
let selectCommand validator operation direction actorId level =
level
|> validator direction actorId
|> bind (fun l -> operation direction actorId l)
let private selectActorCommand direction actorId level =
resultOrElse {
return! selectCommand isValidMove buildMoveActorCommand direction actorId level
return! selectCommand canOpenDoor buildOpenDoorCommand direction actorId level
return! (invalidCommand level)
}
let rec handleKeyPress activeBuilder actorId =
let workingBuilder =
match activeBuilder with
| Some builder -> builder
| None -> selectActorCommand
match Console.ReadKey().Key with
| ConsoleKey.O -> handleKeyPress (Some buildOpenDoorCommand) actorId
| ConsoleKey.C -> handleKeyPress (Some buildCloseDoorCommand) actorId
| ConsoleKey.W -> workingBuilder north actorId
| ConsoleKey.A -> workingBuilder west actorId
| ConsoleKey.S -> workingBuilder south actorId
| ConsoleKey.D -> workingBuilder east actorId
| ConsoleKey.Spacebar -> idleCommand
| _ -> invalidCommand
let getPlayerCommand actorId = handleKeyPress None actorId
The only issue at the moment is termination if the player holders down O or C, that should not be an issue as this should be tail call recursive. If this proves to be incorrect I will need to revisit it. Good enough for now.
Summary
Short one today, but nice simple change that gives a lot of power for very little work. Most of it already existed just needed moving around a bit :)
And for those who have only just found the series, here is the story so far for Building a roguelike in F# from scratch :
- Introduction
- Repo and Initial Types
- First Problems
- Level Queries
- CRUD Operations
- Validation
- Game Loop Time
- It's ALIVE
- Working Doors
Finally the GitHub Repo
Feel free to ask questions and happy coding :)
Woz
Congratulations @woz.software! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of comments
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP