@Whnoy

Почему перемещение в игре в терминале ведет себя странно?

Я захотел сделать игру в терминале, но когда я сделал перемещение, все пошло не по плану.
Когда ты нажимаешь на "W", то объект двигается вверх 2 раза:
1) После первого нажатия
2) После второго нажатия (причем любой кнопки, не только "W")
У меня не получается разобраться почему.

Вот все, что с этим связанно:

Класс экрана
Класс экрана
class Display
{
    private:
    short length, height = 0;
    unsigned long start_t = 0;
    bool border = false;
    vector<Pixel> pool; //Символы, которые необходимо поставить

public:

    map<string, void *> Obj_map; //Все обьекты на экране

//... я пропустил конструкторы (если что, они есть)
    void add_Objects() { // Добавление обьектов на экран
        for (auto i : Obj_map) {
            if (i.first == "Rectangle")
            add_to_pool((*(Rectangle *) i.second).draw());
        }
    }

    void draw() {
        clear();
        for (auto ch : pool) {
            if (border && ch.x < length && ch.y > height) {}
            else {
                move(ch.y, ch.x);
                printw(ch.ch);
            }
        }
        pool.clear();
    }

    int read() {
        return getch();
    }
}


//Обьекты
class Object{
    private:
    pair<short, short> cord;

    public:
    Object(pair<short, short> center_cord) {
        cord = center_cord;
    }

    Object(pair<short, short> center_cord, vector<Object>& Object_list) {
        cord = center_cord;
        //Object_list.push_back(this);
    }

    Object(vector<pair<short, short>>& Points) {
        short X = 0;
        short Y = 0;
        for (pair<short, short> p : Points) {
            X += p.first;
            Y += p.second;
        }
        cord = {X/Points.size(), Y/Points.size()};
    }

    pair<short, short> Get_center() {
        return cord;
    }

    void move(pair<short, short> movement) {
        cord.first += movement.first;
        cord.second += movement.second;
    }
};

//Аналог многоугольника, создается легче
class Rectangle: public Object {
    private:
    short length, height;

    public:

    Rectangle(pair<short, short> cord_center, short Length, short Height, map<string, void *>& Obj_list, const char *Color = &Bright): Object(cord_center) {
        length = Length;
        height = Height;
        Obj_list["Rectangle"] = this;
    }

    // 0.1.4 - Fixed - написана
    vector<Pixel> draw(const char *color = &Bright) {
        vector<Pixel> ret_list;
        pair<short, short> center = Get_center();
        for (short x = center.first - (length/2); x <= center.first + (length/2); ++x) {
                for (short y = center.second - (height/2); y <= center.second + (height/2); ++y) {
                    ret_list.push_back({x, y, color});
                }
        }

            return ret_list;
    }

    // одноразовый квадрат (1 кадр)
    static vector<Pixel> draw_onetime(pair<short, short> center, short Length, short Height, const char *color = &Bright) {
       vector<Pixel> ret_list;
       for (short x = center.first - (Length/2); x <= center.first + (Length/2); ++x) {
            for (short y = center.second - (Height/2); y <= center.second + (Height/2); ++y) {
                ret_list.push_back({x, y, color});
            }
       } 
        return ret_list;
    }

};


Место вызова
int main() {
    __init__(); —Инициализации ncurses.h и настройка
    Display display = {};

    Rectangle rect = {{10, 10}, 20, 20, display.Obj_map, &Bright};

    int ch = 0;

    while(display.close('q', ch)) {
        display.add_Objects();
        
        ch = display.read();
        rect.move(go(ch));
        //display.add_to_pool(Rectangle::draw_onetime({5, 5}, 10, 10));
        display.draw();
    }
    
    __end__(); // Завершение ncurses.h
}
  • Вопрос задан
  • 127 просмотров
Пригласить эксперта
Ответы на вопрос 1
@school_toddler
Вероятнее всего, это и-за буферизации, и ожидании ввода. "getch()" может считывать предыдущий ввод, даже если ты ждешь одного символа.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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