我一直在查看我发现的一些代码,并试图了解它是如何工作的,但是当我编译代码时,我遇到了一些错误。代码中的文件是(抱歉长问题,但唯一重要的文件是Test.cpp文件,因为这是我构建的并且给出错误,其余的文件是因为我和#39;我有链接错误,所以我想表明以下方法确实存在但我仍然得到"未定义的引用"错误):
TetrisBlock.h
#ifndef TETRIS_BLOCK_INCLUDED
#define TETRIS_BLOCK_INCLUDED
#include "Common.h"
class CTetrisBlock
{
public:
void Create();
void Draw();
void Destroy();
CTetrisBlock();
virtual ~CTetrisBlock();
int GetPosX();
int GetPosY();
void SetPosX(int x);
void SetPosY(int y);
private:
int m_iPosX, m_iPosY;
};
#endif
TetrisBlock.cpp
#include "TetrisBlock.h"
CTetrisBlock::CTetrisBlock()
{
int num_blocks_x = WINDOW_WIDTH / (BLOCK_SIZE + BLOCK_SPACING);
int num_blocks_y = WINDOW_HEIGHT / (BLOCK_SIZE + BLOCK_SPACING);
m_iPosX = num_blocks_x / 2;
m_iPosY = num_blocks_y - 1;
}
CTetrisBlock::~CTetrisBlock()
{
Destroy();
}
void CTetrisBlock::Create()
{
}
void CTetrisBlock::Draw()
{
tRect quad;
quad.m_iLeft = m_iPosX * (BLOCK_SIZE + BLOCK_SPACING) + BLOCK_SPACING;
quad.m_iRight = quad.m_iLeft + BLOCK_SIZE - BLOCK_SPACING;
quad.m_iTop = m_iPosY * (BLOCK_SIZE + BLOCK_SPACING) - BLOCK_SPACING;
quad.m_iBottom = quad.m_iTop - BLOCK_SIZE + BLOCK_SPACING;
glColor3d(1,1,1);
glBegin(GL_QUADS);
glVertex3f(quad.m_iLeft, quad.m_iBottom, 0);
glVertex3f(quad.m_iRight, quad.m_iBottom, 0);
glVertex3f(quad.m_iRight, quad.m_iTop, 0);
glVertex3f(quad.m_iLeft, quad.m_iTop, 0);
glEnd();
}
void CTetrisBlock::Destroy()
{
}
void CTetrisBlock::SetPosX(int x)
{
m_iPosX = x;
}
void CTetrisBlock::SetPosY(int y)
{
m_iPosY = y;
}
int CTetrisBlock::GetPosX()
{
return m_iPosX;
}
int CTetrisBlock::GetPosY()
{
return m_iPosY;
}
TetrisFigure.h
#ifndef TETRIS_FIGURE_INCLUDED
#define TETRIS_FIGURE_INCLUDED
#include "TetrisBlock.h"
class CTetrisFigure
{
public:
void Create(int num_blocks);
void Draw();
void Destroy();
CTetrisBlock *GetBlock(int x, int y);
CTetrisBlock *GetBlock(int index);
CTetrisFigure();
virtual ~CTetrisFigure();
int GetBlockCount();
private:
CTetrisBlock **m_ppBlocks;
int m_iBlocksCount;
};
#endif
TetrisFigure.cpp
#include "TetrisFigure.h"
CTetrisFigure::CTetrisFigure()
{
m_ppBlocks = NULL;
m_iBlocksCount = 0;
}
CTetrisFigure::~CTetrisFigure()
{
Destroy();
}
void CTetrisFigure::Create(int num_blocks)
{
if(m_ppBlocks != NULL)
Destroy();
else
{
if(num_blocks > 0)
{
m_iBlocksCount = num_blocks;
m_ppBlocks = new CTetrisBlock*[num_blocks];
for (int i=0; i<num_blocks; i++)
m_ppBlocks[i] = new CTetrisBlock;
}
}
}
void CTetrisFigure::Destroy()
{
if(m_ppBlocks)
{
for (int i=0; i<m_iBlocksCount; i++)
{
if(m_ppBlocks[i] !=NULL)
delete m_ppBlocks[i];
}
delete[] m_ppBlocks;
}
m_ppBlocks = NULL;
}
void CTetrisFigure::Draw()
{
if(!m_ppBlocks)
return;
for (int i=0; i < m_iBlocksCount; i++)
{
if(m_ppBlocks[i] !=NULL)
m_ppBlocks[i]->Draw();
}
}
CTetrisBlock *CTetrisFigure::GetBlock(int x, int y)
{
for (int i=0; i<m_iBlocksCount; i++)
{
if(m_ppBlocks[i] !=NULL)
{
if(m_ppBlocks[i]->GetPosX() == x && m_ppBlocks[i]->GetPosY() == y)
return m_ppBlocks[i];
}
}
return NULL;
}
CTetrisBlock *CTetrisFigure::GetBlock(int index)
{
if(index >=0 && index < m_iBlocksCount)
return m_ppBlocks[index];
return NULL;
}
int CTetrisFigure::GetBlockCount()
{
return m_iBlocksCount;
}
TetrisGame.h
#ifndef TETRIS_GAME_INCLUDED
#define TETRIS_GAME_INCLUDED
#include "TetrisFigure.h"
#include "Common.h"
class CTetrisGame
{
public:
void Create();
void Draw();
void Destroy();
void MapFigure(CTetrisFigure *figure, bool assign);
CTetrisGame();
virtual ~CTetrisGame();
private:
int m_iScore;
CTetrisFigure *m_pTemplateFigures;
CTetrisBlock *m_pTemplateBlocks;
int m_iNumTemplateFigures;
int m_iNumTemplateBlocks;
CTetrisBlock ***m_ppTetrisMatrix;
CTetrisFigure *m_pCurrentFigure;
CTetrisFigure *m_pNextFigure;
};
#endif
TetrisGame.cpp
#include "TetrisGame.h"
CTetrisGame::CTetrisGame()
{
m_pCurrentFigure = NULL;
m_pNextFigure = NULL;
m_ppTetrisMatrix = NULL;
m_iScore = 0;
}
CTetrisGame::~CTetrisGame()
{
Destroy();
}
void CTetrisGame::Destroy()
{
if(m_pCurrentFigure)
m_pCurrentFigure = NULL;
int num_blocks_x = WINDOW_WIDTH / (BLOCK_SIZE + BLOCK_SPACING);
int num_blocks_y = WINDOW_HEIGHT / (BLOCK_SIZE + BLOCK_SPACING);
if(m_pTemplateBlocks)
{
delete[] m_pTemplateBlocks;
m_pTemplateBlocks = NULL;
}
if(m_pTemplateFigures)
{
delete[] m_pTemplateFigures;
m_pTemplateFigures = NULL;
}
if(m_ppTetrisMatrix)
{
for (int y=0; y<num_blocks_y; y++)
{
delete[] m_ppTetrisMatrix[y];
m_ppTetrisMatrix[y] = NULL;
}
delete[] m_ppTetrisMatrix;
m_ppTetrisMatrix = NULL;
}
m_iScore = 0;
}
void CTetrisGame::Draw()
{
int num_blocks_x = WINDOW_WIDTH / (BLOCK_SIZE + BLOCK_SPACING);
int num_blocks_y = WINDOW_HEIGHT / (BLOCK_SIZE + BLOCK_SPACING);
for (int i=0; i<num_blocks_y; i++)
{
for (int j=0; j<num_blocks_x; j++)
{
if(m_ppTetrisMatrix[i][j] !=NULL)
m_ppTetrisMatrix[i][j]->Draw();
}
}
}
void CTetrisGame::Create()
{
int num_blocks_x = WINDOW_WIDTH / (BLOCK_SIZE + BLOCK_SPACING);
int num_blocks_y = WINDOW_HEIGHT / (BLOCK_SIZE + BLOCK_SPACING);
m_ppTetrisMatrix = new CTetrisBlock**[num_blocks_y];
for (int i=0; i<num_blocks_y; i++)
{
m_ppTetrisMatrix[i] = new CTetrisBlock*[num_blocks_x];
for (int j=0; j<num_blocks_x; j++)
m_ppTetrisMatrix[i][j] = NULL;
}
}
void CTetrisGame::MapFigure(CTetrisFigure *figure, bool assign)
{
for (int i=0; i<figure->GetBlockCount(); i++)
{
if(assign)
{
if(figure->GetBlock(i) !=NULL)
m_ppTetrisMatrix[figure->GetBlock(i)->GetPosY()][figure->GetBlock(i)->GetPosX()] = figure->GetBlock(i);
}
else
{
if(figure->GetBlock(i) !=NULL)
m_ppTetrisMatrix[figure->GetBlock(i)->GetPosY()][figure->GetBlock(i)->GetPosX()] = NULL;
}
}
}
我自己构建了一个测试文件:Test.cpp
#include "TetrisGame.h"
CTetrisGame gTetrisGame;
void reshape(int w, int h) // Resize And Initialize The GL Window
{
if (h==0) // Prevent A Divide By Zero By
h=1; // Making Height Equal One
glViewport(0,0,w,h); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glOrtho(0, w, 0, h, 0, 100); // Set Up An Ortho Screen
//gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
}
void init() // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
/****************** NEW !!!!!! **************************************************************************/
/* Here we are creating a game instance by calling Create(), and allocating space for one figure
(you can add more if you want). Then, we set up coordinates for each block by using window' width
and height as base - let's assume we put our figure in the middle top of the window.
After that, we simply call MapFigure to assign blocks of the figure to game's grid array. That's it!
*/
gTetrisGame.Create();
CTetrisFigure *figure = new CTetrisFigure;
figure->Create(4);
int num_blocks_x = WINDOW_WIDTH / (BLOCK_SIZE + BLOCK_SPACING);
int num_blocks_y = WINDOW_HEIGHT / (BLOCK_SIZE + BLOCK_SPACING);
figure->GetBlock(0)->SetPosX(num_blocks_x / 2);
figure->GetBlock(0)->SetPosY(num_blocks_y - 2);
figure->GetBlock(1)->SetPosX((num_blocks_x / 2) + 1);
figure->GetBlock(1)->SetPosY(num_blocks_y - 2);
figure->GetBlock(2)->SetPosX((num_blocks_x / 2) + 1);
figure->GetBlock(2)->SetPosY(num_blocks_y - 1);
figure->GetBlock(3)->SetPosX(num_blocks_x / 2);
figure->GetBlock(3)->SetPosY(num_blocks_y - 1);
gTetrisGame.MapFigure(figure, true);
/***************** NEW !!!!!! **************************************************************************/
// Initialization Went OK
}
void display() // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); // Really Nice Perspective Calculations
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); // Really Nice Point Smoothing
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPushMatrix(); // Store The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glOrtho(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT, 0, 1); // Set Up An Ortho Screen
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glPushMatrix(); // Store The Modelview Matrix
glLoadIdentity();
/****************** NEW !!!!!! **************************************************************************/
/* Let's draw our game's grid onto the orthogonal set screen! */
gTetrisGame.Draw();
/****************** NEW !!!!!! **************************************************************************/
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glutSwapBuffers(); // swap the backbuffer with the front
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(800, 600);
glutInitWindowPosition(50, 50);
glutCreateWindow("Tetris!");
//glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
init();
glutMainLoop();
return 0;
}
当我尝试编译Test.cpp时,我在控制台中收到以下错误:
g++ -O3 -O3 -L/usr/X11R6/lib Test.cpp -lglut -lGL -lGLU -lX11 -lm -o Test
/tmp/ccaG5hQL.o: In function `global constructors keyed to gTetrisGame':
Test.cpp:(.text+0xa): undefined reference to `CTetrisGame::CTetrisGame()'
Test.cpp:(.text+0x19): undefined reference to `CTetrisGame::~CTetrisGame()'
/tmp/ccaG5hQL.o: In function `display()':
Test.cpp:(.text+0xc5): undefined reference to `CTetrisGame::Draw()'
/tmp/ccaG5hQL.o: In function `init()':
Test.cpp:(.text+0x15b): undefined reference to `CTetrisGame::Create()'
Test.cpp:(.text+0x170): undefined reference to `CTetrisFigure::CTetrisFigure()'
Test.cpp:(.text+0x17d): undefined reference to `CTetrisFigure::Create(int)'
Test.cpp:(.text+0x187): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x194): undefined reference to `CTetrisBlock::SetPosX(int)'
Test.cpp:(.text+0x19e): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x1ab): undefined reference to `CTetrisBlock::SetPosY(int)'
Test.cpp:(.text+0x1b8): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x1c5): undefined reference to `CTetrisBlock::SetPosX(int)'
Test.cpp:(.text+0x1d2): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x1df): undefined reference to `CTetrisBlock::SetPosY(int)'
Test.cpp:(.text+0x1ec): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x1f9): undefined reference to `CTetrisBlock::SetPosX(int)'
Test.cpp:(.text+0x206): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x213): undefined reference to `CTetrisBlock::SetPosY(int)'
Test.cpp:(.text+0x220): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x22d): undefined reference to `CTetrisBlock::SetPosX(int)'
Test.cpp:(.text+0x23a): undefined reference to `CTetrisFigure::GetBlock(int)'
Test.cpp:(.text+0x247): undefined reference to `CTetrisBlock::SetPosY(int)'
Test.cpp:(.text+0x25e): undefined reference to `CTetrisGame::MapFigure(CTetrisFigure*, bool)'
collect2: ld returned 1 exit status
make: *** [Test] Error 1
我的猜测是因为某些原因,Test.cpp中的变量gTetrisGame没有链接到CTetrisGame类,所以调用gTetrisGame.Draw()这样的方法会引发错误,因为它无法定位在类CTetrisGame中命名为Draw()的方法。我该如何解决这个错误?