2

我是编程和 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)。那是我将一些 allegro 对象和函数合并到它们自己的类中,以使其对我来说更容易一些,我不包括这里的源代码,因为编译器不会对它们产生错误。

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

1 回答 1

2

是的,错误在这里:

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

这不会像您认为的那样声明名为,和的成员变量(根据类似代码:)。相反,您编写的是具有这些名称的成员函数的声明,将您指定的参数作为参数。相反,您应该这样做:ballplayer1player2player1.draw();

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(/* ... */)
{
    // ....
}
于 2013-06-25T10:59:19.710 回答