首先,这是我的第一个问题,这不是“编写我的代码”帖子。我需要更有经验的程序员或数学爱好者的提示。
我正在尝试在游戏中形成塔。我不知道这是否与我的数学有关,以及我在编程方面有多糟糕,或者只是我的大脑在试图弄清楚这一点时死了。我写了几种算法,但没有任何效果。当我收集元素时,我需要将它们放置在塔中。第二个紧挨着第一个,然后第三个在它们上面。第四个(图中的索引 3)需要再次下降等等。如果我收集了 4 个物体;它们的位置应类似于图片中的 0-1-2-3。
这是我正在尝试实现的:
我离这个还很远。我只是循环遍历我的列表,并尝试通过一些 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++;
}
}
这就是它实际的样子。每次啦啦队人数发生变化时,下面的金字塔就会重新绘制:
这是整个 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/