Riverwolf
Riverwolf

Reputation: 33

class declaration error: insufficient contextual information to determine type

I'm a bit of a newcomer to programming and C++, and learning how to program games with Allegro 5. One of the projects I've set for myself is to clean up a tutorial source code of Pong that I found here: http://www.cppgameprogramming.com/newforums/viewtopic.php?f=5&t=1991

However, I've run into a problem. The compiler generates an error I don't entirely understand, and none of my research is panning out. The error is:

insufficient contextual information to determine type

The closest I found on the internet was this page: http://bytes.com/topic/c/answers/138897-error-insufficient-contextual-information-determine-type which helped me narrow down that the problem is in the class declarations. However, the solution provided there doesn't exactly apply to me, since the class constructors here take parameters. The question previously asked here doesn't seem to apply to my situation, either, since it used file output and templates, neither of which I'm using.

I've posted a large chunk of my program below, with the error-generating parts marked out with commented stars to make them easy to find, I hope. However, I've left in a lot of the rest of the code on the off-chance that it's somewhere else.

As a heads up: there might be bits of code you don't recognize from allegro 5, such as alObject.paint(255,255,255). That's me consolidating some of the allegro objects and functions into their own class to make it a bit easier on me, the source of which I'm not including here since the compiler doesn't generate errors with them.

#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){}

Upvotes: 2

Views: 2347

Answers (1)

Boris Dalstein
Boris Dalstein

Reputation: 7748

Yes, the error is here:

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

This doesn't declare member variables called ball, player1 and player2, as you think it does (according to code like: player1.draw();). Instead, what you've written is a declaration of member functions with these names, taking in argument the parameters you've specified. Instead, you should do:

CBall ball;
CPlayer player1;
CPlayer player2;

Then in the constructor of GameLoop, initialize them with whatever value you want, using initialization lists:

GameLoop::GameLoop(Allegro& alObject) :
    ball(/* ... */),
    player1(/* ... */),
    player2(/* ... */)
{
    // ....
}

Upvotes: 2

Related Questions