1

RED SQUARE : PlayerPictureBox;

BLUE SQUARE : End Point;

BLACK SQUARE : WALL;

I have a maze organized in a PictureBox.

If the player arrives at the arrival point,

I want to implement a replay function that shows the path they found again, what should I do?

enter image description here

  public void CreateNewMaze()
    {
        mazeTiles = new PictureBox[XTILES, YTILES];
        for (int i = 0; i < XTILES; i++)
        {
            for (int j = 0; j < YTILES; j++)
            {
                mazeTiles[i, j] = new PictureBox();
                int xPosition = (i * TILESIZE) + 25;
                int yPosition = (j * TILESIZE) + 10;
                mazeTiles[i, j].SetBounds(xPosition, yPosition, TILESIZE, TILESIZE);

                this.Controls.Add(mazeTiles[i, j]);
            }
        }
    }


 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        int directionX = 0;
        int directionY = 0;
        switch (keyData)
        {
            case Keys.Left: directionX = -1;
                EndGame();
                break;

            case Keys.Right: directionX = 1;
                EndGame();
                break;

            case Keys.Up: directionY = -1;
                EndGame();
                break;

            case Keys.Down: directionY = 1;
                EndGame();
                break;

            default: return base.ProcessCmdKey(ref msg, keyData);
        }

        int x = directionX + (PlayerPictureBox.Left - 25) / TILESIZE;
        int y = directionY + (PlayerPictureBox.Top - 10) / TILESIZE;

        bool isRoad = mazeTiles[x, y].BackColor != Color.Black;
        if (isRoad)
        {
            PlayerPictureBox.Left += directionX * TILESIZE;
            PlayerPictureBox.Top += directionY * TILESIZE;
        }
        return true;
  
    }
FUZIION
  • 1,606
  • 1
  • 6
  • 19
toe ko
  • 88
  • 7
  • The easiest way is to do it like Doom did, save every key input in a long queue, and then if you want to see a replay of the game, instead of taking player input, just dequeue the inputs one after another and apply them instead – MindSwipe Oct 18 '22 at 06:36
  • I don't understand you telling me "save every key input in a long queue" If you don't mind, could you give me an example? – toe ko Oct 18 '22 at 06:44
  • Basically, in your `ProcessCmdKey` method, before doing anything, push the `keyData` to a [queue](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.queue-1?view=net-6.0) like `_previouslyInputKeys.Push(keyData)` – MindSwipe Oct 18 '22 at 07:29
  • Difficult to implement previouslyInputKeys.Push method Can you give me an example? – toe ko Oct 18 '22 at 08:18

1 Answers1

1
  • Add each step (or move) to a list of steps.
  • Add Replay method that takes each step from this list, performs it and then waits for a while.
  • Clear the 'steps' list before each game (in CreateNewMaze for example).
  • Start playback when pressing Space, for example.

So, add this code to you Form:

    class Step
    {
        public int dx;
        public int dy;
    }

    List<Step> steps = new List<Step>();

    async void Replay(int delay = 50)
    {
        int firstX = 1; // Initial player position, maybe you'll have to change it
        int firstY = 1; 

        PlayerPictureBox.Left = 25 + firstX * TILESIZE;
        PlayerPictureBox.Top = 10 + firstY * TILESIZE;

        var copy = steps.ToArray(); // Let's make a copy of steps array, to avoid possible conflicts with working array.
        foreach (var step in copy)
        {
            PlayerPictureBox.Left += step.dx * TILESIZE;
            PlayerPictureBox.Top += step.dy * TILESIZE;

            await Task.Delay(delay);
        }
    }

Modify CreateNewMaze like this:

    public void CreateNewMaze()
    {
        // Add the following line
        steps.Clear();

        maze = new bool[XTILES, YTILES];
        //...

Modify ProcessCmdKey like this:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        int directionX = 0;
        int directionY = 0;
        switch (keyData)
        {
            // Add the following:
            case Keys.Space:
                Replay();
                return true;
            // ...

and below like this:

        // ...
        if (isRoad)
        {
            // Add the following line
            steps.Add(new Step { dx = directionX, dy = directionY });

            PlayerPictureBox.Left += directionX * TILESIZE;
            PlayerPictureBox.Top += directionY * TILESIZE;
        }

I would recommend using a different PictureBox instance for playing back the steps, so that the user can continue playing while playback is running. But I'll leave it for you.

Jiri Volejnik
  • 1,034
  • 6
  • 9