Bước này xây dựng lớp CBoard để quản lý bàn cờ
Tạo 2 file Board.h, Board.cpp cho project "game" (Lưu trong thư mục source)
Board.h
#ifndef __BOARD__
#define __BOARD__
#include "gametutor.h"
class CCell
{
public:
CCell(__INT32 ID);
virtual ~CCell();
void Render(CGraphics2D* g, int x, int y);
private:
__INT32 m_iID;
CSprite* m_pSpriteRef;
};
Board.cpp
#include "Board.h"
#define CELL_REGION 96
CCell::CCell(__INT32 ID): m_iID(ID), m_pSpriteRef(0)
{
char spr_name [50];
char anim_name [50];
sprintf (spr_name, "CELL_%d", m_iID);
m_pSpriteRef = CSpriteManager::GetInstance()->Get(spr_name);
if (!m_pSpriteRef)
{
char ErrorMessage [100];
sprintf (ErrorMessage, "Sprite %s is not found", spr_name);
BREAK(ErrorMessage);
}
else
{
memset(anim_name, 0, 50);
sprintf (anim_name, "%d", ID);
m_pSpriteRef->SetAnimation(anim_name);
}
}
CCell::~CCell() {}
void CCell::Render(CGraphics2D* g, int x, int y)
{
m_pSpriteRef->SetPosition(SPosition2D<__INT32>(x, y));
m_pSpriteRef->RenderAnimation(g);
}
Khi được khởi tạo, tùy vào ID, m_pSpriteRef sẽ tham chiếu đến sprite tương ứng theo tên.
sprintf (spr_name, "CELL_%d", m_iID);
m_pSpriteRef = CSpriteManager::GetInstance()->Get(spr_name);
Lưu ý, các sprite cần được load trước khi khởi tạo các Cell. Trong trường hợp các sprite chưa được load, chương trình sẽ thông báo lỗi:
if (!m_pSpriteRef)
{
char ErrorMessage [100];
sprintf (ErrorMessage, "Sprite %s is not found", spr_name);
BREAK(ErrorMessage);
}
Nếu đã có sprite, tiến hành thiết lập animation ứng với ID
else
{
memset(anim_name, 0, 10);
sprintf (anim_name, "%d", ID);
m_pSpriteRef->SetAnimation(anim_name);
}
Cell cung cấp hàm render, dùng để vẽ cell tại một vị trí cụ thể. Thực chất của hàm này là vẽ animation của sprite tham chiếu.
m_pSpriteRef->SetPosition(SPosition2D<__INT32>(x, y));
m_pSpriteRef->RenderAnimation(g);
Vẫn dùng file Board.h, Board.cpp để viết tiếp lớp CBoard
Board.h
....
class CBoard
{
public:
CBoard(__INT32 size);
virtual ~CBoard();
void SetPosition(__INT32 x, __INT32 y);
void Render(CGraphics2D* g);
private:
__INT32 m_iSize;
__INT32 m_iSizeSquare;
__INT32 m_iX;
__INT32 m_iY;
CCell** m_Cells;
__INT32* m_pBoardData;
};
#endif
Với Board.cpp,
CBoard::CBoard(__INT32 size): m_iSize(size), m_iSizeSquare(size*size), m_iX(0), m_iY(0), m_Cells(0)
{
m_Cells = new CCell*[m_iSizeSquare - 1];
for (int i = 0; i < m_iSizeSquare - 1; i++)
{
m_Cells[i] = new CCell(i+1);
}
m_pBoardData = new __INT32[m_iSizeSquare];
for (int i = 0; i < m_iSizeSquare; i++)
{
m_pBoardData[i] = i;
}
}
Với size là kích thước bàn cờ. size = 3: bàn cờ 3x3; 4: bàn cờ 4x4; 5: bàn cờ 5x5. Hàm này khởi tạo (size*size-1) cell.
m_pBoardData cho biết giá trị tại một Cell, với các giá trị 0 cho số "1", 1 cho số "2", ... (size*size-1) cho ô trống. Việc lưu trữ m_pBoardData bằng mãng 1 chiều thay vì mãng 2 chiều sẽ thuận tiện hơn trong việc xử lý sau này
CBoard::~CBoard()
{
SAFE_DEL_ARRAY_OBJ(m_Cells, m_iSizeSquare - 1);
SAFE_DEL_ARRAY(m_pBoardData);
}
void CBoard::SetPosition(__INT32 x, __INT32 y)
{
m_iX = x;
m_iY = y;
}
void CBoard::Render(CGraphics2D* g)
{
int x = m_iX;
int y = m_iY;
int index = 0;
for (int i = 0; i < m_iSize; i++)
{
for (int j = 0; j < m_iSize; j++)
{
int spr_id = m_pBoardData[index++];
if (spr_id < m_iSizeSquare - 1)
{
m_Cells[spr_id]->Render(g, x, y);
}
x += CELL_REGION;
}
y += CELL_REGION;
x = 0;
}
}
#ifndef __CSTATEINGAME_H__
#define __CSTATEINGAME_H__
#include "gametutor.h"
#include "Board.h"
class CStateIngame :public CState
{
public:
CStateIngame(): CState(), m_pBoard(0) {}
~CStateIngame() {}
void Init();
void Update();
void Render();
void Exit();
void OnControllerEvent(SControllerEvent Event);
private:
CBoard* m_pBoard;
};
#endif
void CStateIngame::Init()
{
char buffer [50];
for (int i = 0; i < MAX_CELL; i++)
{
memset(buffer, 0, 50);
sprintf (buffer, "CELL_%d", i+1);
CSprite *spr = CSpriteManager::GetInstance()->AddSprite<CFileWin32Driver>(buffer, SPR_CELL);
}
CGraphics2D::GetInstance()->Reset();
m_pBoard = new CBoard(4);
}
void CStateIngame::Render()
{
CGraphics2D::GetInstance()->Clear(SColor<float>(0, 0, 0, 1));
m_pBoard->Render(CGraphics2D::GetInstance());
CGraphics2D::GetInstance()->Flush();
}
Source code Board
//cBoard.h #ifndef __BOARD__ #define __BOARD__ #include "gametutor.h" class CCell { public: CCell(__INT32 ID); virtual ~CCell(); void Render(CGraphics2D* g, int x, int y); private: __INT32 m_iID; CSprite* m_pSpriteRef; }; class CBoard { public: CBoard(__INT32 size); virtual ~CBoard(); void SetPosition(__INT32 x, __INT32 y); void Render(CGraphics2D* g); private: __INT32 m_iSize; __INT32 m_iSizeSquare; __INT32 m_iX; __INT32 m_iY; CCell** m_Cells; __INT32* m_pBoardData; }; #endif
//CBoard.cpp #include "Board.h" #define CELL_REGION 96 CCell::CCell(__INT32 ID): m_iID(ID), m_pSpriteRef(0) { char spr_name [10]; char anim_name [10]; sprintf (spr_name, "CELL_%d", m_iID); m_pSpriteRef = CSpriteManager::GetInstance()->Get(spr_name); if (!m_pSpriteRef) { char ErrorMessage [100]; sprintf (ErrorMessage, "Sprite %s is not found", spr_name); BREAK(ErrorMessage); } else { memset(anim_name, 0, 10); sprintf (anim_name, "%d", ID); m_pSpriteRef->SetAnimation(anim_name); } } CCell::~CCell() {} void CCell::Render(CGraphics2D* g, int x, int y) { m_pSpriteRef->SetPosition(SPosition2D<__INT32>(x, y)); m_pSpriteRef->RenderAnimation(g); } CBoard::CBoard(__INT32 size): m_iSize(size), m_iSizeSquare(size*size), m_iX(0), m_iY(0), m_Cells(0) { m_Cells = new CCell*[m_iSizeSquare - 1]; for (int i = 0; i < m_iSizeSquare - 1; i++) { m_Cells[i] = new CCell(i+1); } m_pBoardData = new __INT32[m_iSizeSquare]; for (int i = 0; i < m_iSizeSquare; i++) { m_pBoardData[i] = i; } } CBoard::~CBoard() { SAFE_DEL_ARRAY_OBJ(m_Cells, m_iSizeSquare - 1); SAFE_DEL_ARRAY(m_pBoardData); } void CBoard::SetPosition(__INT32 x, __INT32 y) { m_iX = x; m_iY = y; } void CBoard::Render(CGraphics2D* g) { int x = m_iX; int y = m_iY; int index = 0; for (int i = 0; i < m_iSize; i++) { for (int j = 0; j < m_iSize; j++) { int spr_id = m_pBoardData[index++]; if (spr_id < m_iSizeSquare - 1) { m_Cells[spr_id]->Render(g, x, y); } x += CELL_REGION; } y += CELL_REGION; x = 0; } }