【问题标题】:C# using a timer within another timer?C# 在另一个计时器中使用计时器?
【发布时间】:2016-08-17 16:15:35
【问题描述】:

我正在编写俄罗斯方块游戏。到目前为止,我已经实现了一个间隔很短的定时器,大约 50 毫秒。当前下降的 tetromino 每滴答声就会在游戏矩阵中向下移动一个位置。然后游戏会检查是否存在碰撞,如果是,则四联体被标记为“着陆”并生成新的四联体。

不,我有一个问题,我想让玩家有机会在 tetromino 着陆后向左或向右移动 0.5 秒,以便有可能将 tetromino 移动到悬垂的已经着陆的 tetromino 下方。

但是使用我当前的代码,我遇到的问题是,一旦检测到碰撞,计时器就会继续并产生下一个 tetromino。我现在的想法是尝试实现第二个计时器,每次检测到碰撞时激活 0.5 秒,以便在主计时器继续之前允许额外的键盘输入。所以基本上暂停主定时器0.5秒,让程序在这段时间内检测键盘输入,然后继续主定时器。

到目前为止,我尝试的一切都没有真正奏效。似乎第一个计时器总是继续运行,而我有第二个计时器处于活动状态。

这是我的第一个计时器的样子:

private void TimerBrick_Tick(object sender, EventArgs e)
        {
            ResetGameBoard(jaggedTetrisBricks[rnd-1][rotation], _brickX, _brickY, xLengthBrick, yLengthBrick);
            _brickX++;
            CollisionCheck(jaggedTetrisBricks[rnd - 1][rotation], _brickX, _brickY, xLengthBrick, yLengthBrick);
            LineCheck();

            Invalidate();
        }

现在我需要在我的 CollisionCheck() 方法中实现一种等待 0.5 秒的方法,然后代码继续使用 LineCheck()

或者还有其他我现在看不到的方法吗?

【问题讨论】:

  • 您可以使用Thread.Sleep(time),但这可能会暂停整个程序,如果是这种情况,您可以为teromino 使用Task,但这会导致您必须解决的其他问题。
  • 如何在您的主计时器滴答声中实现一个状态驱动系统 - 正常状态是“BrickFalling”,一旦您检测到碰撞,您将状态更改为持续 10 个滴答声的“MoveSideways”,然后您创建一个新砖并返回“BrickFalling”。在计时器滴答事件中,只需使用 if 或 switch。如果您愿意,可以轻松添加更多状态。
  • @PaulF 建议的是usual approach in games。您还可以将 0.5 秒作为游戏循环的默认间隔,以便在“Falling”状态期间可以进行其他类型的处理。
  • @PaulIF 我喜欢这个主意。但是我怎么能在我的 'TimerBrick_Tick' 事件中说我只想做 10 个滴答声然后切换回其他东西呢?
  • 我成功了,谢谢!

标签: c# timer


【解决方案1】:

除了我之前的评论——这里有一点伪代码:

enum GameState
{
    Starting,
    CreateBrick,
    BrickFalling,
    MoveSideways
}

private GameState curState = Starting;
private ushort ctSideways;

private void TimerBrick_Tick(object sender, EventArgs e)
{
    switch (curState)
    {
        case Starting:
            InitialiseGame();
            curState = CreateBrick;
            break;

        case CreateBrick:
            CreateNewBrick();
            curState = BrickFalling;
            break;

        case BrickFalling:
            .....
            .....
            if (CollisionCheck())
            {
                ctSideways = 0;
                curState = MoveSideways;
            }
            break;

        case MoveSideways:
            .....
            .....
            ctSidways++;
            if (ctSideways == 10)
                curState = CreateBrick;
            break;
    }

}

【讨论】:

  • 谢谢我有一个类似的方法,当变量达到某个值时,变量计数来改变状态;)
猜你喜欢
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多