我正在努力理解碰撞检测,并决定创建一个模拟Pacman的程序。简单地说,当Pacman遇到Ghost它就会死掉。
我指定了我想要的Pacmen数量以及我的MainForm_Paint(当我的控件需要绘画时调用)我创建了一个指定量的我创建的类Pacman的数组。然后我继续用指定的参数构造数组中的每个Pacman。
当说完所有的话后,我继续尝试在循环中尝试画出所有的Pacmen。无论我指定绘制多少个,都只在ClientRectangle内绘制一个。当我扩展我的ClientRectangle时,我看到小线条或看起来像是Pacman的一小部分。我已检查以确保起始位置在ClientRectangles x,y系统内,并且它们是。我只是难过为什么他们没有在ClientRectangle内部绘制。 :(非常感谢任何帮助。
以下是我为MainForm_Paint编码的内容
private void MainForm_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle rect = this.ClientRectangle;
Pacman[] pacmen = new Pacman[parameters[0]];
int whichPacman = 0;
for (int i = 0; i < parameters[0]; i++)
{
pacmen[i] = new Pacman(rect, parameters[1]);
}
while (play)
{
pacmen[whichPacman].PacmanDraw(g, rect);
// Must reset whichPac if whichPac + 1 == parameters[0]
// Break out while testing
if ((whichPacman + 1) == parameters[0])
{
break;
}
else
{
whichPacman++;
}
}
}
以下是我为Pacman课程编写的内容:
public Pacman(Rectangle rect, int radius)
{
Random rand = new Random();
this.xpos = rand.Next(rect.Left, rect.Left + rect.Width);
this.ypos = rand.Next(rect.Top, rect.Top + rect.Height);
this.radius = radius;
}
public void PacmanDraw(Graphics g, Rectangle rect)
{
GraphicsPath path = new GraphicsPath();
path.AddArc(this.xpos, this.ypos, (float) this.radius * 2, (float) this.radius * 2, 0, 360);
path.CloseFigure();
g.FillPath(new SolidBrush(Color.AliceBlue), path);
path.Dispose();
}
如果这是对SOF的不当使用,感谢您的帮助和抱歉。
答案 0 :(得分:0)
您需要考虑到您指定对象的左上角这一事实;您的xpos
和ypos
最多只能width - object width
,以使其完全可见。
this.xpos = rand.Next(rect.Left, rect.Left + rect.Width - radius * 2.0);
this.ypos = rand.Next(rect.Top, rect.Top + rect.Height - radius * 2.0);
答案 1 :(得分:0)
每次调用Pacman
构造函数时,都会为随机数生成器创建一个新种子。当你在一个紧凑的循环中这样做时,所有的Pacmen将最终在同一个地方。这是因为Random
使用日期/时间作为种子的一部分。
随机数生成从种子值开始。如果重复使用相同的种子,则生成相同的数字序列。产生不同序列的一种方法是使种子值与时间相关,从而与每个新的Random实例产生不同的序列。默认情况下,Random类的无参数构造函数使用系统时钟生成其种子值,而其参数化构造函数可以根据当前时间中的滴答数采用Int32值。但是,由于时钟具有有限的分辨率,因此使用无参数构造函数以紧密连续的方式创建不同的随机对象会创建随机数生成器,从而生成相同的随机数序列。以下示例说明了以紧密连续方式实例化的两个Random对象生成相同的随机数序列。
在循环外创建随机数生成器并将其传递给构造函数。