【问题标题】:creating a group of controls创建一组控件
【发布时间】:2016-03-31 14:39:23
【问题描述】:

我今天在开发游戏时遇到了小问题... 问题是我在 1 毫秒计时器上运行此条件:

if (jump == true && 
    jumped == 0 && 
   (Player.Location == new Point(Player.Location.X, Block1.Location.Y - Player.Height) || 
    Player.Top == this.Height - Player.Height))
{
   do something...
}

“Block1”是游戏中的一个对象(Picturebox),我需要 10 或 20 甚至 100 多个具有相同条件的这些块,那么我该如何简化它呢?这将是一个条件的 50 行甚至更多行。基本上我想知道是否有一种方法可以将所有 "Blocks"(图片框)混合到一个组中(命名为 Blocks)或者我仍然可以使用 Blocks.Location.Y 等访问的东西

【问题讨论】:

  • 为什么是 1ms 定时器?如果代码执行需要更长的时间,您也会遇到问题,然后您将在多核/CPU 机器上并行运行该函数。

标签: c# winforms conditional-statements


【解决方案1】:

IMO,这一次检查的条件太多了。我会将它们分解,然后以独立的方式处理每个条件,这将使事情更容易调试以及将来阅读/理解。

// Too much going on here; let's refactor.
if (jump == true 
    && jumped == 0 
    && (Player.Location == new Point(Player.Location.X, Block1.Location.Y - Player.Height) 
        || Player.Top == this.Height - Player.Height))
{
   //do something...
}

与其创建一个大的 if 语句,不如将条件合并到一个方法中:

// first refactor
private bool IsValidForSomeAction()
{
    if(!jump)
    {
        return false;
    }

    if(jumped != 0)
    {
        return false;
    }

    if(Player.Top == this.Height - Player.Height)
    {
        return true;
    }

    if (Player.Location == new Point(Player.Location.X, Block1.Location.Y - Player.Height))
    {
       return true;
    }

    return false;
}

在第一个 refator 之后,很明显不需要再为最终的比较创建一个新的 Point:

// second refactor
private bool IsValidForSomeAction()
{
    if(!jump)
    {
        return false;
    }

    if(jumped != 0)
    {
        return false;
    }

    if(Player.Top == this.Height - Player.Height)
    {
        return true;
    }

    // only the Y location matters, no need to create a new Point for the comparison.
    if (Player.Location.Y == Block1.Location.Y - Player.Height)
    {
       return true;
    }

    return false;
}

现在,让我们专注于真正重要的事情:if (Player.Location.Y == Block1.Location.Y - Player.Height)。条件归结为 Block 的 Y 位置和 Player 的高度之间的差异。

假设可能有 10、20、50 或 100 多个要比较的块,则创建一个包含所有块的集合的私有字段。

// override the onload event and find all the picture boxes:

private readonly List<PictureBox> _boxes = new List<PictureBox>();

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);    

    _boxes.AddRange(this.Controls.OfType<PictureBox>()
}

_boxes 字段随后可用于最终验证:

// third refactor
private bool IsValidForSomeAction()
{
    if(!jump)
    {
        return false;
    }

    if(jumped != 0)
    {
        return false;
    }

    if(Player.Top == this.Height - Player.Height)
    {
        return true;
    }

    // only the Y location matters, no need to create a new Point for the comparison.
    if(_boxes.Any(x => x.Location.Y - Player.Height == Player.Location.Y)
    {
        return true;
    }

    return false;
}

【讨论】:

  • 真的感谢那组盒子(做其他事情我必须重新做所有事情,但也谢谢你)我希望你过圣诞节:P
  • 欢迎来到 S.O.如果这个答案有帮助,那么请投票和/或接受答案并祝圣诞快乐:)
猜你喜欢
  • 2014-12-26
  • 1970-01-01
  • 2015-07-19
  • 2011-01-11
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 2016-12-09
相关资源
最近更新 更多