等待,直到触发了点击事件C# [英] Wait until a click event has been fired C#
问题描述
我正在开发纸牌游戏,但我需要具有一个停止程序的功能,直到玩家没有单击卡的图片框以丢弃它.我的游戏算法是这样的:
int nextDrawer = 0;//将要弃牌的玩家从人类玩家开始逆时针确定for(int i = 0; i< players; i ++)//直到所有玩家都未抓牌{if(i == 0)....//人类玩家必须单击图片框来丢弃纸牌else ....//AI玩家将丢弃AI从其手中的3张牌中随机选择的一张牌}
问题在于,当手法结束时,第一个丢弃卡的人可能会改变.如果玩家被编号为0(人类玩家),1(第一位AI玩家),2(第二位AI玩家)和3(第三位AI玩家),则在第一手牌中首先弃牌的是人类玩家,但在第二个先弃牌的人可能是2名AI玩家,人类玩家必须等到所有AI玩家弃掉一张牌(在这种情况下,回合为2-3-0-1).>
如果AI玩家还没有丢弃卡,如何取消点击事件?
更新
我并不需要总是等所有所有 AI玩家都抓到一张牌:如果筹码的赢家是2号,则回合将为2-3-0-1:这意味着玩家必须等待AI玩家2和3抽奖,然后玩家必须单击一个PictureBox,然后循环将返回到AI玩家,然后允许AI玩家1丢弃其卡牌.
更新2
我曾经想过这样的事情:
int领导者= 0;//谁先丢弃int nextDiscarder =领导者;//下一个要舍弃的玩家for(int i = 0; i< nPlayers; i ++)//直到所有玩家都没有被丢弃{if(nextDiscarder == 0)//人类必须丢弃{enablePictureBoxClickEvent;//现在,在循环继续之前,程序必须等待事件单击图片框}别的{AI [nextDiscarder] .discard();//AI播放器将舍弃}if(nextDiscarder == players-1)//如果nextDiscarder已到达表的末尾nextDiscarder = 0;//返回开始,直到所有玩家都弃了纸牌别的++ nextDiscarder;//继续与下一位玩家一起放弃}
在事件中单击,我会做这样的事情:
private myEventClick(对象发送者,EventArgs e){....//按照丢弃卡片的指示进行操作disableMyEventClick;returnToLoop;}
但是主要的问题是我不知道如何在指令 returnToLoop
中编写代码.
我知道大多数人会认为您应该使用事件驱动的方法,但是 async/await
功能可以用于轻松实现这样的事情,而无需实现手动状态机.
我已经在强制循环等待中发布了类似的方法事件和一种更好的实施方式是一个WaitForMouseUp()函数吗?,所以基本上,这是与前者相同的助手,只是用 Button
替换为 Control
:
公共静态类实用程序{公共静态任务WhenClicked(此控件目标){var tcs = new TaskCompletionSource< object>();EventHandler onClick = null;onClick =(发送方,e)=>{target.Click-= onClick;tcs.TrySetResult(null);};target.Click + = onClick;返回tcs.Task;}}
现在,您所需要做的就是将您的方法标记为 async
并使用 await
:
//...if(nextDiscarder == 0)//人类必须丢弃{//现在,在循环继续之前,程序必须等待事件单击图片框等待pictureBox.WhenClicked();//单击图片框后,您会到达此处}//...
I'm developing a card game but I need to have a function that stops the program until the player hasn't clicked in the PictureBox of his card to discard it. The algorithm of my game is this:
int nextDrawer = 0; // the players which will discard a card are determinated in counterclockwise starting from the human player
for (int i = 0; i < players; i++) // untill all the players hasn't drawed a card
{
if (i == 0) .... // the human player has to click on a picture box to discard a card
else .... // an AI player will discard a card which is selected randomly from the 3 cards which AI has got in its hand
}
The problem is that when a mance ends, the first who will discard a card could change. If the players are numerated with 0 (human player), 1 (first AI player), 2 (second AI player) and 3 (third AI player), at the first mance the first to discard a card is the human player, but at the second mance the first to discard could be the 2 AI player and the human player has to wait until all the AI players before him discard a card (in this case, the round would be 2-3-0-1).
How can I cancel the click event if the AI players hasn't discarded a card yet?
UPDATE
I don't always need to wait that all AI players had drawed a card: if the winner of the mance is the number 2, the round would be 2-3-0-1: that means the player has to wait the AI players 2 and 3 drawed, then the player has to click one PictureBox, and the loop will return back to the AI players and then the AI player 1 is allowed to discard its card.
UPDATE 2
I've thought something like that:
int leader = 0; // who is going to discard first
int nextDiscarder = leader; // next player who's going to discard
for (int i = 0; i < nPlayers; i++) // until all the players hasn't discarded
{
if (nextDiscarder == 0) // the human has to discard
{
enablePictureBoxClickEvent;
// now before the loop continue the program has to wait the event click on a picture box
}
else
{
AI[nextDiscarder].discard(); // the ai player will discard
}
if (nextDiscarder == players - 1) // if nextDiscarder has reached the end of the table
nextDiscarder = 0; // return to the begin until all player has discarded a card
else
++nextDiscarder; // continue to discard with the next player
}
and in my event click I'd do something like this:
private myEventClick(object sender, EventArgs e)
{
.... // do the instructions needed to discard a card
disableMyEventClick;
returnToLoop;
}
but the main problem is that I don't know how to write in code my instruction returnToLoop
.
I know most of the people will argue that you should use event-driven approach, but async/await
feature can be used for easily implementing things like this w/o the need of implementing manually state machines.
I already posted similar approach in Force loop to wait for an event and A Better Way to Implement a WaitForMouseUp() Function?, so basically this is the same helper as in the former with Button
replaced with Control
:
public static class Utils
{
public static Task WhenClicked(this Control target)
{
var tcs = new TaskCompletionSource<object>();
EventHandler onClick = null;
onClick = (sender, e) =>
{
target.Click -= onClick;
tcs.TrySetResult(null);
};
target.Click += onClick;
return tcs.Task;
}
}
Now all you need is to mark your method as async
and use await
:
// ...
if (nextDiscarder == 0) // the human has to discard
{
// now before the loop continue the program has to wait the event click on a picture box
await pictureBox.WhenClicked();
// you get here after the picture box has been clicked
}
// ...
这篇关于等待,直到触发了点击事件C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!