当玩家在基于网格的游戏中穿过道路时,如何防止道路消失? – C 编程


我目前正在用 C 语言开发一个基于网格的游戏,其中道路由点(“.”)表示,玩家由“P”表示。 玩家的目标是到达目的地(“G”)。 然而,当玩家穿过道路时,我面临着如何保持道路可见的挑战。

问题描述:

网格是用道路和边界初始化的,但当玩家在道路上移动时,道路就会消失。
尽管我尝试在 movePlayer 函数中的玩家移动期间保留道路单元,但道路仍然消失。

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
#include "traffic.h"

void initializeGame(char **grid, int rows, int cols) {
    int i, j;  /* Declare loop control variables */
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if (i == 0 || i == rows - 1 || j == 0 || j == cols - 1) {
                grid[i][j] = '*'; /* Set border cells to "*" */
            } else if ((i % 2 == 0) && (j > 0 && j < cols - 1)) {
                grid[i][j] = '.'; /* Set road cells to "." on even rows */
            } else {
                grid[i][j] = ' '; /* Set other cells inside borders to empty */
            }
        }
    }

    /* Place the player at the top-left corner and the goal at the bottom-right corner */
    grid[1][1] = 'P';
    grid[rows - 2][cols - 2] = 'G';
}


/* Function to display the game grid with borders */
void displayGame(char **grid, int rows, int cols, int prevPlayerRow, int prevPlayerCol) {
    int i, j;  /* Declare loop control variables */
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            /* Move the cursor to the current cell */
            move(i, j);

            /* Print the content of the grid */
            printw("%c", grid[i][j]);
        }
    }

    mvprintw(rows, 0, "Press 'w' to move up");
    mvprintw(rows + 1, 0, "Press 'a' to move left");
    mvprintw(rows + 2, 0, "Press 's' to move down");
    mvprintw(rows + 3, 0, "Press 'd' to move right");

    refresh(); /* Refresh the screen using ncurses */
}

void movePlayer(char **grid, int rows, int cols, int move, int *win, int *prevPlayerRow, int *prevPlayerCol) {
    int i, j, playerRow, playerCol;  /* Declare loop control variables */

    /* Find the current position of the player */
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if (grid[i][j] == 'P') {
                playerRow = i;
                playerCol = j;
            }
        }
    }

    /* Clear the player's previous position */
    grid[*prevPlayerRow][*prevPlayerCol] = ' ';

    /* Move the player based on the user's input */
    switch (move) {
        case 'w':
            if (playerRow > 1) {
                playerRow--;
            }
            break;
        case 'a':
            if (playerCol > 1) {
                playerCol--;
            }
            break;
        case 's':
            if (playerRow < rows - 2) {
                playerRow++;
            }
            break;
        case 'd':
            if (playerCol < cols - 2) {
                playerCol++;
            }
            break;
        default:
            /* Invalid move */
            break;
    }

    /* Set the player's new position */
    grid[playerRow][playerCol] = 'P';

    /* Update the previous player position */
    *prevPlayerRow = playerRow;
    *prevPlayerCol = playerCol;

    /* Check if the player reached the goal */
    if (playerRow == rows - 2 && playerCol == cols - 2) {
        *win = 1; /* Set win flag to 1 */
    }
}



/* Main function, entry point of the program */
int main(int argc, char *argv[]) {
    /* Check the number of command-line arguments */
    if (argc != 3) {
        printf("Usage: %s <map_row> <map_col>\n", argv[0]);
        return 1;
    }

    /* Parse command-line arguments */
    int mapRows = atoi(argv[1]);
    int mapCols = atoi(argv[2]);

    /* Check for valid map size */
    if (mapRows < 3 || mapRows % 2 == 0 || mapCols < 5) {
        printf("Invalid map size. Please ensure <map_row> is an odd number >= 3 and <map_col> is >= 5.\n");
        return 1;
    }

    /* Dynamically allocate memory for the 2D char array */
    char **gameGrid = (char **)malloc(mapRows * sizeof(char *));
    int i;  /* Declare loop control variable */
    for (i = 0; i < mapRows; i++) {
        gameGrid[i] = (char *)malloc(mapCols * sizeof(char));
    }

    /* Initialize the game grid with "*" and place the player and goal inside borders */
    initializeGame(gameGrid, mapRows, mapCols);

    initscr(); /* Initialize ncurses */

    timeout(0); /* Set non-blocking input */

    char move;
    int win = 0; /* Win flag */
    int prevPlayerRow = 1; /* Initialize with player's initial row */
    int prevPlayerCol = 1; /* Initialize with player's initial column */

    do {
        /* Display the updated game grid with borders */
        displayGame(gameGrid, mapRows, mapCols, prevPlayerRow, prevPlayerCol);

        /* Get user input for player movement */
        move = getch(); /* Get the key without waiting for 'Enter' */

        /* Move the player based on user input */
        movePlayer(gameGrid, mapRows, mapCols, move, &win, &prevPlayerRow, &prevPlayerCol);

        /* Check if the player has won */
        if (win) {
            clear(); /* Clear the screen */
            printw("Congratulations! You have cleared the level.\n");
            printw("Press any key to exit.\n");
            refresh(); /* Refresh the screen to display the message */
            getch(); /* Wait for a key press before ending the program */
        }

    } while (move != 'q' && !win); /* Loop until the user enters 'q' or wins */

    endwin(); /* End ncurses */

    /* Free the dynamically allocated memory */
    for (i = 0; i < mapRows; i++) {
        free(gameGrid[i]);
    }
    free(gameGrid);
    

    return 0; /* Properly reach the end of the main function */
}

我尝试过的:

我已经审查了 movePlayer 函数,以确保道路单元在播放期间不会被修改
我尝试将道路单元和玩家移动的逻辑分开,但仍然面临道路消失的问题。

解决方案1

创建一个名为的全局变量 lastSurfaceType 并将其初始化为“路”。
当您移动玩家时,将其所在的方块设置为 lastSurfaceType 在进行移动之前,将变量设置为玩家将要移动到的类型。

这样,下次您移动玩家时,您就可以准备好正确的表面类型来替换您要移动的“P”。

解决方案2

引用:

当玩家在基于网格的游戏中穿过道路时,如何防止道路消失? – C 编程

代替

C++
/* Clear the player's previous position */
grid[*prevPlayerRow][*prevPlayerCol] = ' ';

C++
/* Clear the player's previous position */
grid[*prevPlayerRow][*prevPlayerCol] = '.';

当您将玩家从单元格中移出时,请将其设为一条道路而不是清空它。

コメント

タイトルとURLをコピーしました