这真的让我感到沮丧。
基本上,这是我为GTA IV编写的脚本的一部分(当它完成时我可能会在我的网站上发布mod)并且我需要在用户按下游戏中定义的键时退出此循环。当然,我无法使用KeyPreview
因为这是类库(GTA IV插件必须使用.net.dll)。
这是我到目前为止所尝试的内容(显然不是完整代码),正如许多网站所建议的那样:
循环:
Sub CarFunctions()
Dim veh = Player.Character.CurrentVehicle
Do
Application.DoEvents()
If CancelLoop = True Then
Exit Do
End If
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, True)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 1)
Wait(500)
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, False)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 2)
Wait(500)
Loop
End Sub
KeyDown事件:
Private Sub VehicleControls_KeyDown(sender As Object, e As GTA.KeyEventArgs) Handles Me.KeyDown
Try
Dim veh = Player.Character.CurrentVehicle
If e.Key = Keys.NumPad5 Then
CancelLoop = True
End If
Catch ex As Exception
Game.Console.Print(ex.ToString)
End Try
End Sub
我知道,问题是程序在循环中没有检测到任何按键事件。我尝试使用多线程,但它在游戏中引发异常,我不能使用调用方法。
提前谢谢。
答案 0 :(得分:0)
一般来说,“退出控制结构”关键词,例如exit do,应该避免使用。
https://msdn.microsoft.com/en-us/library/eked04a7.aspx
Dim index As Integer = 0
Do
Debug.Write(index.ToString & " ")
index += 1
Loop Until index > 10
我认为循环直到你正在寻找。您可能必须使用while循环而不是do while来支持您的特定逻辑。这是我的尝试。
Sub CarFunctionsTask()
Task.Factory.StartNew(Sub()
Dim veh = Player.Character.CurrentVehicle
Do
If CancelLoop = False Then
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, True)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 1)
Wait(500)
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, False)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 2)
Wait(500)
End If
Loop Until CancelLoop
End Sub)
End Sub
答案 1 :(得分:0)
我认为codemonkeyliketab接近答案,因为循环需要在后台线程上运行才能阻止keypress事件。我会推荐类似于他所做的事情,但使用调用上下文来执行Native.Function.Call
行,如下所示:
Sub CarFunctions()
Dim veh = Player.Character.CurrentVehicle
Dim callingContext = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext
System.Threading.Tasks.Task.Factory.StartNew(
Sub()
While CancelLoop = False
Dim t As Task
t = System.Threading.Tasks.Task.Factory.StartNew(
Sub()
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, True)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 1)
End Sub,
System.Threading.CancellationToken.None,
System.Threading.Tasks.TaskCreationOptions.None,
callingContext)
t.Wait()
Wait(500)
t = System.Threading.Tasks.Task.Factory.StartNew(
Sub()
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, False)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 2)
End Sub,
System.Threading.CancellationToken.None,
System.Threading.Tasks.TaskCreationOptions.None,
callingContext)
t.Wait()
Wait(500)
End While
End Sub)
End Sub
答案 2 :(得分:0)
在Mike Guthrie和codemonkeyliketab的帮助下,我设法通过在循环中使用isKeyPressed()
来解决问题(不是很完美):
Do
If Me.isKeyPressed(Keys.Decimal) Then
Exit Do
End If
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, True)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 1)
Wait(500)
Native.Function.Call("SET_VEH_INDICATORLIGHTS", veh, False)
Native.Function.Call("FORCE_CAR_LIGHTS", veh, 2)
Wait(500)
Loop
感谢您的所有答案。