ошибка объявления класса: недостаточно контекстной информации для определения типа

Я немного новичок в программировании и C++ и учусь программировать игры с помощью Allegro 5. Один из проектов, который я поставил перед собой, — очистить исходный код учебника Pong, который я нашел здесь: http://www.cppgameprogramming.com/newforums/viewtopic.php?f=5&t=1991

Однако я столкнулся с проблемой. Компилятор выдает ошибку, которую я не совсем понимаю, и ни одно из моих исследований не дает результатов. Ошибка:

недостаточная контекстная информация для определения типа

Ближайшим, что я нашел в Интернете, была эта страница: http://bytes.com/topic/c/answers/138897-error-insufficient-contextual-information-determine-type, что помогло мне понять, что проблема заключается в объявлениях классов. Однако представленное там решение не совсем применимо ко мне, поскольку конструкторы классов здесь принимают параметры. Ранее заданный здесь вопрос, по-видимому, также не относится к моей ситуации, поскольку он использовал вывод файла и шаблоны, ни один из которых я не использую.

Я разместил большую часть своей программы ниже, с частями, генерирующими ошибки, отмеченными звездочками с комментариями, чтобы их было легко найти, я надеюсь. Тем не менее, я оставил большую часть остального кода на случай, если он где-то еще.

На заметку: могут быть фрагменты кода, которые вы не узнаете из allegro 5, например, alObject.paint(255,255,255). Это я объединяю некоторые из объектов и функций аллегро в их собственный класс, чтобы облегчить мне задачу, источник которого я не включаю здесь, поскольку компилятор не генерирует с ними ошибок.

#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include "allegro.h"

struct CBox{
  CBox(int _x, int _y, int _w, int _h):x(_x),y(_y),w(_w),h(_h){}

  CBox(const CBox& other){
    x = other.x;
    y = other.y;
    w = other.w;
    h = other.h;
  }
  bool collides(const CBox& other){
    return not(other.x + other.w < x or other.y + other.h < y or other.x > x + y or other.y > y + h);
  }
  int x;
  int y;
  int w;
  int h;
};

class CPlayer{
private:
  int score;
  CBox box;
  ALLEGRO_COLOR color;
  double mov_y;
  void testBounds(CBox&);
public:
  CPlayer(CBox p, ALLEGRO_COLOR col):box(p),color(col){mov_y = 0.0;}
  void setScore(int new_s){score=new_s;}
  int getScore(){return score;}

  void setBox(const CBox& b){box=b;}
  CBox getBox(){return box;}

  void setXYMovement(double new_my){mov_y=new_my;}
  double getXYMovement(){return mov_y;}

  void move(CBox& bounds);

  void draw(){
    al_draw_filled_rectangle(box.x, box.y, box.x + box.w, box.y + box.h, color);
  }
};

class CBall{
private:
  CBox box;
  ALLEGRO_COLOR color;
  double mov_y;
  double mov_x;
  int last_touch;
  void testCollision(CBox&, const CBox&, CPlayer*);
  int testBounds(CBox&, const CBox&);
public:
  CBall(CBox p, ALLEGRO_COLOR col):box(p),color(col),last_touch(3){}
  void setXYMovement(double new_mx, double new_my){
    mov_x = new_mx;
    mov_y = new_my;
  }
  void move(const CBox& bounds, CPlayer* plys);
  void draw(){
    al_draw_filled_circle(box.x + box.w/2, box.y + box.h/2, box.w/2, color);
  }
};

class GameLoop{
private:
  CBox fieldbox(int, int, int, int);

/************************************************/
/***********ERROR HERE?? ERROR HERE??************/
/************************************************/
  CBall ball(const CBox&, ALLEGRO_COLOR);
  CPlayer player1(const CBox&, ALLEGRO_COLOR);
  CPlayer player2(const CBox&, ALLEGRO_COLOR);
/*************************************************/
/*************************************************/

public:
  GameLoop(Allegro&);
  void GameStart(Allegro&);
  void runTimerChecks(ALLEGRO_EVENT&, Allegro&);
  void runExit(ALLEGRO_EVENT&, Allegro&, bool&);
  void playerInput(ALLEGRO_EVENT&, bool&);
  void endPlayerInput(ALLEGRO_EVENT&);
};

void CPlayer::move(CBox& bounds){
  //make sure the player doesn't go off-bounds
  testBounds(bounds);
  box.y+=(int)mov_y;
  //Players can't move horizontally, so no bounds checking in that matter
}

void CPlayer::testBounds(CBox& bounds){
  if((mov_y < 0) && (box.y + mov_y < bounds.y)){
    box.y = bounds.y;
    mov_y = 0;
  }
  else if((mov_y > 0) && (box.y + box.h > bounds.y + bounds.h)){
    box.y = bounds.y + bounds.h - box.h;
    mov_y = 0;
  }
}

//ghostbox is the precalculated ball's trajectory
void CBall::move(const CBox& bounds, CPlayer* plys){
  CBox ghostbox(box.x+(int)mov_y, box.y+(int)mov_y, box.w, box.h);

  // test collision for box players
  testCollision(ghostbox, bounds, plys);
  testBounds(ghostbox, bounds);
}

