1

我正试图让我的 winForms 像Manhole那样相互溶解。所有表格都在屏幕中央打开。任何帮助将不胜感激。

这就是我目前打开和关闭表单的方式:

private void storyChooser_Click(object sender, EventArgs e)
{
    switch (userChoice)
    {
        case Choice.Son:
            this.Close();
            form2.Show();
            form2.label1.Text = "Son has been choosen.";
            break;
        case Choice.Dad:
            this.Close();
            form2.Show();
            form2.label1.Text = "Dad has been choosen.";
            break;
        case Choice.Mom:
            this.Close();
            form2.Show();
            form2.label1.Text = "Mom has been Choosen.";
            break;
        default:
            break;
    }
}

为了阻止应用程序关闭,我从一开始就运行了所有表单,但未显示。我无法获得内存效率更高的工作方式,所以我现在将其用作解决方法。

4

2 回答 2

1

您想要的称为交叉淡入淡出。您拍摄一张图像并将每个像素从一张图像插入到另一张图像。

这是直截了当的。假设时间从 0(所有第一张图像)到 1.0(所有最后一张图像),那么您将执行以下操作:

public Color Lerp(Color c1, Color c2, float t)
{
    return Color.FromArgb(Lerp(c1.R, c2.R, t), Lerp(c1.G, c2.G, t), Lerp(c1.B, c2.B, t));
}

public int Lerp(int a, int b, float t)
{
    float tp = 1.0f - t;
    return (int)(tp * a + t * b);
}

您的流程将是:

  1. 将 form1 渲染为位图
  2. 将 form2 渲染为位图
  3. 分配临时位图
  4. 对于从 0 到 1 的 t,例如 0.1,在 form1 位图和 form2 位图之间的每一个 (x, y) 处进行 Lerp,并将该像素设置在暂存区
  5. 显示划痕

现在,您可以编写此代码,并且您应该确保它有效。如果性能足够好,那就顺其自然吧。

我认为您实际上并不想使用此代码(我以编写图像处理代码为生)。在 .NET 中进行所有像素修改的开销可能会让您陷入困境。您最好从位图中获取原始字节字节并对它们进行 lerp,而不是执行 get/get/set 像素。此外,每个颜色分量的这三个浮点运算也会拖累你,所以如果是我,如果我对字节进行运算,我会在定点上完成工作。

于 2013-02-04T16:33:37.567 回答
0

第一:WinForms 不是创建游戏的最佳选择。

但是,如果您想或必须这样做,您可能不应该为此任务使用多种形式。

您可以以一种形式创建多个面板,然后使用计时器操作它们的不透明度。

如果您创建大型游戏,则必须动态创建屏幕。

样本

这是一个如何动态创建控件的示例。您可以开始为不同的场景创建自己的控件(例如为问题的不同答案提供 n 个组合框的控件)。然后你可以开始用步骤来定义你的故事,然后每个步骤都会创建正确的控件,比如一个“决策步骤”,它提出一个问题并根据答案选择下一步。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var newButton = new Button { Text = "Click me", Dock = DockStyle.Top };
        newButton.Click += new EventHandler(newButton_Click);
        this.panel1.Controls.Add(newButton);
    }

    void newButton_Click(object sender, EventArgs e)
    {
        MessageBox.Show("I was clicked");
        var button = sender as Button;
        button.Click -= new EventHandler(newButton_Click);
        this.panel1.Controls.Remove(button);
    }
}
于 2013-02-04T16:27:33.230 回答