c# - Unity/C# 中的三角形

标签 c# algorithm sorting unity-game-engine game-development

首先,这是我的第一个问题,这不是“编写我的代码”帖子。我需要更有经验的程序员或数学爱好者的提示。


我正在尝试在游戏中形成塔。我不知道这是否与我的数学有关,以及我在编程方面有多糟糕,或者只是我的大脑在试图弄清楚这一点时死了。我写了几种算法,但没有任何效果。当我收集元素时,我需要将它们放置在塔中。第二个紧挨着第一个,然后第三个在它们上面。第四个(图中的索引 3)需要再次下降等等。如果我收集了 4 个物体;它们的位置应类似于图片中的 0-1-2-3。


这是我正在尝试实现的:

enter image description here

我离这个还很远。我只是循环遍历我的列表,并尝试通过一些 x-y 偏移计算来找出答案。我不确定是否应该使用预先填充的 Vector3 列表手动执行此操作。

public void goPositions(int count)
{
    Vector3 pos = Vector3.zero;
    for (int i = count; i > 0; i--)
    {
        for (int j = 0; j < i; j++)
        {
            GameObject gM = Instantiate(prefab);
            gM.transform.SetParent(transform);
            gM.transform.position = new Vector3(pos.x, pos.y, 0);
            pos += new Vector3(xOffset, 0, 0);
        }
        pos += new Vector3(0, yOffset, 0);
    }
}

最佳答案

将拉拉队员换成杂技 Actor 。杂技 Actor 不是金字塔,而是直接堆叠成列,上下直立在彼此的肩膀上。列号从左侧开始,最左侧的列指定为 1,并随着向右移动而增加。

以下是放置杂技 Actor 的规则:

In column 1, you stack 1 acrobat.
In column 2, you stack 2 acrobats.
In column 3, you stack 3 acrobats.
Etc...

这就是 9 个杂技 Actor 的样子:

      9
    5 8
  2 4 7
0 1 3 6

现在想象一下杂技 Actor 非常强壮,可以偏离中心站立,这样只有一条腿压在下面的人身上,另一条腿放在另一边的肩膀上。它们都向同一方向偏移,使每根柱子都向一侧倾斜。

每个堆叠的杂技 Actor 的偏移量恰好是底行杂技 Actor 之间距离的一半,因此看起来他们直接站在下面两个杂技 Actor 的顶部:

   9
  5 8
 2 4 7
0 1 3 6

看起来很眼熟吗?金字塔并不是真正的金字塔,它是柱子的倾斜集合!

所以算法只是在每一列中不断放置正确数量的杂技 Actor ,当你向上时,将每个杂技 Actor 向左偏移半列。每当你到达一栏的顶部时,你就开始一个新的并重复,直到达到所需的杂技 Actor 数量。新列中每个底部 acrobat 的起始位置很容易计算,因为它只是列号减一,乘以金字塔“原点”(左下)右侧的水平偏移距离。

我不是 Unity 程序员,这是为 C# WinForms 编写的,但我很确定您能够理解算法和代码。

这是该程序的核心部分:

private int xOffset = 45;
private int yOffset = 45;
private int cheerleaderRadius = 15;

private int numCheerleaders = 1;

private void MainForm_Paint(object sender, PaintEventArgs e)
{
    // set origin at the bottom left of the form
    Point origin = new Point(cheerleaderRadius * 2, this.ClientRectangle.Height - (cheerleaderRadius*2));
           
    int currentCheerleader = 1;
    int currentColumnNumber = 1;
    int cheerleadersInCurrentColumn;
    while (currentCheerleader <= numCheerleaders)
    {
        cheerleadersInCurrentColumn = 1;
        Point position = new Point(origin.X + (currentColumnNumber - 1) * xOffset, origin.Y);
        while(cheerleadersInCurrentColumn<=currentColumnNumber && currentCheerleader<=numCheerleaders)
        {
            drawCheerleader(e.Graphics, position, (currentCheerleader - 1));
            position.Offset(-xOffset / 2, -yOffset);
            cheerleadersInCurrentColumn++;
            currentCheerleader++;
        }
        currentColumnNumber++;
    }     
}

这就是它实际的样子。每次啦啦队人数发生变化时,下面的金字塔就会重新绘制:

enter image description here

这是整个 C# WinForms 程序:

public partial class MainForm : Form
{
    
    private int xOffset = 45;
    private int yOffset = 45;
    private int cheerleaderRadius = 15;

    private int numCheerleaders = 1;
    
    private StringFormat sf = new StringFormat();

    public MainForm()
    {
        InitializeComponent();
        sf.Alignment = StringAlignment.Center;
        sf.LineAlignment = StringAlignment.Center;
        this.Paint += MainForm_Paint;
        this.SizeChanged += MainForm_SizeChanged;
    }

    private void MainForm_SizeChanged(object sender, EventArgs e)
    {
        this.Invalidate();
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        numCheerleaders = (int)numericUpDown1.Value;
        this.Invalidate();
    }

    private void MainForm_Paint(object sender, PaintEventArgs e)
    {
        // set origin at the bottom left of the form
        Point origin = new Point(cheerleaderRadius * 2, this.ClientRectangle.Height - (cheerleaderRadius*2));
               
        int currentCheerleader = 1;
        int currentColumnNumber = 1;
        int cheerleadersInCurrentColumn;
        while (currentCheerleader <= numCheerleaders)
        {
            cheerleadersInCurrentColumn = 1;
            Point position = new Point(origin.X + (currentColumnNumber - 1) * xOffset, origin.Y);
            while(cheerleadersInCurrentColumn<=currentColumnNumber && currentCheerleader<=numCheerleaders)
            {
                drawCheerleader(e.Graphics, position, (currentCheerleader - 1));
                position.Offset(-xOffset / 2, -yOffset);
                cheerleadersInCurrentColumn++;
                currentCheerleader++;
            }
            currentColumnNumber++;
        }     
    }

    private void drawCheerleader(Graphics g, Point pos, int number)
    {
        RectangleF rc = new RectangleF(pos, new Size(1, 1));
        rc.Inflate(cheerleaderRadius, cheerleaderRadius);
        g.DrawEllipse(Pens.Black, rc);
        g.DrawString(number.ToString(), this.Font, Brushes.Black, rc, sf);
    }

}

关于c# - Unity/C# 中的三角形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74668397/

相关文章:

Python - 选择总和为 2D 列表中累积总和的 68% 的元素

c# - 同步多个 View 、编辑器和提交/取消

c# - Asp.net 核心问题中的分页,只得到 10 个项目不能让它更快?

c# - ASP.NET 异步调用的问题,等待处理程序返回

algorithm - 遍历 FPGA 中的位

sorting - 重击 : sort text file by last field value

C#列表列表问题

python - 具有可变数量 worker 的任务的最佳调度

swift - 归并排序算法效率

sorting - 这些天你是否编写代码来对列表进行排序?