gpt4 book ai didi

C# Windows 窗体应用程序函数循环

转载 作者:行者123 更新时间:2023-11-30 17:40:33 24 4
gpt4 key购买 nike

必须将我在控制台应用程序中创建的 RPG 游戏转换为 Windows 窗体应用程序以用于编程入门类(class)。一切都按预期进行,但后来我陷入了改造战斗系统的困境。下面是调用战斗函数的按钮点击事件和战斗函数:

private void btStoryProgression_Click(object sender, EventArgs e)
{
{...}

else if (flagControl == 20)
{
Enemy enemy = new Enemy("Hellhound", "Oblivion Cave", 1);

if (combat(player, enemy) == true)
{
Lines.Text += "You won!\n";
player.itemList.Add(new Item("Fruit", 22));
}
else
{
Lines.Text = "YOU DIED.";
Lines.Text += "GAME OVER.";
return;
}
}
}


bool combat(Player player, Enemy enemy)
{
Lines.Text = enemy.getName() + " appeared!\n";
int damage;
bool battle = true;
int battleChoice = 0, itemChoice = -1;

turns = 0;
Lines.Text += "What are you going to do?";
buttonVisibility();
buttonChoices("Attack", "Item");

while (battle)
{
if (player.getSpeed() > enemy.getSpeed())
{
//Player turn
if (battleChoice == 1)
{
Lines.Text = player.getName() + " attacked!\n";

if (player.getAccuracy() < 100)
{
Random rnd = new Random();
if (rnd.Next(1, 100) > player.getAccuracy())
{
Lines.Text += "The attack missed!\n";
goto enemyturn;
}
}


damage = player.getAtk() - enemy.getDef();
if (damage < 0)
damage = 0;
enemy.setHP(enemy.getHP() - damage);
if (enemy.getHP() < 0)
enemy.setHP(0);

Lines.Text += "You dealt " + damage + " damage to " + enemy.getName();
Lines.Text += "Enemy HP is now " + enemy.getHP();

if (enemy.getHP() == 0)
return true;
}
else if (battleChoice == 2)
{
Lines.Text += "Your items: ";
foreach (Item item in player.itemList)
{
Lines.Text += item.getName();
}
Lines.Text += "Choose a number based on the order the items appeared";
try
{
do
{
itemChoice = Convert.ToInt32(Console.ReadLine());
itemChoice--;

} while (itemChoice > player.itemList.Count());
}
catch (FormatException)
{
Console.WriteLine("SOMETHING WRONG!!");
}

Lines.Text += "Player HP was: " + player.getHP();
player.setHP(player.getHP() + player.itemList[itemChoice].getRecoverQtd());
Lines.Text += "Player HP is now: " + player.getHP();
player.itemList.RemoveAt(itemChoice);

}

enemyturn:
//Enemy turn
if (battleChoice != 0)
{
Lines.Text += enemy.getName() + " attacked!\n";

damage = enemy.getAtk() - player.getDef();
if (damage < 0)
damage = 0;
player.setHP(player.getHP() - damage);
if (player.getHP() < 0)
player.setHP(0);

Lines.Text += enemy.getName() + " dealt " + damage + " damage to " + player.getName();
Lines.Text += player.getName() + " HP is now " + player.getHP();
}

if (player.getHP() == 0)
return false;

turns++;
}
else
{
enemyturn:
//Enemy turn
if (battleChoice != 0)
{
Lines.Text += enemy.getName() + " attacked!\n";

damage = enemy.getAtk() - player.getDef();
if (damage < 0)
damage = 0;
player.setHP(player.getHP() - damage);
if (player.getHP() < 0)
player.setHP(0);

Lines.Text += enemy.getName() + " dealt " + damage + " damage to " + player.getName();
Lines.Text += player.getName() + " HP is now " + player.getHP();

if (player.getHP() == 0)
return false;
}
//Player turn
if (battleChoice == 1)
{
Lines.Text += player.getName() + " attacked!\n";

if (player.getAccuracy() < 100)
{
Random rnd = new Random();
if (rnd.Next(1, 100) > player.getAccuracy())
{
Lines.Text += "The attack missed!";
goto enemyturn;
}
}

damage = player.getAtk() - enemy.getDef();
if (damage < 0)
damage = 0;
enemy.setHP(enemy.getHP() - damage);
if (enemy.getHP() < 0)
enemy.setHP(0);

Lines.Text += "You dealt " + damage + " damage to " + enemy.getName();
Lines.Text += "Enemy HP is now " + enemy.getHP();

if (enemy.getHP() == 0)
return true;
}

else if (battleChoice == 2)
{
Lines.Text += "Your items: ";
for (int i = 0; i < player.itemList.Count; ++i)
{
Lines.Text += player.itemList[i].getName();
}
Lines.Text += "Choose a number based on the order the items appeared";

}
turns++;
}
return true;

}

基本上,当我按下按钮并调用战斗时,整个函数将被跳过,直到找到一些松散的“其他”,或者,如果我限制每个比较,程序就会卡住。我进行了一些搜索,看到有人建议使用 Delegate 或 BackgroundWorker,但我仍然对使用它们感到困惑。 This link是我发现的最接近我的问题,但它也不能帮助我(也许因为我是新手......)。

你们能帮帮我吗?提前谢谢你:)

最佳答案

您的第一个问题是您计算战斗力的方法是在 GUI 线程上运行的。由于它很忙,它实际上无法真正完成更新 GUI 的工作,因此 GUI 会卡住。永远不要在 GUI 线程上执行长时间运行的任务。

您可以使用 async 和 await 来更正此问题,方法是创建一个新的异步方法并在您的按钮点击中运行它:

private async Task RunCombat()
{
Enemy enemy = new Enemy("Hellhound", "Oblivion Cave", 1);
//this next line will run async now and will not block your gui thread.
bool combatResult = await Task.Run(() => combat(player, enemy));

if (combatResult)
{
Lines.Text += "You won!\n";
player.itemList.Add(new Item("Fruit", 22));
}
else
{
Lines.Text = "YOU DIED.";
Lines.Text += "GAME OVER.";
return;
}

然后只需在您的按钮点击中调用此方法,而不是您已经拥有的方法。一旦这样做,您将无法再在战斗方法中使用 Lines.Text +=,因为它将在不同的线程上运行。

我会在您的表单类声明上方创建一个名为 LineAppenderDelegate 的委托(delegate):

public delegate void LineAppenderDelegate(string lineToAdd);

然后创建一个AppendLine方法:

private void AppendLine(string lineToAdd)
{
if(InvokeRequired) //if we are not on the gui thread
{
//re-call the same method on the gui thread
LineAppenderDelegate d = new LineAppenderDelegate(AppendLine);
Invoke(d, new object[]{lineToAdd});
}
else //we are on the gui thread and can just do the work
{
Lines.Text += lineToAdd;
}
}

并使用它来添加行。此方法主要检查您是否在正确的线程上与 gui 交互。如果不是,它会调用 gui 线程上的方法。如果您是,它就会发挥作用。

关于C# Windows 窗体应用程序函数循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34256104/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com