飞扬围棋

 找回密码
 注册
搜索
查看: 8394|回复: 5
打印 上一主题 下一主题

[初级]棋盘界面的简单实现

[复制链接]
跳转到指定楼层
1#
发表于 2004-9-18 20:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式




先声明一下,如果您很熟悉编程,尤其是熟悉windows下的GUI编程,那么请您不要在这里浪费时间了。
经常看见论坛里有对电脑围棋技术感兴趣的菜鸟在“围棋软件”版块里问这问那,可惜老鸟多不屑(不愿?)回答。借着今天这个好日子,俺这只笨鸟就随便写点,算是抛砖引玉吧。
首先,人机对弈俺是不懂的,也没兴趣去研究那个拿奖金。所以,今天就教大家怎么画一个棋盘,而且是有木纹背景和图像棋子的那种。工具是VB6。为什么用这么老土的工具呢?因为它简单嘛。而且它不是真正的OO语言,即使读者对“面向对象编程”的概念不清楚,也可以照用不误。土专家俞斌的软件不都是拿QB或VB编的吗。要是换种工具,不要说C++、Java,就是Delphi、C#,恐怕也要先加一段“对象的概念”做前言才行。
话归正题,大家跟我一步步来:

一、准备工作
准备四张图片,分别是棋盘背景、黑子图、白子图、棋子遮罩图。

二、设计界面
启动VB6。没有装VB6的要先安装(废话)。默认情况下会有一个叫“Form1”的小窗体出现在中间。右边几个窗口里最重要的“属性”,等下要用到。左边长长的一条就是各种控件。
现在分别拖一个“PictureBox”控件和一个“Image”控件到“Form1”的小窗体上去。在“属性”窗口里找到“Image1”的Picture属性,载入棋盘背景那张图,然后把“Image1”的Visible属性设为False。再把“PictureBox1”的AutoRedraw属性设为True
用菜单“工程”→“部件”,在列出的一堆条目中把“microsoft windows common controls 6.0”选上,这样你会发现控件栏里又多了几项。再拖一个“ImageList”控件到“Form1”上。在“ImageList1”上单击右键,在弹出菜单里选“属性”,依次载入黑子图、白子图和棋子遮罩图。
好了,按F5键运行一下看看……这是什么东东?别急,下面我们来编写代码。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
2#
 楼主| 发表于 2004-9-18 20:42 | 只看该作者
三、棋盘代码
选择菜单“视图”→“代码窗口”,在Form_Load过程中添如下内容:
Form1.Height = 7970
Form1.Width = 7700
Picture1.Top = 0
Picture1.Left = 0
Picture1.Height = 7580
Picture1.Width = 7580
这几行是设定窗体和棋盘的位置、大小。

然后在Form_Paint过程中添如下内容:
Dim bgX As Integer '定义贴图横坐标变量
Dim bgY As Integer '定义贴图纵坐标变量
Dim lineX As Integer '定义纵线横坐标变量
Dim lineY As Integer '定义横线纵坐标变量
Dim starX As Integer '定义星位横坐标变量
Dim starY As Integer '定义星位纵坐标变量
Const bgBegin = 180 '定义贴图的开始坐标点
Const bgEnd = 6660 '定义贴图的结束坐标点
Const bgStep = 720 '定义贴图的坐标间距
Const lineBegin = 540 '定义第一根线的坐标点
Const lineEnd = 7020 '定义最后一根线的坐标点
Const lineStep = 360 '定义线的坐标间距
Const linePlus = 90 '定义边框与最外围线的距离
Picture1.Cls '用Cls方法预先清除以前的图象
For bgX = bgBegin To bgEnd Step bgStep '设定贴图横坐标的起止位置
For bgY = bgBegin To bgEnd Step bgStep '设定贴图纵坐标的起止位置
Picture1.PaintPicture Image1.Picture, bgX, bgY '用PaintPicture方法平铺贴图
Next bgY
Next bgX
Picture1.DrawWidth = 2 '设定输出线宽为2像素
Picture1.Line (lineBegin - linePlus, lineBegin - linePlus)-(lineEnd + linePlus, lineEnd + linePlus), , B '画棋盘边线
Picture1.DrawWidth = 1 '设定输出线宽为1像素
For lineX = lineBegin To lineEnd Step lineStep '设定纵线横坐标位置
Picture1.Line (lineX, lineBegin)-(lineX, lineEnd) '画19条纵线
Next lineX
For lineY = lineBegin To lineEnd Step lineStep '设定横线纵坐标位置
Picture1.Line (lineBegin, lineY)-(lineEnd, lineY) '画19条横线
Next lineY
Picture1.FillStyle = 0 '设定填充形式为实线
For starX = lineStep * 3 + lineBegin To lineEnd - lineStep * 3 Step lineStep * 6 '设定星位横坐标的位置
For starY = lineStep * 3 + lineBegin To lineEnd - lineStep * 3 Step lineStep * 6 '设定星位纵坐标的位置
Picture1.Circle (starX, starY), 30 '画9个星位
Next starY
Next starX
Picture1.FillStyle = 1 '设定填充形式为透明
就是几条循环语句和画线、画圆的方法而已,很容易看懂的。
需要注意的是PaintPicture这个方法,后面还会用到它。语法结构如下:
PaintPicture Picture,DestX,DestY,DestWidth,DestHeight,SourceX,SourceY,SourceWidth,SourceHeight,opcode
Picture是图形框、图像框或窗体的Picture属性,是图像的传送源。(必选参数)
DestX和DestY是传送目标的左上角坐标。(必选参数)
DestWidth和DestHeight是传送目标的区域大小。(可选参数)
SourceX和SourceY是传送源的左上角坐标。(可选参数)
SourceWidth和SourceHeight是传送源的区域大小。(可选参数)
opcode是传送方式,可参见API函数BitBlt。(可选参数)

运行一下,效果还不错吧。不过不能落子,工作还没做完。
回复 支持 反对

使用道具 举报

3#
 楼主| 发表于 2004-9-18 20:42 | 只看该作者

四、棋子
图像都是矩形的,而棋子都是圆的。怎样让棋子以外的部分透明呢?还是用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+第三方控件做出来的。有空再向大家介绍吧。
回复 支持 反对

使用道具 举报

4#
 楼主| 发表于 2004-9-18 20:46 | 只看该作者

这个是VB的源程序

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

5#
发表于 2004-9-19 09:59 | 只看该作者
3Q
回复 支持 反对

使用道具 举报

6#
发表于 2004-10-21 18:31 | 只看该作者
晕~晕~晕~晕~
真应该好好学习一下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|飞扬围棋网 ( 苏ICP备11029047号-1 )

GMT+8, 2024-11-27 07:52 , Processed in 0.212926 second(s), 22 queries .

since 2003飞扬围棋论坛 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表