26_ConsoleInput.lua 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. -- Console input example.
  2. -- This sample demonstrates:
  3. -- - Implementing a crude text adventure game, which accepts input both through the engine console,
  4. -- and standard input.
  5. -- - Disabling default execution of console commands as immediate mode Lua script.
  6. require "LuaScripts/Utilities/Sample"
  7. local gameOn = false
  8. local foodAvailable = false
  9. local eatenLastTurn = false
  10. local numTurns = 0
  11. local hunger = 0
  12. local urhoThreat = 0
  13. -- Hunger level descriptions
  14. local hungerLevels = {
  15. "bursting",
  16. "well-fed",
  17. "fed",
  18. "hungry",
  19. "very hungry",
  20. "starving"
  21. }
  22. -- Urho threat level descriptions
  23. local urhoThreatLevels = {
  24. "Suddenly Urho appears from a dark corner of the fish tank",
  25. "Urho seems to have his eyes set on you",
  26. "Urho is homing in on you mercilessly"
  27. }
  28. function Start()
  29. -- Execute the common startup for samples
  30. SampleStart()
  31. -- Disable default execution of Lua from the console
  32. SetExecuteConsoleCommands(false)
  33. -- Subscribe to console commands and the frame update
  34. SubscribeToEvent("ConsoleCommand", "HandleConsoleCommand")
  35. SubscribeToEvent("Update", "HandleUpdate")
  36. -- Subscribe key down event
  37. SubscribeToEvent("KeyDown", "HandleEscKeyDown")
  38. -- Hide logo to make room for the console
  39. SetLogoVisible(false)
  40. -- Show the console by default, make it large
  41. console.numRows = graphics.height / 16
  42. console.numBufferedRows = 2 * console.numRows
  43. console.commandInterpreter = "LuaScriptEventInvoker"
  44. console.visible = true
  45. console.closeButton.visible = false
  46. -- Show OS mouse cursor
  47. input.mouseVisible = true
  48. -- Set the mouse mode to use in the sample
  49. SampleInitMouseMode(MM_FREE)
  50. -- Open the operating system console window (for stdin / stdout) if not open yet
  51. -- Do not open in fullscreen, as this would cause constant device loss
  52. if not graphics.fullscreen then
  53. OpenConsoleWindow()
  54. end
  55. -- Initialize game and print the welcome message
  56. StartGame()
  57. -- Randomize from system clock
  58. SetRandomSeed(Time:GetSystemTime())
  59. end
  60. function HandleConsoleCommand(eventType, eventData)
  61. if eventData["Id"]:GetString() == "LuaScriptEventInvoker" then
  62. HandleInput(eventData["Command"]:GetString())
  63. end
  64. end
  65. function HandleUpdate(eventType, eventData)
  66. -- Check if there is input from stdin
  67. local input = GetConsoleInput()
  68. if input:len() > 0 then
  69. HandleInput(input)
  70. end
  71. end
  72. function HandleEscKeyDown(eventType, eventData)
  73. -- Unlike the other samples, exiting the engine when ESC is pressed instead of just closing the console
  74. if eventData["Key"]:GetInt() == KEY_ESCAPE then
  75. engine:Exit()
  76. end
  77. end
  78. function StartGame()
  79. print("Welcome to the Urho adventure game! You are the newest fish in the tank your\n" ..
  80. "objective is to survive as long as possible. Beware of hunger and the merciless\n" ..
  81. "predator cichlid Urho, who appears from time to time. Evading Urho is easier\n" ..
  82. "with an empty stomach. Type 'help' for available commands.")
  83. gameOn = true
  84. foodAvailable = false
  85. eatenLastTurn = false
  86. numTurns = 0
  87. hunger = 2
  88. urhoThreat = 0
  89. end
  90. function EndGame(message)
  91. print(message)
  92. print("Game over! You survived " .. numTurns .. " turns.\n" ..
  93. "Do you want to play again (Y/N)?")
  94. gameOn = false
  95. end
  96. function Advance()
  97. if urhoThreat > 0 then
  98. urhoThreat = urhoThreat + 1
  99. if urhoThreat > 3 then
  100. EndGame("Urho has eaten you!")
  101. return
  102. end
  103. elseif urhoThreat < 0 then
  104. urhoThreat = urhoThreat + 1
  105. elseif urhoThreat == 0 and Random() < 0.2 then
  106. urhoThreat = urhoThreat + 1
  107. end
  108. if urhoThreat > 0 then
  109. print(urhoThreatLevels[urhoThreat] .. ".")
  110. end
  111. if (numTurns % 4) == 0 and not eatenLastTurn then
  112. hunger = hunger + 1
  113. if hunger > 5 then
  114. EndGame("You have died from starvation!")
  115. return
  116. else
  117. print("You are " .. hungerLevels[hunger + 1] .. ".")
  118. end
  119. end
  120. eatenLastTurn = false
  121. if foodAvailable then
  122. print("The floating pieces of fish food are quickly eaten by other fish in the tank.")
  123. foodAvailable = false
  124. elseif Random() < 0.15 then
  125. print("The overhead dispenser drops pieces of delicious fish food to the water!")
  126. foodAvailable = true
  127. end
  128. numTurns = numTurns + 1
  129. end
  130. function TrimInput(input)
  131. return input:gsub("^%s*(.-)%s*$", "%1")
  132. end
  133. function HandleInput(input)
  134. local inputLower = TrimInput(input:lower())
  135. if inputLower:len() == 0 then
  136. print("Empty input given!")
  137. return
  138. end
  139. if inputLower == "quit" or inputLower == "exit" then
  140. engine:Exit()
  141. elseif gameOn then
  142. -- Game is on
  143. if inputLower == "help" then
  144. print("The following commands are available: 'eat', 'hide', 'wait', 'score', 'quit'.")
  145. elseif inputLower == "score" then
  146. print("You have survived " .. numTurns .. " turns.")
  147. elseif inputLower == "eat" then
  148. if foodAvailable then
  149. print("You eat several pieces of fish food.")
  150. foodAvailable = false
  151. eatenLastTurn = true
  152. if hunger > 3 then
  153. hunger = hunger - 2
  154. else
  155. hunger = hunger - 1
  156. end
  157. if hunger < 0 then
  158. EndGame("You have killed yourself by over-eating!")
  159. return
  160. else
  161. print("You are now " .. hungerLevels[hunger + 1] .. ".")
  162. end
  163. else
  164. print("There is no food available.")
  165. end
  166. Advance()
  167. elseif inputLower == "wait" then
  168. print("Time passes...")
  169. Advance()
  170. elseif inputLower == "hide" then
  171. if urhoThreat > 0 then
  172. local evadeSuccess = hunger > 2 or Random() < 0.5
  173. if evadeSuccess then
  174. print("You hide behind the thick bottom vegetation, until Urho grows bored.")
  175. urhoThreat = -2
  176. else
  177. print("Your movements are too slow you are unable to hide from Urho.")
  178. end
  179. else
  180. print("There is nothing to hide from.")
  181. end
  182. Advance()
  183. else
  184. print("Cannot understand the input '" .. input .. "'.")
  185. end
  186. else
  187. -- Game is over, wait for (y)es or (n)o reply
  188. local c = inputLower:sub(1, 1)
  189. if c == 'y' then
  190. StartGame()
  191. elseif c == 'n' then
  192. engine:Exit()
  193. else
  194. print("Please answer 'y' or 'n'.")
  195. end
  196. end
  197. end
  198. -- Create XML patch instructions for screen joystick layout specific to this sample app
  199. function GetScreenJoystickPatchString()
  200. return
  201. "<patch>" ..
  202. " <add sel=\"/element/element[./attribute[@name='Name' and @value='Button2']]\">" ..
  203. " <attribute name=\"Is Visible\" value=\"false\" />" ..
  204. " </add>" ..
  205. " <add sel=\"/element/element[./attribute[@name='Name' and @value='Hat0']]\">" ..
  206. " <attribute name=\"Is Visible\" value=\"false\" />" ..
  207. " </add>" ..
  208. "</patch>"
  209. end