四、棋子
图像都是矩形的,而棋子都是圆的。怎样让棋子以外的部分透明呢?还是用PaintPicture这个方法。先用vbSrcAnd参数贴遮罩图,再用vbSrcInvert参数贴棋子图,就一切OK了。
先在通用部分添加如下代码:
Option Base 1 '设置数组下界
Dim Board(19, 19) As Integer '定义一个二元数组以判断棋盘上某区域的状态
Dim num As Integer '定义一个变量记录落子数目
再在Picture1_MouseDown过程中添加如下代码:
Dim stoneX As Integer '定义X轴系数以便对应棋盘数组Borad()并以此确定该区域内唯一的绘图起点
Dim stoneY As Integer '定义Y轴系数以便对应棋盘数组Borad()并以此确定该区域内唯一的绘图起点
Const lineStep = 360 '同前lineStep
Const lineModify = 540 - 360 '同前lineBegin-lineStep
Const stoneModify = 300 / 2 '棋子图尺寸的一半
stoneX = Round((X - lineModify) / lineStep)
stoneY = Round((Y - lineModify) / lineStep)
If stoneX > 0 And stoneX < 20 And stoneY > 0 And stoneY < 20 Then '设定落子的有效范围
If Board(stoneX, stoneY) = 0 Then '判断落子位置是否为空
If num Mod 2 = 0 And num <> 1 Then '用落子数目来判断落下的是黑子还是白子
Picture1.PaintPicture ImageList1.ListImages.Item(3).Picture, stoneX * lineStep + lineModify - stoneModify, stoneY * lineStep + lineModify - stoneModify, , , , , , , vbSrcAnd '用vbSrcAnd参数贴棋子遮罩图
Picture1.PaintPicture ImageList1.ListImages.Item(1).Picture, stoneX * lineStep + lineModify - stoneModify, stoneY * lineStep + lineModify - stoneModify, , , , , , , vbSrcInvert 'vbSrcInvert参数贴黑子图
Board(stoneX, stoneY) = 1 '标记该区域为黑子
num = num + 1
Else
Picture1.PaintPicture ImageList1.ListImages.Item(3).Picture, stoneX * lineStep + lineModify - stoneModify, stoneY * lineStep + lineModify - stoneModify, , , , , , , vbSrcAnd '用vbSrcAnd参数贴棋子遮罩图
Picture1.PaintPicture ImageList1.ListImages.Item(2).Picture, stoneX * lineStep + lineModify - stoneModify, stoneY * lineStep + lineModify - stoneModify, , , , , , , vbSrcInvert 'vbSrcInvert参数贴白子图
Board(stoneX, stoneY) = 2 '标记该区域为白子
num = num + 1
End If
End If
End If
五、结束语
现在,一个简单的棋盘就算画好了。如果再添上工具栏、文本框等等控件,就不会比MultiGo、弈通、围棋助手之类的样子差了(当然这几个软件都是C++写的,只是不知道开发工具用的是VC还是CB?)。不过,这也仅仅是个GUI而已,象提子、禁入等问题都没有解决,更谈不上读取和修改SGF文件等功能。要实现这些功能,就牵涉到算法。而算法的好坏,直接影响到软件的效率。这方面我就不误人子弟了,还是请老鸟们出马。
也许有人会问,象StoneBase那样漂亮的界面是怎么做出来的呢?可以告诉大家,那是Delphi+第三方控件做出来的。有空再向大家介绍吧。 |