c# - 等待用户点击多个控件中的一个控件
问题描述
这个问题以一堆其他人的话开头......“我正在尝试用c#做一个纸牌游戏”,我已经看到了很多类似的问题,但没有人真正解决我的问题。
我将用一个小场景介绍我的问题:
玩家 A 与目标 B 打牌 X
玩家 B 需要选择一张反牌 Y 或通过
玩家 B 视图包含他的牌,每张牌都由一个图片框表示。
要继续游戏,我需要玩家 B 的控制器等待,直到他点击类型 Y 的卡,或通过回合。
对我来说,做这样的事情最简单的方法是使用布尔值来伪装等待。很容易记录哪张牌是最后一张牌(例如 X),然后等到 card.Click 事件在 Y 类型的牌上触发或按下通过按钮。
问题在于它需要使用大量布尔变量和 if/else 来处理这些“事件”。
什么是这样的更好的实现?
编辑。
GameController.cs
public void XCardPlayed(string target)
{
if (this.players[0].Username.Equals(target))
{
// I'm the target
lastCardPlayed = "X";
PlayYCard();
}
else
{
// display the card on the table
}
}
public void PlayYCard()
{
gameView.NotifyPlayYCard();
}
GameForm.cs
public void PlayCardFromHand(int index)
{
if (playY)
{
// Check if card at index is instance of Y
}
}
public void NotifyPlayYCard()
{
playY = true;
}
public void CardClick(object sender, EventArgs e)
{
PictureBox current = (PictureBox)sender;
PlayCardFromHand(pnl_cards.Controls.IndexOf(current));
}
解决方案
一般来说,这类问题是通过创建一个状态机来解决的,即知道游戏处于什么状态的东西,并且根据这个状态,如何处理下一个输入。有几种方法可以对状态机进行编程,但一种方法是使用 async/await 让编译器来完成。
您可以将按钮包装在每次按下按钮时完成任务的类中:
public class ButtonAwaiter
{
private readonly Button button;
private TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
public ButtonAwaiter(Button button)
{
this.button = button;
this.button.Click += OnClick;
}
private void OnClick(object sender, EventArgs e)
{
tcs.SetResult(true);
tcs = new TaskCompletionSource<bool>();
}
public Task GetTask() => tcs.Task;
}
用“bool”代替按钮代表的任何东西。
并等待第一个按钮被按下,例如:
public async Task DoGameLoop()
{
var b1 = new ButtonAwaiter(button1);
var b2 = new ButtonAwaiter(button2);
while (GameIsInProgress)
{
var pressed = await Task.WhenAny(new[] {b1.GetTask(), b2.GetTask()});
}
}
当用户需要遵循某些操作序列时,此方法特别好,因为它可以让您以相当简单的方式编写代码。
推荐阅读
- ios - 无法增加 UIView 相对于 TextView 的高度
- docker - 由于卷名短,无法从 docker-compose 创建容器
- python - 我将如何修复 pygame 的按键事件不做任何事情?
- python-3.x - 如何创建相当于 1x2 linspace 数组的 numpy
- r - How can I train the word2vec model on my own corpus in R?
- python-3.x - 根据 Python Dataframe 中具有特定要求的其他列的值创建新列
- vba - 为 Word VBA 使用自定义字体(非 MS Office)
- javascript - 打字稿:未定义的静态变量问题
- anaconda - 如何在最新 Anancoda 2019.03 中安装/更新到 sympy 1.4?
- express - 如何使用 socket.io 通过套接字登录/注销?