26_ConsoleInput.lua 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 = "LuaScript"
  44. console.visible = true
  45. console.closeButton.visible = false
  46. -- Show OS mouse cursor
  47. input.mouseVisible = true
  48. -- Open the operating system console window (for stdin / stdout) if not open yet
  49. -- Do not open in fullscreen, as this would cause constant device loss
  50. if not graphics.fullscreen then
  51. OpenConsoleWindow()
  52. end
  53. -- Initialize game and print the welcome message
  54. StartGame()
  55. -- Randomize from system clock
  56. SetRandomSeed(time:GetSystemTime())
  57. end
  58. function HandleConsoleCommand(eventType, eventData)
  59. if eventData:GetString("Id") == "LuaScript" then
  60. HandleInput(eventData:GetString("Command"))
  61. end
  62. end
  63. function HandleUpdate(eventType, eventData)
  64. -- Check if there is input from stdin
  65. local input = GetConsoleInput()
  66. if input:len() > 0 then
  67. HandleInput(input)
  68. end
  69. end
  70. function HandleEscKeyDown(eventType, eventData)
  71. -- Unlike the other samples, exiting the engine when ESC is pressed instead of just closing the console
  72. if eventData:GetInt("Key") == KEY_ESC then
  73. engine:Exit()
  74. end
  75. end
  76. function StartGame()
  77. Print("Welcome to the Urho adventure game! You are the newest fish in the tank your\n" ..
  78. "objective is to survive as long as possible. Beware of hunger and the merciless\n" ..
  79. "predator cichlid Urho, who appears from time to time. Evading Urho is easier\n" ..
  80. "with an empty stomach. Type 'help' for available commands.")
  81. gameOn = true
  82. foodAvailable = false
  83. eatenLastTurn = false
  84. numTurns = 0
  85. hunger = 2
  86. urhoThreat = 0
  87. end
  88. function EndGame(message)
  89. Print(message)
  90. Print("Game over! You survived " .. numTurns .. " turns.\n" ..
  91. "Do you want to play again (Y/N)?")
  92. gameOn = false
  93. end
  94. function Advance()
  95. if urhoThreat > 0 then
  96. urhoThreat = urhoThreat + 1
  97. if urhoThreat > 3 then
  98. EndGame("Urho has eaten you!")
  99. return
  100. end
  101. elseif urhoThreat < 0 then
  102. urhoThreat = urhoThreat + 1
  103. elseif urhoThreat == 0 and Random() < 0.2 then
  104. urhoThreat = urhoThreat + 1
  105. end
  106. if urhoThreat > 0 then
  107. Print(urhoThreatLevels[urhoThreat] .. ".")
  108. end
  109. if (numTurns % 4) == 0 and not eatenLastTurn then
  110. hunger = hunger + 1
  111. if hunger > 5 then
  112. EndGame("You have died from starvation!")
  113. return
  114. else
  115. Print("You are " .. hungerLevels[hunger + 1] .. ".")
  116. end
  117. end
  118. eatenLastTurn = false
  119. if foodAvailable then
  120. Print("The floating pieces of fish food are quickly eaten by other fish in the tank.")
  121. foodAvailable = false
  122. elseif Random() < 0.15 then
  123. Print("The overhead dispenser drops pieces of delicious fish food to the water!")
  124. foodAvailable = true
  125. end
  126. numTurns = numTurns + 1
  127. end
  128. function TrimInput(input)
  129. return input:gsub("^%s*(.-)%s*$", "%1")
  130. end
  131. function HandleInput(input)
  132. local inputLower = TrimInput(input:lower())
  133. if inputLower:len() == 0 then
  134. Print("Empty input given!")
  135. return
  136. end
  137. if inputLower == "quit" or inputLower == "exit" then
  138. engine:Exit()
  139. elseif gameOn then
  140. -- Game is on
  141. if inputLower == "help" then
  142. Print("The following commands are available: 'eat', 'hide', 'wait', 'score', 'quit'.")
  143. elseif inputLower == "score" then
  144. Print("You have survived " .. numTurns .. " turns.")
  145. elseif inputLower == "eat" then
  146. if foodAvailable then
  147. Print("You eat several pieces of fish food.")
  148. foodAvailable = false
  149. eatenLastTurn = true
  150. if hunger > 3 then
  151. hunger = hunger - 2
  152. else
  153. hunger = hunger - 1
  154. end
  155. if hunger < 0 then
  156. EndGame("You have killed yourself by over-eating!")
  157. return
  158. else
  159. Print("You are now " .. hungerLevels[hunger + 1] .. ".")
  160. end
  161. else
  162. Print("There is no food available.")
  163. end
  164. Advance()
  165. elseif inputLower == "wait" then
  166. Print("Time passes...")
  167. Advance()
  168. elseif inputLower == "hide" then
  169. if urhoThreat > 0 then
  170. local evadeSuccess = hunger > 2 or Random() < 0.5
  171. if evadeSuccess then
  172. Print("You hide behind the thick bottom vegetation, until Urho grows bored.")
  173. urhoThreat = -2
  174. else
  175. Print("Your movements are too slow you are unable to hide from Urho.")
  176. end
  177. else
  178. Print("There is nothing to hide from.")
  179. end
  180. Advance()
  181. else
  182. Print("Cannot understand the input '" .. input .. "'.")
  183. end
  184. else
  185. -- Game is over, wait for (y)es or (n)o reply
  186. local c = inputLower:sub(1, 1)
  187. if c == 'y' then
  188. StartGame()
  189. elseif c == 'n' then
  190. engine:Exit()
  191. else
  192. Print("Please answer 'y' or 'n'.")
  193. end
  194. end
  195. end
  196. function Print(input)
  197. -- Logging appears both in the engine console and stdout
  198. Log:WriteRaw(input .. "\n")
  199. end
  200. -- Create XML patch instructions for screen joystick layout specific to this sample app
  201. function GetScreenJoystickPatchString()
  202. return
  203. "<patch>" ..
  204. " <add sel=\"/element/element[./attribute[@name='Name' and @value='Button2']]\">" ..
  205. " <attribute name=\"Is Visible\" value=\"false\" />" ..
  206. " </add>" ..
  207. " <add sel=\"/element/element[./attribute[@name='Name' and @value='Hat0']]\">" ..
  208. " <attribute name=\"Is Visible\" value=\"false\" />" ..
  209. " </add>" ..
  210. "</patch>"
  211. end