擎墨閣文學 2008-5-1 11:56
扑克牌类游戏DIY之一:整体布局的设计 (3)
[table=98%][tr][td]扑克牌在桌面移动需有动画显示,不然会很生硬且不易分清谁出的牌。图片框的动画可用一个循环来完成,只需不断调用图片框的Move方法,便能形成动画效果。这里有两点要注意:一是窗体的ClipControls属性应设为True,否则牌移动的效果会有闪烁;二是应在循环中释放CPU控制权,让图片能够刷新,否则会看不到动感或留下黑色拖影。为了便于调整动画速度,先定义一个全局的长整形变量glnPKSpeed,动画过程如下:[/td][/tr][/table][table=98%][tr][td]Private Sub MovePK(ByVal PKID As Long, ByVal EndX As Long, ByVal EndY As Long)[/td][/tr][/table][table=98%][tr][td]Dim i As Long, StepX As Long, StepY As Long[/td][/tr][/table][table=98%][tr][td]With PK(PKID)[/td][/tr][/table][table=98%][tr][td].Visible = True[/td][/tr][/table][table=98%][tr][td]StepX = (EndX - .Left) \ glnPKSpeed '根据速度变量(越大越慢)算出每次移动的距离[/td][/tr][/table][table=98%][tr][td]StepY = (EndY - .Top) \ glnPKSpeed[/td][/tr][/table][table=98%][tr][td]For i = 1 To glnPKSpeed[/td][/tr][/table][table=98%][tr][td].Move .Left + StepX, .Top + StepY[/td][/tr][/table][table=98%][tr][td]DoEvents '释放CPU控制权,让图片能够刷新[/td][/tr][/table][table=98%][tr][td]Next[/td][/tr][/table][table=98%][tr][td].Move EndX, EndY[/td][/tr][/table][table=98%][tr][td]End With[/td][/tr][/table][table=98%][tr][td]End Sub[/td][/tr][/table][table=98%][tr][td]以上动画使用了DoEvents语句,会有可能带来副作用,在使用时请结合实际,把牌移动中可能发生的事件考虑全面。当然动画还可以通过时间控件来完成,不过就是控制上难了一点,因为每人出牌数目不同时间不定,容易发生两人同时出牌的尴尬局面。[/td][/tr][/table][table=98%][tr][td]高级一点的动画效果,还可以做得象人摸牌一样,手中的牌先空出一个恰当牌位,牌桌中央的牌象长了眼似的正好飞入这个空档。这种动画实际上用了“障掩法”:即用两个变量记住要发牌的初始坐标,将其Visable属性设为False,先加入手中牌集合;接着调用前面的LiPai过程对手中牌排序,并按新顺序定位。因要发的牌不可见,看起来是个空着的位置,这时换用两个变量记下此牌的新坐标后,依靠前面已保存的坐标将牌恢复原位,重新设其Visable属性设为True,最后调用MovePK过程将牌移向新坐标,整个动画就完成了。听起来挺复杂,可在程序中执行是很快的,绝对看不出破绽,只是这张牌“累”了点!因涉及众多过程调用,还是不举例了。[/td][/tr][/table][table=98%][tr][td]扑克并不总是正面朝上,要实现牌背牌面的变化,可另加一个图像控件Back,预先载入牌背的图片,扑克正面朝上时,根据其控件的Index属性从资源中载入正面图片,背面朝上时设其等于Back控件,为了让程序能检测一张牌的状态是正面还是背面,可在控件的Tag属性中加入一个数字作标记,如“1”代表正面,“0”代表背面。这样便可建立一个设置扑克状态的过程:[/td][/tr][/table][table=98%][tr][td]Sub ShowPK(PKID As Long,up As Boolean)[/td][/tr][/table][table=98%][tr][td]If up Then '依据up执行牌面的正反操作[/td][/tr][/table][table=98%][tr][td]With PK(PKID)[/td][/tr][/table][table=98%][tr][td].Pictrue = LoadResPicture(101 + .Index \ 2, vbResBitmap) '按Index号载入扑克正面图片[/td][/tr][/table][table=98%][tr][td].Tag = "1" '设定扑克是正面的状态标记[/td][/tr][/table][table=98%][tr][td]End With[/td][/tr][/table][table=98%][tr][td]Else[/td][/tr][/table][table=98%][tr][td]With PK(PKID)[/td][/tr][/table][table=98%][tr][td].Pictrue = Back.Picture '[/td][/tr][/table][table=98%][tr][td].Tag = "0" '设定扑克是背面的状态标记[/td][/tr][/table][table=98%][tr][td]End With[/td][/tr][/table][table=98%][tr][td]End If[/td][/tr][/table][table=98%][tr][td]End Sub[/td][/tr][/table]