@linawhite

Как можно сделать массив символов двигающимся в ncurses?

Мне нужно сделать игру (гонку) с помощью ncurses. Я уже сделала окно для выбора пользователем уровня (к-ство дорог) и сделала возможность перемещать машинку с помощью клавиш вперед-назад. Теперь загвоздка, не знаю как сделать чтобы появлялись преграды на протяжении всей игры. Ибо перемещение машинки основано на move() и текущей позиции курсора. То есть если я буду делать преграды этим же способом, все сломается. Может есть идеи как это реализовать?

#define _POSIX_C_SOURCE 200201L
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <time.h>
#include <math.h>

char my_car[8][12] =
{
    {' ', ' ', ' ', '_', '_', '_', '_', '_', ' ', ' ', ' ', '\0'},
    {' ', '(', ')', ' ', '|', '|', '|', ' ', '(', ')', ' ', '\0'},
    {'/', ' ', '_', '_', '_', '_', '_', '_', '_', ' ', '\\', '\0'},
    {'|', '/', '_', '_', '_', '_', '_', '_', '_', '\\', '|', '\0'},
    {'|', ' ', ' ', '_', '_', '_', '_', '_', ' ', ' ', '|', '\0'},
    {'|', ' ', ' ', '\\', '_', '_','_', '/', ' ', ' ', '|', '\0'},
    {'\\', '@', '@', ' ', '|', ' ', '|', ' ', '@', '@', '/', '\0'},
    {' ', ' ', '@', '_', '|', '_', '|', '_', '@', ' ', ' ', '\0'}
};

char barrier_car[4][15] =
{
    {' ', ' ', ' ', ' ', '_', '_', '_', '_', ' ', ' ', ' ', ' ', ' ', '\0'},
    {' ', ' ', ' ', '/', '|', '_', '\\', '_', ' ', ' ', ' ', ' ', '\0'},
    {'|', ' ', ' ', '_',' ', ' ', ' ', ' ', ' ', '_', '`', '`', '-', '.', '\0'},
    {'\'', '-', '(', '_', ')', '-', '-', '-', '(', '_', ')', '-', '-', '\'', '\0'},
};

char barrier_rock[3][6] =
{
    {' ', '@', '@', '@', ' ', '\0'},
    {'@', '@', '@', '@', ' ', '\0'},
    {' ', '@', '@', '@', ' ', '\0'},
};

int main () {
    srand(time(NULL));
    initscr();
    cbreak();
    noecho();

    // get screen sizes
    int yMax, xMax;
    getmaxyx(stdscr, yMax, xMax);

    //create a new window for input
    int height = 10;
    int width = 120;
    WINDOW * inputwin = newwin(height, width, yMax/2 - 5, (xMax/2 - width/2));
    box(inputwin, 0, 0);

    refresh();

    wrefresh(inputwin);

    // get amount roads
    echo();
    mvwprintw(inputwin, 4, width/2 - 38, "Press key left to choose beginner level, key right - intermediate, key up - advanced.");
    int amount_roads = 0;
    keypad(inputwin, TRUE);

    int a;

    while (a != KEY_DOWN) {
        int c = mvwgetch(inputwin, 5, 50);

        if (c == KEY_LEFT) {
            mvwprintw(inputwin, 5, 50, "You chose beginner                ");
            amount_roads = 2;
        } else if (c == KEY_RIGHT) {
            mvwprintw(inputwin, 5, 50, "You chose intermediate            ");
            amount_roads = 3;
        } else if (c == KEY_UP) {
            mvwprintw(inputwin, 5, 50, "You chose advanced                ");
            amount_roads = 4;
        } else mvwprintw(inputwin, 5, 50, "INCORRECT INPUT. TRY AGAIN");
        wrefresh(inputwin);

        mvwprintw(inputwin, 6, 47, "Press key down to continue");
        a =  mvwgetch(inputwin, 7, 60);
    }
    delwin(inputwin);
    wrefresh(stdscr);

    //create win for game
    height = yMax - 4;
    width = xMax - 10;
    WINDOW * gamewin = newwin(height, width, 2, 5);
    box(gamewin, 0, 0);
    refresh();
    wrefresh(gamewin);

    // draw roads
    int road_width = (width - 2) / amount_roads;
    for (int i = road_width; i < width - 2; i += road_width + 1) {
        for (int j = 1; j < height - 1; j ++) {
            mvwprintw(gamewin, j, i, "|");
        }
    }

    //draw car

    int y = height - 9;   //y position

    for (int i = 0; i < 8; i ++) {
        int x = (road_width/2) - (11/2);  // x position
        for (int j = 0; j < 12; j ++) {
            mvwprintw(gamewin, y, x, "%c", my_car[i][j]);
            x ++;
        }
        y ++;
    }
    wrefresh(gamewin);

    // clear current road to let car move at the next road
    void delete_car() {
        int yCurr, xCurr;
        getyx(gamewin, yCurr, xCurr);
        int yPos = height - 9;   //y position

        for (int i = 0; i < 8; i ++) {
            int xPos = xCurr - 11;  // x position
            for (int j = 0; j < 12; j ++) {
                mvwprintw(gamewin, yPos, xPos, "%c", ' ');
                xPos ++;
            }
            yPos ++;
        }
        wrefresh(gamewin);
    }

    void move_car(const char direction) {
        // let to move at given side
        int add;
        if (direction == 'l') add = -road_width;
        else if (direction == 'r') add = road_width;
        else return;
        //defines a start position for car from left side
        int yCurr;
        int xCurr;
        getyx(gamewin, yCurr, xCurr);
        int yPos = height - 9;
        for (int i = 0; i < 8; i ++) {
            int xPos = xCurr - 11 + add;  // x position
            for (int j = 0; j < 12; j ++) {
                mvwprintw(gamewin, yPos, xPos, "%c", my_car[i][j]);
                xPos ++;
            }
            yPos ++;
        }
        wmove(gamewin, yCurr, xCurr + add - 1);
        wrefresh(gamewin);
    }


    unsigned start_time = (unsigned)time(NULL);
    unsigned finish_time;
    while (true) {
        keypad(gamewin, TRUE);
        int move = wgetch(gamewin);

        if (move == KEY_RIGHT) {
            int yCurr, xCurr;
            getyx(gamewin, yCurr, xCurr);
            if (xCurr + road_width < width) {   // check is the road on the right
                delete_car();                                                        // clear current road
                move_car('r');                                                       // add car to next road
            } else {
                finish_time = (unsigned)time(NULL);
                break;
            }
        } else if (move == KEY_LEFT) {
            int yCurr, xCurr;
            getyx(gamewin, yCurr, xCurr);

            if ((xCurr - 12) >= road_width) {      // check is the road on the left
                delete_car();                      // clear current road
                move_car('l');                     // add car to next road
            } else {
                finish_time = (unsigned)time(NULL);
                break;
            }
        }
    }
    unsigned int playtime = finish_time - start_time;
    int score = playtime * 5;

    // creates file with scores and writes 0 score
    FILE * datagame;
    datagame = fopen("C:\\datagame.txt","w");

    if(datagame == NULL)
    {
        printf("Error!");
        exit(1);
    }
    fprintf(datagame,"New score: %d;\n", score);
    fclose(datagame);

    wrefresh(gamewin);

    getchar();
    endwin();

    return EXIT_SUCCESS;
}


Преграды должны появляться сверху
63923e68cdf2e338514161.png
  • Вопрос задан
  • 50 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы