views:

174

answers:

2

I am working on understanding collision detection and have decided to create a program that simulates Pacman. Simply put when a Pacman runs into a Ghost it dies.

I specify how many Pacmen I would like and in my MainForm_Paint (called when my control needs painting) I create an array of the specified amount of a class I created called Pacman. I then go on to construct each Pacman in the array with parameters specified.

When all is said and done I then go on to just try and draw all the Pacmen while inside a loop. Only one drawn inside the ClientRectangle regardless of how many I specify to draw. When I expand my ClientRectangle I see little lines or what appears to be a sliver of a Pacman. I have checked to make sure that the start positions are within the ClientRectangles x,y system and they are. I am just stumped as to why they aren't drawing inside the ClientRectangle though. :( Any help would be much appreciated.

Here is what I have coded for 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++;
            }
        }
    }

Here is what I have coded for my Pacman class:

    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();
    }

Thanks for you help and sorry if this is an inappropriate use of SOF.

A: 

You need to account for the fact that you're specifying the top left of the object; your xpos and ypos can only go to a maximum of width - object width in order to keep it fully visible.

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);
Adam Robinson
A: 

You're creating a new seed for your random number generator every time you call the Pacman constructor. As you are doing this in a tight loop all the Pacmen will end up in the same place. This is because Random uses the date/time as part of it's seed.

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. The following example illustrates that two Random objects that are instantiated in close succession generate an identical series of random numbers.

Create the random number generator outside the loop and pass it into the constructor.

ChrisF