Click here to Skip to main content
15,608,936 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Trying to code Pacman in C# for programming class.

For the map(classic design) I used picture boxes but there's like 50 of them, so collison detection is a pain.

Is there an easier why to make the map and simplify the colision detection?

    public Form1()

    private void Form1_KeyDown(object sender, KeyEventArgs e)
        string a;
        a = e.KeyData.ToString();
        if (e.KeyData.ToString() == "Escape") Application.Exit();
        if (e.KeyData.ToString() == "Up") { Up.Enabled = true; Right.Enabled = false; Down.Enabled = false; Left.Enabled = false; }
        if (e.KeyData.ToString() == "Down") { Down.Enabled = true; Up.Enabled = false; Right.Enabled = false; Left.Enabled = false; }
        if (e.KeyData.ToString() == "Left") { Left.Enabled = true; Right.Enabled = false; Up.Enabled = false; Down.Enabled = false; }
        if (e.KeyData.ToString() == "Right") { Right.Enabled = true; Up.Enabled = false; Left.Enabled = false; Down.Enabled = false; }

    private void Up_Tick(object sender, EventArgs e)
        pacman.Top += -1;
        pacman.Image = Image.FromFile(@"y:\\Pacman Up.png");
        if (pacman.Top <= pictureBox1.Bottom+1 && pacman.Right >=       pictureBox1.Left && pacman.Left<= pictureBox1.Right||
            pacman.Top <= pictureBox2.Bottom+1 && pacman.Right >= pictureBox2.Left && pacman.Left<= pictureBox2.Right)
            Up.Enabled = false;
    private void Down_Tick(object sender, EventArgs e)
        pacman.Top += 1;
        pacman.Image = Image.FromFile(@"y:\\Pacman Down.png");
    private void Left_Tick(object sender, EventArgs e)
        pacman.Left += -1;
        pacman.Image = Image.FromFile(@"y:\\Pacman Left.png");
        if (pacman.Left <= 13) { pacman.Location = new Point(470, 242); }
        if (pacman.Left <=pictureBox1.Right && pacman.Right>=pictureBox1.Left && pacman.Top <= pictureBox1.Bottom && pacman.Bottom >= pictureBox1.Top ||
            pacman.Left <=pictureBox2.Right && pacman.Right>=pictureBox2.Left && pacman.Top <= pictureBox2.Bottom && pacman.Bottom >= pictureBox2.Top)
            { Left.Enabled = false; }
    private void Right_Tick(object sender, EventArgs e)
        pacman.Left += 1;
        pacman.Image = Image.FromFile(@"y:\\Pacman Right.png");
        if (pacman.Right >= 470) { pacman.Location = new Point(12, 242); }

I cut out a ton of code, but it was just the rest of the collision detection for the 30 other boxes.
Updated 20-Apr-11 21:57pm

Don't use picture boxes at all. Handle the Paint event for your form or panel, and paint on the appropriate bitmaps or blobs. Picture boxes may seem to make it easier, but that's a lot of controls to play with - and it will slow things down.

If you paint it yourself, collision detection becomes easier: The pac man is in square x, y where x and y are easy to calculate from the current location with just a division by the cell width/height: same for each ghost. Since the whole of a cell is either enterable or not enterable, you only need to work out if the pac man is being eaten.
Share this answer
Sergey Alexandrovich Kryukov 20-Apr-11 19:58pm    
You're absolutely right, my 5. I'm tired to explain why not picture boxes.
Sorry for shouting.
Don't use picture boxes!

Create a tile class and store a collection (Grid) of tile classes. Each one knows how to draw itself given a graphics object (which you will pass from the Paint event of your panel - the panel will be used to draw all graphics)

Collision detection should then be done by looping the map tiles (preferable only checking tiles near to the player) and other game objects (such as the ghosts, power-ups, dots, bonus items etc.)

Don't perform collision logic on Ticks like you have. You should aim to have a game loop similar to something like follows

Read Input (Get key presses)
Process Logic (detect collection, object movement etc.)
Update Animation (if any)
Render Graphics (Draw all objects on panel)
Play Sounds (if any)
Sync Frame Rate (delay loop if needed)

If you have to do winforms application then you can use a timer to simulate the game loop

So you would have a tile class and you can you a 2D array to store them in a grid

TileClass[,] tiles = new TileClass[15,15];

Then you can translate you pac man position to a tile and check the surrounding ones for collision

So say your tiles are 25px x 25px you can do something like

int x = (int)(pacMan.Position.X / 25);//Pacman position should be relative to grid point 0,0
int y = (int)(pacMan.Position.Y / 25);

//Then check collition with surrounding tiles
//tiles[x-1, y-1];
//tiles[x-1, y];
//tiles[x-1, y+1];
//tiles[x, y-1];
//tiles[x, y+1];
//tiles[x+1, y-1];
//tiles[x+1, y];
//tiles[x+1, y+1];

...anyway, something like that. I don't have the time at the minute to check for any flaws in that logic
//tiles[x, y];
Share this answer
Sergey Alexandrovich Kryukov 20-Apr-11 19:59pm    
You're absolutely right, my 5. I'm tired to explain why not picture boxes.
Sorry for shouting.
Bravo03 20-Apr-11 20:51pm    
Ok that sounds pretty good. Could you give me an example though on how to make the map out of grid since I'm not familiar with making grids at all in C#.
Dalek Dave 21-Apr-11 3:58am    
Great Answer.
BobJanova 21-Apr-11 9:23am    
Good answer.

One point that I would mention is that you can also use the 'Invalidate game loop' (call Invalidate in your paint handler) if you don't want a fixed frame rate.

Also, I don't think PacMan can collide diagonally.

Also also, if you are going to ask a lot of game related questions you might want to join (Am I allowed to say that here?)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900