棋盘绘制思路分享
在探索数字绘画与图形设计的旅途中,绘制一个传统的象棋棋盘无疑是一个既经典又充满挑战的项目。今天,我想和大家分享一种高效且富有创意的棋盘绘制方法,希望能激发你对图形编程的更多灵感。
确定基础框架
首先,明确棋盘的大小是关键。设定棋盘的总宽度和高度,并决定每个方格之间的间距为80像素,这不仅保证了棋盘的清晰度,也符合视觉上的舒适感。接着,确定背景颜色,通常选择淡色或中性色作为背景,以突出棋盘的主体部分。
矩形绘制法
不同于传统的线条绘制方法,我采用了绘制矩形的方式来构建棋盘。这种方法不仅简化了代码逻辑,还使得每个格子边缘更加平滑。
象路与楚河汉界
在绘制过程中,我特别注重了“象路”(即棋盘边缘的两条线)的细节处理。通过调整线条为虚线,使其更加贴近传统象棋棋盘的质感。同时,对于“楚河汉界”的绘制,我觉得还有提升的空间,就是改变字体的角度。
炮与兵的站位绘制
在绘制棋子站位时,我充分考虑了棋盘布局的对称性和实际对战需求。对于靠近边框的炮和兵站位,我巧妙地采用了分区绘制的方法:将棋盘分为左右两部分,分别处理站位的绘制逻辑。这样不仅避免了站位绘制出界的尴尬情况,还使得整个棋盘布局更加合理、美观。
源码
///////////////////////////////////////////////////
// 程序名称:中国象棋盘绘制
// 编译环境:Mictosoft Visual Studio 2022, EasyX_20200315(beta)
// 作 者:luoyh <2864292458@qq.com>
// 最后修改:2024-8-11
// 公 众 号:C语言研究
//
void drawChineseChessBoard(); // 绘制象棋盘
void drawZW(int x, int y, int num); // 绘制站位
void drawZ(int x, int y);
void drawY(int x, int y);
int main()
{
initgraph(740, 820);
drawChineseChessBoard();
_getch();
return 0;
}
void drawChineseChessBoard()
{
setbkcolor(RGB(252, 215, 162));
cleardevice();
setlinecolor(BLACK);
setlinestyle(PS_SOLID, 2);
rectangle(45, 45, 695, 775);
for (int j = 0; j < 9; j++)
{
for (int i = 0; i < 8; i++)
{
if (j == 4)
{
rectangle(50, 50 + j * 80, 130 + 7 * 80, 130 + j * 80);
RECT r = { 50 , 50 + j * 80, 130 + 7 * 80, 130 + j * 80 };
settextcolor(BLACK);
settextstyle(60, 0, _T("楷体"));
setbkmode(TRANSPARENT);
drawtext(_T("楚 河 汉 界"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
continue;
}
rectangle(50 + i * 80, 50 + j * 80, 130 + i * 80, 130 + j * 80);
}
}
setlinestyle(PS_DASH, 2);
// 绘制象路
line(50 + 80 * 3, 50, 50 + 80 * 5, 50 + 80 * 2);
line(50 + 80 * 5, 50, 50 + 80 * 3, 50 + 80 * 2);
line(50 + 80 * 3, 50 + 7 * 80, 50 + 80 * 5, 50 + 80 * 9);
line(50 + 80 * 5, 50 + 7 * 80, 50 + 80 * 3, 50 + 80 * 9);
// 绘制炮位兵位
drawZW(50 + 80, 50 + 80 * 2, 0);
drawZW(50 + 80, 50 + 80 * 7, 0);
drawZW(50 + 80 * 7, 50 + 80 * 2, 0);
drawZW(50 + 80 * 7, 50 + 80 * 7, 0);
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 5; j++)
{
int num = (j == 0) ? 2 : ((j == 4) ? 1 : 0);
drawZW(50 + j * 80 * 2, 50 + 80 * 3 + i * 80 * 3, num);
}
}
}
void drawZW(int x, int y, int num)
{
setlinestyle(PS_SOLID, 2);
// 当num为0时为全
// 当num为1时为左边
// 当num为2时为右边
switch (num)
{
case 0:drawZ(x, y); drawY(x, y); break;
case 1:drawZ(x, y); break;
case 2:drawY(x, y); break;
}
}
void drawZ(int x, int y) // 左边全
{
line(x - 5, y - 5, x - 5, y - 20);
line(x - 5, y - 5, x - 20, y - 5);
line(x - 5, y + 5, x - 20, y + 5);
line(x - 5, y + 5, x - 5, y + 20);
}
void drawY(int x, int y) // 右边全
{
line(x + 5, y - 5, x + 5, y - 20);
line(x + 5, y - 5, x + 20, y - 5);
line(x + 5, y + 5, x + 20, y + 5);
line(x + 5, y + 5, x + 5, y + 20);
}