void CBall::testCollision(CBox& ghostbox, const CBox& bounds, CPlayer* plys){
  for(int i = 0; i < 2; i++){
    //a player cannot touch the ball twice in a row
    if(i != last_touch){
      CBox other = plys[i].getBox();
      if(ghostbox.collides(other)){
        //set the last touch to this player
        last_touch = i;
        //negate the "ghost movement" in x axis
        ghostbox.x -= (int)mov_x;
        //bounce horizontally
        mov_x = -mov_x;
        //bounce vertically to change the ball's trajectory
        mov_y = (((box.y+box.h/2.0)-(other.y+other.h/2.0))/other.h)*10;
        break;
      }
    }
  }
}

int CBall::testBounds(CBox& ghostbox, const CBox& bounds){
  if(ghostbox.y < bounds.y){
    ghostbox.y = bounds.y;
    mov_y = -mov_y;
  }
  else if(ghostbox.y + ghostbox.h > bounds.y + bounds.h){
    ghostbox.y = (bounds.y + bounds.h - ghostbox.h);
    mov_y = -mov_y;
  }

  if(ghostbox.x + ghostbox.w < bounds.x){
    box.x = bounds.x + bounds.w/2 - bounds.w/2;
    box.y = bounds.y + bounds.h/2 - bounds.h/2;
    return 2;
  }
  else if(ghostbox.x > bounds.x + bounds.w){
    box.x = bounds.x + bounds.w/2 - box.w/2;
    box.y = bounds.y + bounds.h/2 - box.h/2;
    return 1;
  }
  box = ghostbox;
  return 0;
}

GameLoop::GameLoop(Allegro& alObject){
  // This box is our playfield (covers the whole screen)
  fieldbox(0,0,alObject.getWidth(), alObject.getHeight());
  //we setup the ball at the center of the screen with a white color
  ball(CBox(alObject.getWidth()/2-10,alObject.getHeight()/2-10,20,20),alObject.paint(255,255,255));

  //red player on the left 
  player1(CBox(10,alObject.getHeight()/2-80/2,20,80), alObject.paint(255,0,0));
  //blue player on the right
  player2(CBox(alObject.getWidth()-10-20,alObject.getHeight()/2-80/2,20,80), alObject.paint(0,0,255));
}

void GameLoop::GameStart(Allegro& alObject){
  /*
  when this variable is set to true the program will quit the main loop
  and free the allocated resources before quitting.
  */

  bool exit = false;

  //we tell the ball to move to the left

/***********************************************/
/***********************************************/
  ball.setXYMovement(-5.0,5.0); // GENERATES THE ERROR
/***********************************************/
/***********************************************/

  while(!exit){
    al_wait_for_event(alObject.eventq, NULL);
    while(al_get_next_event(alObject.eventq, &alObject.event)){
      if(alObject.event.type == ALLEGRO_EVENT_TIMER){
        runTimerChecks(alObject.event, alObject);
      }
      else if(alObject.event.type == ALLEGRO_EVENT_DISPLAY_CLOSE){
        // quit if the user tries to close the window
        runExit(alObject.event, alObject, exit);
      }
      else if(alObject.event.type == ALLEGRO_EVENT_KEY_DOWN){
        playerInput(alObject.event, exit);
      }
      else if(alObject.event.type == ALLEGRO_EVENT_KEY_UP){
        endPlayerInput(alObject.event);
      }
    }
  }
}

void GameLoop::runTimerChecks(ALLEGRO_EVENT& event, Allegro& alObject){
  if(alObject.event.timer.source == alObject.getTimer()){
    //fill the screen with black
    al_clear_to_color(alObject.paint(0,0,0));
    //move and draw our two players
/**************************************************/
/**************************************************/
    player1.move(fieldbox);  // GENERATES THE ERROR
    player1.draw();          // GENERATES THE ERROR
    player2.move(fieldbox);  // GENERATES THE ERROR
    player2.draw();          // GENERATES THE ERROR
/**************************************************/
/**************************************************/
  }
}

void GameLoop::runExit(ALLEGRO_EVENT& event, Allegro& alObject, bool& exit){
  if(event.display.source == alObject.getDisplay()){
    exit = true;
  }
}
void GameLoop::playerInput(ALLEGRO_EVENT& event, bool& exit){}
void GameLoop::endPlayerInput(ALLEGRO_EVENT& event){}

person Riverwolf    schedule 25.06.2013    source источник


Ответы (1)


Да, ошибка здесь:

CBall ball(const CBox&, ALLEGRO_COLOR);
CPlayer player1(const CBox&, ALLEGRO_COLOR);
CPlayer player2(const CBox&, ALLEGRO_COLOR);

Это не объявляет элементы переменные с именами ball, player1 и player2, как вы думаете (согласно коду вида: player1.draw();). Вместо этого вы написали объявление функций-членов с этими именами, принимающих в качестве аргумента указанные вами параметры. Вместо этого вы должны сделать:

CBall ball;
CPlayer player1;
CPlayer player2;

Затем в конструкторе GameLoop инициализируйте их любым значением, которое вы хотите, используя списки инициализации. :

GameLoop::GameLoop(Allegro& alObject) :
    ball(/* ... */),
    player1(/* ... */),
    player2(/* ... */)
{
    // ....
}
person Boris Dalstein    schedule 25.06.2013
comment
Огромное спасибо! Это исправило это. Извините, что надоедаю. - person Riverwolf; 25.06.2013