如何在Do循环中等待用户输入?VB.NET文本游戏开发问题
Hey there, let's break down why your current code isn't running as expected and get it working properly. I spot three critical problems that are blocking your progress:
1. Blocking the UI Thread with a Do Loop in frmMain_Load
Your Do...Loop runs immediately when the form loads, and since it’s on the UI thread, it completely freezes the interface. Users can’t click the button or type anything because the thread is stuck in the loop—this is why your code won’t behave like you expect.
2. Input Variable Scope Mismatch
In your btnEnter_Click event, you declare a local input variable (Dim input As String = Me.txtInput.Text), but your class-level input variable is never updated. The loop in frmMain_Load checks an unassigned variable, so none of your direction logic will ever trigger.
3. Repeating Initial Room Text
Every iteration of the loop would add "You awake in a room of darkness." to the list box, which would spam the output even if you fixed the loop issue.
Corrected Code
Here's a revised version that fixes these problems, with comments explaining key changes:
Public Class frmMain Const north As String = "n" Const east As String = "e" Const west As String = "w" Const south As String = "s" ' Class-level input variable (now updated on button click) Dim input As String Dim finished As Boolean = False ' Track current room state Dim spawnpoint As Boolean = True Dim spawnpointN As Boolean = False Dim spawnpointE As Boolean = False Dim spawnpointW As Boolean = False Dim spawnpointS As Boolean = False Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load AcceptButton = btnEnter ' Add initial room description ONCE when the form loads lstDisplay.Items.Add("You awake in a room of darkness.") lstDisplay.TopIndex = lstDisplay.Items.Count - 1 End Sub Private Sub btnEnter_Click(sender As Object, e As EventArgs) Handles btnEnter.Click ' Skip empty input to avoid unnecessary logic If String.IsNullOrWhiteSpace(txtInput.Text) Then Return ' Update class-level input with user's trimmed, lowercase input input = txtInput.Text.Trim().ToLower() ' Add user's command to the display lstDisplay.Items.Add(input) txtInput.Clear() ' Handle commands only if the game isn't finished If Not finished Then HandleRoomLogic() End If ' Auto-scroll to the latest entry lstDisplay.TopIndex = lstDisplay.Items.Count - 1 End Sub ' Separated method to clean up room state handling Private Sub HandleRoomLogic() Select Case True Case spawnpoint ' Handle input while in the starting dark room Select Case input Case north spawnpoint = False spawnpointN = True lstDisplay.Items.Add("You move north into a dimly lit stone chamber.") Case east spawnpoint = False spawnpointE = True lstDisplay.Items.Add("You move east into a room filled with echoing drips.") Case south spawnpoint = False spawnpointS = True lstDisplay.Items.Add("You move south into a room with a faint floral scent.") Case west spawnpoint = False spawnpointW = True lstDisplay.Items.Add("You move west into a cold, drafty corridor.") Case "end" finished = True lstDisplay.Items.Add("You have finished my game!") Case Else lstDisplay.Items.Add("I don't understand that command. Try n/e/s/w or 'end' to quit.") End Select Case spawnpointN ' Handle input while in the north room Select Case input Case south spawnpointN = False spawnpoint = True lstDisplay.Items.Add("You head back to the dark starting room.") Case "end" finished = True lstDisplay.Items.Add("You have finished my game!") Case Else lstDisplay.Items.Add("You can only go south from here, or type 'end' to quit.") End Select ' Add similar logic for east, west, south rooms below Case spawnpointE lstDisplay.Items.Add("East room: You hear distant voices. Type 'w' to go back.") If input = west Then spawnpointE = False spawnpoint = True End If Case spawnpointW lstDisplay.Items.Add("West room: A rusted door creaks nearby. Type 'e' to go back.") If input = east Then spawnpointW = False spawnpoint = True End If Case spawnpointS lstDisplay.Items.Add("South room: Sunlight filters through a crack. Type 'n' to go back.") If input = north Then spawnpointS = False spawnpoint = True End If End Select End Sub End Class
Key Changes Explained
- Removed the blocking loop: Instead of using a
Do...Loopto wait for input, we handle all logic in thebtnEnter_Clickevent. This keeps the UI responsive, and we only process input when the user submits a command. - Fixed input scope: The class-level
inputvariable is now updated with the user’s input every time they click Enter, so our room logic can access it correctly. - Cleaned up room logic: The
HandleRoomLogicmethod makes the code easier to read and expand as you add more rooms. - Added user feedback: We now catch unrecognized commands and skip empty inputs, so players know what’s expected.
- Initial room text only once: The starting description is added just when the form loads, not repeatedly.
内容的提问来源于stack exchange,提问作者Pierci

