| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2915 人关注过本帖, 2 人收藏
标题:兴趣是这样培养的---从一个游戏开始
只看楼主 加入收藏
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
结帖率:100%
收藏(2)
已结贴  问题点数:0 回复次数:33 
兴趣是这样培养的---从一个游戏开始
华容道.rar (740.75 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册

  春暖花开,总有一些想做些什么的冲动!但毕竟很久没写代码了,业务生疏,于是到论坛上来逛逛,看能否启迪思维、温故而知新。结果发现这个论坛冷清,有的只是些初学者活跃其中,问些不着边际的问题,很多人只是丢下问题,连再回来的兴趣都没有;这不由得让我想起当初,决定开此贴,一来当练手,二来看能否激发许多初学者学编程的兴趣!
  九十年代初我就开始写程序了,虽然资深但绝对业余;那时还是Dos时代,我最拿手的就是用汇编做些内存驻留程序,拦截Dos中断,做些小开发,满足好奇心。那时我不会C,也不会Basic,仅仅只有些概念;一天,一个同事的儿子到单位完,带了一个益智玩具,也就是“华容道”,我玩了一上午也没通关;后来同事的儿子把玩具拿回家,我没的玩了;我突然想我应该可以把这个变成电脑游戏的。汇编是不可能做的到了,当时的电脑都普遍带Qbasic解释程序,通过找资料,反复看书、实验,我还真做了出来,我记得当时是要进入图形状态,用画图命令写的;通过写“华容道”游戏把我引进了Basic,后来有了VB,从VB4到VB6,我都用过。总的来说,有所得,有所失,得到的是我用VB做了些实用的程序并有所应用,失去的是我至今还不会写其他语言的程序,如VC;我最近一次写程序应该是08年学.Net时写的一个理财软件,近三年再没写代码了!
  废话不多说,我是通过写“华容道”游戏开始对写程序感兴趣的,我想这也能激发其他初学者的兴趣,因此,我决定用VB6重写“华容道”游戏(尽管网上有很多Flash的了),我将附上所有源码,并尽我所能做些注解。
  一、    对工程中的控件说明
我已经做好“华容道”的工程文件,并打包好供同志们下载,不过这个工程里只有事先设计好的窗口控件,没写一行代码,在后面我将边讲解边添加代码,直到让程序鲜活起来;包里有一个已经编译好的“华容道.exe”文件,大家写代码累了可以玩玩它,它实现了部分功能,我最短是89步完成。
  “华容道”工程设计窗口如图,在窗体里我首先放一个frame1控件用于图片移动的容器,图片是用image控件数组做的,名称从img(0)至img(9),图片的大小和所需图片我已经设计好,需要说明的是,每个图片控件的DataFiled属性我都用来表示该图片的大小,比如img(4)的图片最大,它DataFiled的属性值为“2,2”,表示该图片宽高均为2的正方形,而img(0)的值为“1,1”,表示该图片宽高均为1的正方形,而img(6)的属性值为“2,1”,表示该图片宽为1,高为2,是个竖着的长方形,同理img(5)的属性值为“1,2”,表示该图片宽为2,高为1,是一个横着的长方形;这些值在设计时我已人为输入,高和宽分别用逗号间隔,前面表示图形的高,后面为宽,之所以要这样,是有利于设计程序时使用算法,减少代码量;DataFiled属性一般是在使用数据库时是用来绑定字段的,在这里不需要数据库。
  在设计时我还放了两个定时器(Timer)控件,一个取名为“TimerFlash”,它设定的定时时间为300毫秒,主要用于游戏时对选择的图片闪烁提醒用的;另一个取名为“TimerAuto”,主要用来播放自动演示的;在窗体里我还放了其他一些控件,主要是些标识标签、控制按钮等,都在图片上列出名称了,很容易理解。窗体名称为“MainForm”,其BorderStyle属性值是Fixed Single,即单一属性,运行后不能调整窗体大小。
  好,先说到这里,后面我将逐步添加各种功能的代码,并做算法说明。
收到的鲜花
  • Artless2011-04-23 00:46 送鲜花  5朵   附言:好文章
搜索更多相关主题的帖子: 春暖花开 游戏 
2011-04-17 14:23
Artless
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:4211
专家分:28888
注 册:2009-4-8
收藏
得分:20 
图片附件: 游客没有浏览图片的权限,请 登录注册

无知
2011-04-17 23:40
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
二、    规划功能及算法
  前面说过,写程序我纯粹是业余的,我没学过“程序设计方法学”,也不知道如何规划并完成一个软件工程项目。但我每次写程序前都要花很长时间规划程序功能,越详细越好,这个习惯纯粹是长期积累养成的。我觉得事先规划好程序功能有几个好处:首先是能让程序员保持头脑清晰,不打乱仗;其次是当一个一个功能完成时,有进度感;再就是功能规划清楚,完成功能的各代码目标明确,不相互交叉,提高了代码的安全性;还有就是功能规划清楚,可以事先提取各功能间的共同点,规划数据结构的一致性,减少代码量。
  在设计之前,我玩过不同版本的“华容道”,发现他们都有不同关卡,有一种版本的牛人还可以让玩家设计关卡,有每种关卡最佳玩法演示。因此,我希望我设计的“华容道”即使只有一个关卡,也能支持将来拓展不同关卡,这就需要设计一种数据结构用来描述关卡;再就是,我也希望程序支持演示、回溯等功能,因此也需要一种数据结构描述存储操作步数;要完成这些,功能就很清楚了:能移动图片并进行合理性判断是最基本的,其次支持关卡、支持单步回溯、支持标准玩法演示等等,还有存储等其他功能可以在以后扩充;接下来,我还要对本游戏中所要使用的数据及方法进行描述。
图片附件: 游客没有浏览图片的权限,请 登录注册

  如图,本游戏是要在一个方框内移动9个图片,图片大小不同,但都有规律,最小的是编号0至3的图片,它们是个正方形,我们可以用它作为最小单位,把整个方框划分为高为5,宽为4的矩形,用数组表示为(4,3)即0至4共5行,0至3共4列(之所以从0开始是因为VB数组都是从0起的),这样一来,任何图片在方框中只有5*4=20个放置位置,我们从左至右从上到下按1至20分别为这些位置编号;位置编号和行列号都有公式进行互换的,公式是:
  编号=行*4+列+1
  行=INT((编号-1)/4)
  列=(编号-1) MOD 4
  上述公式将会在代码中经常应用,有兴趣的最好能理解这个公式。编号后即可根据编号设计所需要的数据结构了。我是用字符串结构描述数据结构的,这样初学者容易理解,VB又有强大的字符串处理能力。首先是关卡数据结构,关卡的数据就是描述每个图片第一次的放置位置,因此只需要图片编号和位置编号,图片只需要一位字符,位置需要两位字符表示,描述每个图片位置之间用逗号间隔,比如默认的关卡数据为“601,402,704,809,510,912,114,215,017,320”,解释起来就是:图片6位置1,图片4位置2…图片0位置17,图片3位置20。如有其他关卡就有不同的字符串。接下来描述操作步数的数据,操作步数的数据可用来单步回溯以及自动演示,该数据结构大致同关卡数据,只是多两位字符描述目标位置编号,例如:“60102,30406”,意思是第一步图片6由1到2,第二步图片3由4到6等等,以此类推。
  好了,本程序的功能及所用算法、数据结构介绍完毕,后面将正式进入书写代码阶段。
2011-04-18 13:26
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
  三、    代码之旅(1)---声明及控制窗体
  在写代码之前,我希望有兴趣的初学者不要毫不犹豫地拷贝粘贴代码,而是仔细地一行行看懂再复制。编程前先要声明你所要用到的常量、变量,我声明了一个常量和四个全程变量(全程变量和全局变量还是有区别的),各自的用途我都做了说明。接下来写了个initSize子程序,原本只想初始化各变量,但发现我的设计的窗体偏小,各美女图片看不大清楚,因此临时决定让该子程序可通过参数iSize调整窗口大小,iSize是最小正方形图片的边长,单位是“像素点”。你可以在Form_Load里输入代码以验证函数运行效果,方法如下:
Private Sub Form_Load()
  InitSize 120
End Sub
  你可以将120改成其他数字查看不同的运行效果该子程序相应地方我都做了注释,请仔细阅读。
Const Card1 = "601,402,704,809,510,912,114,215,017,320" '横刀立马关卡的数据
Dim bSize As Integer, imgSel As Integer, iStep As String, iStepCount As Integer
'四个全程变量,bSize用于设置一个图片最基本大小,最小正方形图片就是bSize这么大
'imgSel用于暂存当前选择的图片编号,使选中的图片闪烁就使用该变量
'iStep用于存放移动的历史记录,可依据该数据还原和演示
'iStepCount用于计步数

Private Sub initSize(iSize As Integer)
  '通过iSize给出的像素值计算窗口的大小,并将该值传给bSize作为全局计算的依据
  '初始化所有量
  Dim i As Integer, b() As String, pic As Image
  imgSel = -1 '当前没有选择任何图片
  Label2.Caption = "0"
  Frame1.Enabled = True
  iStepCount = 0
  iStep = ""
  If iSize < 81 Then iSize = 81  '最小像素是81
  bSize = iSize * 15 '将像素转换为缇
  Me.Height = 5 * bSize + 1350
  Me.Width = 4 * bSize + 240  '计算并调整窗体大小
  Frame1.Width = 4 * bSize
  Frame1.Height = 5 * bSize
  Frame1.Left = 75
  Frame1.Top = 75          '计算调整图片移动框的大小并设定位置
  Label1.Width = 2 * bSize
  Label1.Top = Frame1.Height - Label1.Height
  Label1.Left = bSize        '计算并放置华容道出口标签
  Frame2.Top = Frame1.Height + 75
  Frame2.Left = (Me.Width - Frame2.Width) / 2
  For Each pic In Img
    '循环遍历所有图片并初始化各属性以及计算设定图片大小
    pic.Visible = False
    pic.Stretch = True
    pic.Appearance = 0
    pic.BorderStyle = 1
    b() = Split(pic.DataField, ",")
    '获取要放置图片的大小属性,该属性在设计时即人为写在了各图片的DataField属性中
    pic.Height = bSize * Val(b(0))
    pic.Width = bSize * Val(b(1))
  Next
End Sub
2011-04-19 21:33
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
四、    代码之旅(2)---放置一个图片并检测合法性
  前面已经实现了窗体的显示,但不能显示图片,本来要在窗体兰色框里显示图片是很简单的,先只需要计算出图片的放置坐标,放到图片的Left和Top属性里,再将图片的Visible属性设为True即可,但是图片有不同的尺寸,同时图片放置时不能超出兰色容器的(Frame1)边框,也不能在已放置图片的位置上重复放置其他图片,因此,放置一个图片是否成功先要进行合法性检测,这个任务由函数testSetImg完成,testSetImg函数有两个参数,参数index是要放置的图片编号(0—8),pos是图片放置位置编号(1—20),如果放置图片合法则返回True,否则返回False。放置图片的子程序为putAImg,同样有index和pos两个参数。 这两个函数正确输入后,即可在窗体的load事件中实验运行,方法如下:
Private Sub Form_Load()
  InitSize 120   '初始化窗体
  PutAImg 4,1    '将图片4放到位置1处,图片4是曹操,位置1是行0,列1
End Sub
'*********以下是合法性检测函数和放置一个图片的代码**********
Private Function testSetImg(index As Integer, pos As Integer) As Boolean
  '本函数检测指定图片放置的位置是否合法,如果合法则返回true,否则返回false
  '根据最小图片的尺寸,我们先将放置图片的容器分解为5行4列的矩阵,行0-4,列0-3
  '然后将矩阵从左上角到右下角编号为1至20
  '行列到编号的算法是:编号=行*4+列+1
  '编号到行列号的算法是:行=int((编号-1)/4) 列=(编号-1) mod 4
  Dim x1 As Integer, y1 As Integer, b() As String, p(4, 3) As Integer
  Dim i As Integer, j As Integer, f As Boolean, pic As Image
  testSetImg = False
  If pos < 1 Or pos > 20 Then Exit Function '如果编号不合理就返回false,编号只能在1到20之间的数据(包含1,20)
  For i = 0 To 4
    For j = 0 To 3
      p(i, j) = 0
    Next
  Next
  '清空图片占据位置的标志,0:没占据 1:已经被图片占据
  For Each pic In Img
    If pic.index <> index And pic.Visible Then
      y1 = pic.Top / bSize   '图片所占据的行位置
      x1 = pic.Left / bSize  '图片所占据的列位置
      b = Split(pic.DataField, ",") '图片大小高在b(0)中,宽在b(1)中
      For i = 1 To Val(b(0))
        For j = 1 To Val(b(1))
          p(y1 + i - 1, x1 + j - 1) = 1 '图片占据的位置打上标志1
        Next
      Next
    End If
  Next
  x1 = (pos - 1) Mod 4      '图片要测试位置的列值
  y1 = Int((pos - 1) / 4)   '图片要测试位置的行值
  b = Split(Img(index).DataField, ",") '要测试的图片高在b(0)中,宽在b(1)中
  f = True
  For i = 1 To Val(b(0))
    For j = 1 To Val(b(1))
      If y1 + i - 1 > 4 Or x1 + j - 1 > 3 Then f = False   '如果显示的图片超出边界则显示不合法
      If Not f Then Exit For  '如果已经测试到不合法值则退出循环
      If p(y1 + i - 1, x1 + j - 1) <> 0 Then f = False     '如果在指定的位置已经有别的图片存在则显示不合法
    Next
    If Not f Then Exit For    '如果已经测试到不合法值则退出循环
  Next
  testSetImg = f
End Function

Private Sub putAImg(index As Integer, pos As Integer)
  '本过程将指定图片index放置到指定编号pos位置
  Dim x1 As Integer, y1 As Integer
  x1 = (pos - 1) Mod 4      '图片要放置位置的列值
  y1 = Int((pos - 1) / 4)   '图片要放置位置的行值
  If testSetImg(index, pos) Then
    '如果放置图片合格则设置图片放置位置并显示图片
    Img(index).Left = x1 * bSize
    Img(index).Top = y1 * bSize
    Img(index).Visible = True
  End If
End Sub
2011-04-20 21:47
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
  五、    代码之旅(3)---让图片动起来
  我们已经实现了放置并显示一个图片,如果我们通过一定的代码引用代码之旅(1)里声明的常量Card1的数据,就可以显示所有的图片,接下来我们就要让图片移动起来。为了移动图片我差点写了个“寻路算法”的代码,那将相当复杂,还要用到循环嵌套,后来我想到在本例中只有两个空格可供移动,它移动的方式只有几种,根本不需要写“寻路算法”,最后稍微归纳了下,图片的移动只有横移、竖移和斜移三种情况,对这三种分别处理就可以了,移动图片是函数moveAImg完成的,移动成功则返回True,否则返回False,该函数同样有图片编号和移动目的地编号。为了不让图象移动起来生硬,我还写了个子程序aniAImg,这样图片移动过程中将有一个连续的动画显示。游戏过程中对要移动的图片有一个闪烁的动画也属于图片动起来的范围,这是由计时器TimerFlash没300毫秒闪烁一次完成的。让图片动起来的代码不好实验,大家只要看懂下面的代码就可以了。
'*************下面代码可复制***************
Private Sub aniAImg(index As Integer, pos As Integer)
  '给一个图片加上移动动画效果
  Dim x1 As Integer, y1 As Integer, i As Integer, j As Integer, f As Integer
  Dim x2 As Integer, y2 As Integer, x3 As Integer, y3 As Integer
  x1 = Img(index).Left
  y1 = Img(index).Top
  x2 = ((pos - 1) Mod 4) * bSize                '移动目的位置列
  y2 = (Int((pos - 1) / 4)) * bSize             '移动目的位置行
  x3 = x2 - x1
  y3 = y2 - y1
  If x3 <> 0 Then
    '横向移动
    j = x3 / 10
    For i = 0 To 9
      Img(index).Left = x1 + i * j
      For f = 1 To 3000
        '延时一段时间
        DoEvents
      Next
    Next
    Exit Sub
  End If
  If y3 <> 0 Then
    '竖向移动
    j = y3 / 10
    For i = 0 To 9
      Img(index).Top = y1 + i * j
      For f = 1 To 3000
        '延时一段时间
        DoEvents
      Next
    Next
    Exit Sub
  End If
End Sub
Private Function moveAImg(index As Integer, pos As Integer) As Boolean
  '将图片从当前位置移动到指定的位置
  Dim x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer
  Dim x3 As Integer, y3 As Integer, i As Integer, b() As String
  Dim j As Integer, f As Integer
  moveAImg = False
  x1 = Img(index).Left / bSize          '图片当前列
  y1 = Img(index).Top / bSize           '图片当前行
  b = Split(Img(index).DataField, ",")  '图片的高度在b(0)中,宽度在b(1)中
  x2 = (pos - 1) Mod 4                  '移动到的列
  y2 = Int((pos - 1) / 4)               '移动到的行
  x3 = x2 - x1                          '列向上移动的方向和步数
  y3 = y2 - y1                          '行向上移动的方向和步数
  If x3 > 1 Then x3 = x3 - Val(b(1)) + 1
  If y3 > 1 Then y3 = y3 - Val(b(0)) + 1
  If x3 <> 0 And y3 <> 0 Then
    '当有斜向移动时的处理
    If Abs(x3) > 1 Or Abs(y3) > 1 Then Exit Function '斜向移动不存在单个方向上有移动两步的情况
    'If Val(b(0)) > 1 Or Val(b(1)) > 1 Then Exit Sub '大方快也不能斜向移动
    x1 = Img(index).Left / bSize + x3: y1 = Img(index).Top / bSize: i = y1 * 4 + x1 + 1
    '先假设先横移正常的处理
    If testSetImg(index, i) Then
      '能正常移动则处理竖移
      moveAImg = True
      aniAImg index, i
      putAImg index, i
      y1 = y1 + y3: i = y1 * 4 + x1 + 1
      If testSetImg(index, i) Then
        aniAImg index, i
        putAImg index, i
      End If
      Exit Function
    End If
    x1 = Img(index).Left / bSize: y1 = Img(index).Top / bSize + y3: i = y1 * 4 + x1 + 1
    '再假设先竖移正常的处理
    If testSetImg(index, i) Then
      '能正常移动则处理横移
      moveAImg = True
      aniAImg index, i
      putAImg index, i
      x1 = x1 + x3: i = y1 * 4 + x1 + 1
      If testSetImg(index, i) Then
        aniAImg index, i
        putAImg index, i
      End If
      Exit Function
    End If
    Exit Function
  End If
  If x3 <> 0 Then
    '横向移动
    f = 1
    If x3 < 0 Then f = -1
    For i = 1 To Abs(x3)
      x1 = Img(index).Left / bSize          '图片当前列
      y1 = Img(index).Top / bSize           '图片当前行
      x1 = x1 + f
      j = y1 * 4 + x1 + 1
      If Not testSetImg(index, j) Then Exit Function
      moveAImg = True
      aniAImg index, j
      putAImg index, j
    Next
    Exit Function
  End If
  If y3 <> 0 Then
    '横向移动
    f = 1
    If y3 < 0 Then f = -1
    For i = 1 To Abs(y3)
      x1 = Img(index).Left / bSize          '图片当前列
      y1 = Img(index).Top / bSize           '图片当前行
      y1 = y1 + f
      j = y1 * 4 + x1 + 1
      If Not testSetImg(index, j) Then Exit Function
      moveAImg = True
      aniAImg index, j
      putAImg index, j
    Next
    Exit Function
  End If
End Function

Private Sub TimerFlash_Timer()
  '对选择要移动的图片加闪烁效果,TimerFlash计时器代码
  If imgSel < 0 Then Exit Sub
  If Img(imgSel).Visible Then Img(imgSel).BorderStyle = Img(imgSel).BorderStyle Xor 1
End Sub
2011-04-21 19:39
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
六、    代码之旅(4)---给控件加代码,完全控制程序
  相信很多人已经迫不及待想玩游戏验证全面的代码了,这就需要给窗体里各控件增加控制用的代码,我们要在Frame1(图片移动范围框)的MouseDown事件加代码,完成鼠标左右键点击的处理,在Command1(重玩)、Command2(后退)、Command3(前进)、Command4(演示)的Click事件里加相应代码以完成相应功能,在Form(主窗口)的Load事件里完成相应初始化功能,请将原来调试时Form_Load全部删除,所有控件相应事件代码见下面。
'*************下面代码可复制***************
Private Sub Command1_Click()
  Dim i As Integer, b() As String
  '重玩的处理代码
  initSize 120
  b = Split(Card1, ",")
  For i = 0 To UBound(b)
    '排列好默认关卡图片
    putAImg Val(Left(b(i), 1)), Val(Right(b(i), 2))
  Next
End Sub

Private Sub Command2_Click()
  '后退一步的操作
  Dim a As String, i As Integer, j As Integer
  If iStepCount = 0 Then Exit Sub   '如果步数为0则不能再进行后退一步的操作
  a = Mid(iStep, (iStepCount - 1) * 5 + 1, 5)  '获取后退一步的操作数据
  If a <> "" Then
    imgSel = Val(Mid(a, 1, 1))  '第一个字符是图象编号
    i = Val(Mid(a, 2, 2))
    j = Val(Mid(a, 4, 2))
    If moveAImg(imgSel, i) Then
      '回溯成功
      If 4 * Img(imgSel).Top / bSize + Img(imgSel).Left / bSize + 1 <> i Then moveAImg imgSel, i '如果未到位就再移动一次
      iStepCount = iStepCount - 1
      Label2.Caption = Str(iStepCount)
      Command3.Enabled = True
    End If
  End If
End Sub

Private Sub Command3_Click()
  '处理向前一步的操作,前提是有历史记录
  Dim a As String, i As Integer, j As Integer
  If iStepCount * 5 >= Len(iStep) Then
    '如果操作步数记录结束在不能再前进
    If Command4.Caption = "停止" Then Command4_Click '如果处于演示状态将停止演示
    Command3.Enabled = False
    Exit Sub
  End If
  a = Mid(iStep, iStepCount * 5 + 1, 5)
  If a <> "" Then
    imgSel = Val(Mid(a, 1, 1))
    i = Val(Mid(a, 2, 2))
    j = Val(Mid(a, 4, 2))
    If moveAImg(imgSel, j) Then
      '向前一步成功
      If 4 * Img(imgSel).Top / bSize + Img(imgSel).Left / bSize + 1 <> j Then moveAImg imgSel, j '如果未到位就再移动一次
      iStepCount = iStepCount + 1
      Label2.Caption = Str(iStepCount)
    End If
  End If
  
End Sub

Private Sub Command4_Click()
  '演示的代码
  Dim a As String
  If Command4.Caption = "演示" Then
    If iStep = "" Then Exit Sub  '如果根本没有移动历史记录则不需要演示
    a = iStep                    '保存移动步数记录
    Command1_Click               '复位所有数据
    Command1.Enabled = False
    Command2.Enabled = False
    Command3.Enabled = False     '处于演示状态这些按钮不能操作
    Frame1.Enabled = False       '也不能对图片进行操作
    iStep = a                    '还原移动步数记录作为演示的数据
    Command4.Caption = "停止"
    TimerAuto.Interval = 500     '设置计时器每半秒演示一步
  Else
    Command1.Enabled = True
    Command2.Enabled = True
    Command3.Enabled = True
    Command4.Caption = "演示"
    Frame1.Enabled = True
    TimerAuto.Interval = 0       '取消演示状态,恢复所有可操作的按钮,计时器停止
  End If
End Sub

Private Sub Form_Load()
  '第一次启动窗口的代码
  Command1_Click
  Me.Top = 300
  Me.Left = 300  '设置初始窗口位置
End Sub

Private Sub Frame1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  '在图片移动框里点击鼠标的处理
  Dim i As Integer, j As Integer, b() As String, a As String
  If Button = 1 Then
    '如果按下鼠标左键的处理,主要是判断能否移动,记录移动步数及移动历史记录
    i = 4 * Int(Y / bSize) + Int(X / bSize) + 1 '根据鼠标坐标获取要到达的位置编号
    If imgSel >= 0 Then
      '如果有图片被选中,则进行移动判断,记录移动步数及移动历史记录
      j = 4 * Img(imgSel).Top / bSize + Img(imgSel).Left / bSize + 1 '获取当前图片所在位置的编号
      If moveAImg(imgSel, i) Then
        '移动成功则记录步数
        i = 4 * Img(imgSel).Top / bSize + Img(imgSel).Left / bSize + 1 '获取移动成功后图片所在位置的编号
        Command3.Enabled = False   '不允许前进操作,因为正常移动不会有未来的数据
        a = Trim(imgSel)           '图片编号
        If j < 10 Then
          a = a & "0" & Trim(j)
        Else
          a = a & Trim(j)
        End If                     '移动开始位置编号
        If i < 10 Then
          a = a & "0" & Trim(i)
        Else
          a = a & Trim(i)
        End If                     '移动目标位置编号
        '及移动历史记录的格式为:1位图片编号+2位开始位置编号+2位目标位置编号
        If Len(iStep) > iStepCount * 5 Then
          If iStepCount > 0 Then
            iStep = Left(iStep, iStepCount * 5)
          Else
            iStep = ""
          End If
        End If
        iStep = iStep & a
        iStepCount = iStepCount + 1
        Label2.Caption = Str(iStepCount)
        If 4 * Img(imgSel).Top / bSize + Img(imgSel).Left / bSize = 13 And imgSel = 4 Then
          MsgBox "恭喜你,曹操成功从华容道逃跑!"
          imgSel = -1
          Frame1.Enabled = False
        End If
      End If
    End If
  End If
  If Button = 2 Then
    If imgSel >= 0 Then Img(imgSel).BorderStyle = 1
    imgSel = -1
  End If
End Sub

Private Sub Img_Click(index As Integer)
  '在图片上点击鼠标的处理
  If imgSel >= 0 Then Img(imgSel).BorderStyle = 1
  imgSel = index
End Sub

Private Sub TimerAuto_Timer()
  '自动演示计时器代码,它调用的是向前一步的代码
  Command3_Click
End Sub
2011-04-21 20:04
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
七、    给个总结
  这个游戏的代码总算完成了,如果真心对VB编程感兴趣的朋友通过前面几节的认真研读,反复调试,应该可以正确编译并玩这个游戏的,最后我还要给感兴趣的朋友出个作业,我这次提供的压缩包里有完成所有功能的华容道游戏程序,还有一个“华容道标准步数.txt”文件里是我玩通关的字符串数据,共89步,我希望能有人把这个字符串数据放到程序中,复原我玩通关的过程,给个小提示,想办法把字符串数据放到Command4_Click中,只要方法对路即可。
  VB是一个好学好用的面向对象的程序设计语言,我这个游戏仅仅只在程序设计方法技巧上侧重,并没有涉及到VB的精髓,比如我这里并没使用API,初学者也没有理解什么是对象,不知道在什么情况下使用类,也不知道为什么要继承等等,作为VB的初学者,首先要有学编程的强烈兴趣,其次要能静下心来学习、看书,有目的地多写代码学编程的效果最好,如果心浮气躁是不能学好编程的。现在编程界普遍有一种看不起写VB程序的人,认为技术含量不高,作为一个老VB应用人,我的感受是:VB的确入门快,门槛低,但要真的学好用好也是要下一番功夫的,用好了一样能写大型的应用程序。当然,VB也有其局限,如解释执行速度慢,不是完全标准的面向对象,一旦上了VB的轨道后转其他语言相对困难,需要彻底忘掉VB才行,因此我建议初学者直接学.Net,那里将各种语言融合的比较好(和VB也有根本性的区别)。
  好了,就总结到这里,祝各位编程愉快!感谢斑竹Artless将此贴置顶!
  
华容道.rar (301.41 KB)



[ 本帖最后由 lowxiong 于 2011-4-21 22:19 编辑 ]
2011-04-21 21:34
YFur
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2011-4-16
收藏
得分:0 
很有兴趣
2011-04-24 10:18
七彩阳光
Rank: 1
等 级:新手上路
帖 子:23
专家分:4
注 册:2011-4-10
收藏
得分:0 
我也来加油学习!
2011-04-24 14:51
快速回复:兴趣是这样培养的---从一个游戏开始
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019756 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved