Не удается получить доступ к игровым объектам "должна быть вызвана ссылка на нестатическую функцию-член" - PullRequest
0 голосов
/ 25 декабря 2018

Я делаю игру со змеями и пытаюсь преобразовать свою основную функцию в вызов объекта Game (Game.run () или что-то в этом роде).Я опубликую весь код ниже, но базовая настройка состоит в том, что у меня есть объект Snake, окно (которое выполняет для меня рендеринг), объект Food и пара таймеров.В текущей основной функции я создаю их все в начале, а затем использую их позже.Я хочу преобразовать все это в класс Game, в котором в качестве переменных экземпляра используются Snake, Window, Food и Timers.У меня проблема в том, что я не могу получить доступ к этим участникам позже!Я получаю сообщение об ошибке: "C ++" ссылка на нестатическую функцию-член должна быть вызвана ".

Вот фрагмент оригинального кода:

int main( int argc, char* args[] ) {
  Window window("Snake", GRID_WIDTH, GRID_HEIGHT, GRID_STRIDE);
  Snake snake(window, GRID_STRIDE, 20, 20, 255, 255, 255, 255);
  Food food(window, GRID_WIDTH, GRID_HEIGHT, GRID_STRIDE, 192, 192, 192, 255, time(0));
  Timer fpsTimer;
  Timer capTimer;

  int countedFrames = 0;
  fpsTimer.start();
  bool updateDisplay = true;
  while (!window.isClosed()) {
    capTimer.start();
    pollEvents(window, snake);
    if (updateDisplay && !snake.isDead()) {
      window.draw();
      snake.draw();
      food.draw();
      checkCollisions(snake, food);
      snake.checkSelfEat();
    }
}

Это работает нормально. Но когдаЯ превращаю его в игровой класс:

//game.h

class Game {
  public:
    Game(int g_width, int g_height, int g_stride, int fps);
    virtual ~Game() {};
    void run();

  private:
    int grid_width, grid_height, grid_stride, screen_fps, screen_ticks_per_frame;
    Window window(std::string title, int g_width, int g_height, int g_stride);
    Snake snake(Window &window, int g_stride, int x, int y, int r, int g, int b, int a);
    Food food(Window &window, int g_width, int g_height, int g_stride, int r, int g, int b, int a, int random_seed);
    Timer fpsTimer, capTimer;
};

с реализацией:

// game.cpp

Game::Game(int g_width, int g_height, int g_stride, int fps) :
grid_width(g_width), grid_height(g_height), grid_stride(g_stride), screen_fps(fps) {
  Window window("Snake", grid_width, grid_height, grid_stride);
  Snake snake(window, grid_stride, 20, 20, 255, 255, 255, 255);
  Food food(window, grid_width, grid_height, grid_stride, 192, 192, 192, 255, time(0));
  Timer fpsTimer;
  Timer capTimer;
  screen_ticks_per_frame = 1000 / screen_fps;
}

void Game::run() {
  int countedFrames = 0;
    fpsTimer.start();
    bool updateDisplay = true;
    while (!window.isClosed()) {
      capTimer.start();
      pollEvents(window, snake);
      if (updateDisplay && !snake.isDead()) {
        window.draw();
        snake.draw();
        food.draw();
        checkCollisions(snake, food);
        snake.checkSelfEat();
      }
};

Мне бы очень хотелось это понять, я получил ту же ошибку, когда пытался использовать тестовые приспособления GoogleTestтоже. Если кто-нибудь может сказать мне, что я делаю неправильно, это было бы здорово!

Например, одна ошибка:

ошибка: ссылка на нестатическую функцию-член должна быть вызвана, в то время как(! window.isClosed ()) {

С подчеркнутым окном. КАЖДЫЙ экземпляр окна, змея, еда, таймер с ошибками, с подчеркнутым экземпляром.

Некоторая помощь в этом действительнобудьте благодарны, извините, если я не был достаточно ясен в этом посте.

1 Ответ

0 голосов
/ 25 декабря 2018

В вашем коде есть две фундаментальные проблемы.Во-первых, вы объявляете private функции, а не переменные-члены.Для объявления переменных-членов вам нужно использовать только тип и имя переменной, например:

class Game {
  // public omitted for brevity
  private:
    int grid_width, grid_height, grid_stride, screen_fps, screen_ticks_per_frame;
    Window window;
    Snake snake;
    Food food;
    Timer fpsTimer, capTimer;
};

Вторая проблема заключается в том, что в теле вашего конструктора вы объявляете локальные переменные с тем же именем, что и«члены» - это не одно и то же, и локальные уничтожаются после завершения конструктора.
Вы должны использовать список инициализаторов элементов , как вы уже делаете для int членовНапример:

Game::Game(int g_width, int g_height, int g_stride, int fps) :
grid_width(g_width), grid_height(g_height), grid_stride(g_stride), 
screen_fps(fps), window("Snake", grid_width, grid_height, grid_stride), 
snake(window, grid_stride, 20, 20, 255, 255, 255, 255), 
food(window, grid_width, grid_height, grid_stride, 192, 192, 192, 255, time(0)),
screen_ticks_per_frame(1000 / screen_fps){
  // no need to repeat the Timers
}
...