提问人:Finn 提问时间:11/12/2023 最后编辑:Finn 更新时间:11/13/2023 访问量:93
如何在循环中只执行一次代码行?
how to execute a line of code only once inside of a loop?
问:
初学者在这里,我正在尝试做一个 while true 循环,无限期地读取游戏中的整数值。我想做的是,当该整数 = x 值时,执行某个代码,但只执行一次。
我用了这个代码
while (true)
{
var value = swed.ReadInt(localplayer, offsets.health);
if (value == 70)
{
Console.WriteLine("hello");
}
}
问题是,当值为 70 时,当我只想打印一次时,它会永远打印“hello”。请记住,我希望无限期地读取该值并在其 70 时打印一次“hello”,所以我不能使用 break,否则它只能工作一次。我尝试使用 for 循环,它按照我的意愿打印了该消息一次,但它仅在该值开始时为 70 时才有效。它不会像 While 循环那样连续读取该值。所以我想我需要使用嵌套循环?我尝试了很多不同的东西,到目前为止没有任何效果
答:
-1赞
TP95
11/12/2023
#1
正如评论所建议的,使用一个标志来触发“hello”一次,就像:
var hasExecuted = false;
while (true)
{
var value = swed.ReadInt(localplayer, offsets.health);
if (value == 70 && !hasExecuted)
{
Console.WriteLine("hello");
hasExecuted = true;
}
}
编辑:只是一个小小的疏忽,我将标志更改为循环外。
评论
0赞
Finn
11/12/2023
我试过了这个,一开始的值是 70,它仍然无限期地打印“hello”
0赞
Peppermintology
11/12/2023
hasExectued 应该在循环之外,否则它将始终重置为 false。
1赞
Finn
11/12/2023
你说得对,我把 hasExectued 移出循环后,它打印了一次“hello”。但同样的问题,如果值更改为其他值,然后又变回 70,则不会打印任何内容。所以基本上这与使用 break 相同
-1赞
Naser Hamdan
11/12/2023
#2
如果问题的目的是在值达到 70 时触发某些内容,则应该在属性上设置一个侦听器。
检查以下示例代码,假设它在 Unity 中使用:
using System;
using System.ComponentModel;
public class MyClass : INotifyPropertyChanged
{
private string myAttribute;
public string MyAttribute
{
get { return myAttribute; }
set
{
if (myAttribute != value)
{
myAttribute = value;
OnPropertyChanged(nameof(MyAttribute));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Program
{
public static void Main()
{
MyClass myObject = new MyClass();
myObject.PropertyChanged += MyObject_PropertyChanged;
// Change the attribute value to trigger the event
myObject.MyAttribute = "New value";
}
private static void MyObject_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Function to be triggered when the attribute changes
// Check if the property name is "MyAttribute"
if (e.PropertyName == nameof(MyAttribute))
{
// Get the new value of MyAttribute
string newValue = MyAttribute;
// Perform conditional logic based on the new value
if (newValue == "SomeValue")
{
// Do something when the value is "SomeValue"
Debug.Log("Property value is 'SomeValue'.");
}
else
{
// Do something else when the value is not "SomeValue"
Debug.Log("Property value is not 'SomeValue'.");
}
}
}
0赞
Peppermintology
11/12/2023
#3
如果您只想在输入值为 70 时打印 hello,而不想在值没有更改时打印,但如果它确实更改回 70,则再次打印,那么您可以跟踪以前的值。
var previousValue = 0;
var currentValue = 0;
while (true)
{
currentValue = swed.ReadInt(localPlayer, offsets.health);
if (currentValue == 70 && previousValue != 70)
{
Console.WriteLine(“hello”);
}
previousValue = currentValue;
}
不是最优雅的解决方案,但说明了基本思想。您可以根据需要进行整理。
评论
0赞
Finn
11/12/2023
非常感谢。这确实奏效了!
0赞
Peppermintology
11/12/2023
@Finn 好东西。您可以通过将 if 条件逻辑移动到它自己的方法(如果该逻辑将被重用)来改进它,并使值 70 成为它自己的变量并引用它,这样如果它发生变化,它只会在一个地方发生变化,但会在任何地方更新。
0赞
Javad J
11/12/2023
#4
多亏了@TP95,他/她的代码可以稍作更改以支持您的问题:
var hasExecuted = false;
while (true)
{
var value = swed.ReadInt(localplayer, offsets.health);
if (value == 70 && !hasExecuted)
{
Console.WriteLine("hello");
hasExecuted = true;
}
if (value != 70 && hasExecuted)
{
hasExecuted = false;
}
}
对不起,我无法对您的答案发表评论。
评论