كيف أمنع الطرق من الاختفاء عندما يتحرك اللاعب عبرها في لعبة تعتمد على الشبكة؟ – برمجة سي


أنا أعمل حاليًا على لعبة قائمة على الشبكة في لغة 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

يقتبس:

كيف أمنع الطرق من الاختفاء عندما يتحرك اللاعب عبرها في لعبة تعتمد على الشبكة؟ – برمجة سي

يستبدل

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

مع

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

عندما تقوم بإزالة اللاعب من الخلية، اجعلها طريقًا بدلاً من إفراغها.

コメント

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