In-Game Shortcuts
While in game you can use the following reserved keyboard shortcuts. Note that these keys are NOT available to the game itself as they are intercepted and processed by the game engine itself:
*.xp
format saved in the current folder. Accepting a text input from the user is rather tricky in ASCII games - this is one of those quirks that needs to be worked out. The obvious problem here is the fact that we render the game on the same terminal from which we have to read the keyboard user input. When you work in the terminal - most of the time you work via command line shells (like sh
, ws
, fish
, zsh
, etc.) which provides such functionality for cursor movements, Backspace and Del key handling, Tab focus movements, etc.
In CosPlay one could implement all this support in a special sprite as well. To make the handling of the user input easy out-of-the-box, CosPlay comes with built-in CPTextInputSprite sprite that implements a comprehensive functionality for accepting user keyboard input.
Remapped Keys
The following keystrokes are automatically re-mapped:
NOTE: Ctrl+h, Ctrl+i and Ctrl+m will not be detected as-is, and you should use their conversions instead. Note that even-though CPKeyboardKey provides constants these keys they will never be returned to the scene objects since they would always be automatically remapped. This is an inherent limitation of the ANSI terminals.
CPTextInputSprite
The CPTextInputSprite sprite acts as a classic input field: user can input text using keyboard and cursor keys. It supports different field and buffer lengths, skinning input (e.g. for the password field) as well as user-defined set of keys for submission and cancellation. You can also chain multiple text inputs together to create an auto-navigable forms. Note that this sprite works only with system font - you can't use FIGLeft fonts with this sprite.
To understand the API of CPTextInputSprite sprite let's look at the full example of implementing a standard login dialog that prompts the user to enter the username and password:
import org.cosplay.* import CPColor.* import CPPixel.* import CPFIGLetFont.* import CPKeyboardKey.* import CPStyledString.styleStr import examples.utils.* import prefabs.shaders.* object LoginDialog: def main(args: Array[String]): Unit = val termDim = CPDim(100, 40) def mkSkin(active: Boolean, passwd: Boolean): (Char, Int, Boolean) => CPPixel = (ch: Char, pos: Int, isCur: Boolean) => { val ch2 = if passwd && !ch.isWhitespace then '*' else ch if active then if isCur then ch2&&(C_WHITE, C_SLATE_BLUE3) else ch2&&(C_BLACK, C_WHITE) else ch2&&(C_BLACK, C_WHITE.darker(0.3f)) } val userLbl = new CPLabelSprite(6, 4, 1, text = "Username:", C_LIGHT_STEEL_BLUE) val userTin = CPTextInputSprite("user", 6, 5, 1, 15, 20, "", mkSkin(true, false), mkSkin(false, false), submitKeys = Seq(KEY_ENTER, KEY_TAB), next = Option("passwd") ) val pwdLbl = new CPLabelSprite(6, 7, 1, text = "Password:", C_LIGHT_STEEL_BLUE) val pwdTin = CPTextInputSprite("passwd", 6, 8, 1, 15, 20, "", mkSkin(true, true), mkSkin(false, true), submitKeys = Seq(KEY_ENTER, KEY_TAB), next = Option("user") ) val panel = CPPanelSprite(2, 2, 24, 11, 0, "Login") val focusAcq = CPOffScreenSprite(ctx ⇒ if ctx.getSceneFrameCount == 0 then ctx.acquireFocus("user")) val bgPx = '.'&&(C_GRAY2, C_GRAY1) val sc = new CPScene("scene", Option(CPDim(27, 13)), bgPx, userLbl, userTin, pwdLbl, pwdTin, panel, focusAcq ) // Initialize the engine. CPEngine.init( CPGameInfo(name = "Login Dialog", initDim = Option(termDim)), System.console() == null || args.contains("emuterm") ) // Start the game & wait for exit. try CPEngine.startGame(sc) finally CPEngine.dispose() sys.exit(0)
NOTE:
'*'
.CPPanelSprite
utility sprite on the line 41 that is part of examples. It draws a simple panel with a titled border.When you run this example (see a similar built-in example) you will get the following output:
CPTextInputSprite