您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 按键精灵教程之俄罗斯方块
前言:喵~你们相信按键精灵除了能做游戏辅助脚本外,还能做一个游戏玩玩吗?这是真的吗?小猫告诉你,是真的,编程是无所不能的,只要你敢想,就能实现!!!游戏下载地址:喵~用按键精灵做的俄罗斯方块游戏~[更新至1.11.0701]技术:1.多线程2.窗口句柄工具:按键精灵8361的窗口插件mp9999ddd的多线程互斥锁插件俄罗斯方块百度感谢以上两位高人提供的插件喵。游戏背景图片:思路:要写一个游戏,必须要对游戏有一定的了解,而不是简简单单的知道怎么玩。现在小猫要写的是俄罗斯方块,那么小猫需要知道以下几个数据:“游戏的边框长短,各个方块的具体形状,每次变形后的形状,得分的算法,游戏的规则。”那怎么获得这些数据呢?对,活用百度谷歌,具体内容看上面的俄罗斯方块百科,已经写的很清楚了,游戏是10x20大小的,方块有S、Z、L、J、I、O、T这7种形状,得分的大致算法。OK,游戏的一些大致数据已经收集好了,现在要利用这些数据了。小猫刚开始的时候,是想用91的写屏插件,通过清屏和写屏两种功能完成游戏的,后来才发现,这个思路的代码和算法太复杂,于是果断放弃,转为使用361的窗口插件,通过创建一个游戏背景区域和多个方块(按钮),然后使用移动窗口和关闭窗口实现方块的移动和消除,而判断方法则是采用判断上下左右句柄得到。正文:首先,我们要创建一个游戏区域,游戏原本是边框10x20,方块1x1的,我们将其放大30倍,即变为边框300x600,方块30x30,我们还要计算好游戏区域的左上角坐标,在这里,小猫电脑分辨率是1280x800的,小猫为了游戏区域在屏幕中间,故设置游戏区域的左上角坐标为489,99。接着,大家注意找下361窗口插件中的“CreateCustomRgn创建不规则区域”功能,简单的说,这个就是放置一张图片大小的窗口,只不过他会将指定颜色挖空。在这里,我们使用上面那张300x600的背景图片,创建这个游戏区域即可。注意,停止脚本的时候,关闭这个窗口1.setGameLeftUpX=489:setGameLeftUpY=992.FKPath=Attachment:\3.BGPath=Background.bmp4.MainHwnd=Plugin.WindowEx5_01.CreateCustomRgn(0,setGameLeftUpX,setGameLeftUpY,FKPath&BGPath,FF00FF)5.6.SubOnScriptExit()7.HwndArray=Plugin.WindowEx5_01.EnumWindowA(0,0,361Du*Class3,2)8.Fori=0ToUBound(HwndArray)9.CallPlugin.WindowEx5_01.SetWindowState(HwndArray(i),0)10.Next11.EndSub复制代码第二,游戏区域创建好了,现在要创建方块了,大家看下361窗口插件中的“CreateButton创建按钮”功能,我们就用他来创建方块,并得到每个方块的句柄。所有的形状都是由4个方块组成,那么我们可以通过一个带参数的子程序来完成创建工作,先从最简单的O形方块开始。这个方块的形状是“田”字形的,即2X2,游戏刚开始的时候,这个方块应该是在游戏区域的正上方中间等待下降的。故他的左上角坐标应该是609,39,根据一个方块为30x30大小,推出其他3个方块的坐标,创建4个方块窗口,并将这4个窗口句柄分别保存起来。1.OO=609,39,639,39,609,69,639,692.CallCreate(OO)3.4.SubCreate(FKZuoBiao)5.TracePrint创建方块6.CreateZB=Split(FKZuoBiao,,)7.getFKHWnd1=getCreateFK(CreateZB(0),CreateZB(1))8.getFKHWnd2=getCreateFK(CreateZB(2),CreateZB(3))9.getFKHWnd3=getCreateFK(CreateZB(4),CreateZB(5))10.getFKHWnd4=getCreateFK(CreateZB(6),CreateZB(7))11.EndSub复制代码第三,现在游戏背景和O形方块都创建好了,我们先要让他自动落下,怎么弄呢?很简单,每隔一段时间,获取四个方块窗口的当前坐标,然后依次向下移动一次,一次是移动30个像素,对吧?OK,子程序代码如下:1.2.SubFKStatic()3.getFKRect1=Plugin.WindowEx5_01.GetWindowInfo(getFKHWnd1,2)4.getFKRect2=Plugin.WindowEx5_01.GetWindowInfo(getFKHWnd2,2)5.getFKRect3=Plugin.WindowEx5_01.GetWindowInfo(getFKHWnd3,2)6.getFKRect4=Plugin.WindowEx5_01.GetWindowInfo(getFKHWnd4,2)7.EndSub8.9.SubFallFK()10.TracePrint下落11.CallFKStatic()12.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd1,getFKRect1(0),getFKRect1(1)+30)13.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd2,getFKRect2(0),getFKRect2(1)+30)14.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd3,getFKRect3(0),getFKRect3(1)+30)15.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd4,getFKRect4(0),getFKRect4(1)+30)16.EndSub复制代码第四,现在问题来了,我们发现方块不停的掉下去,不会停止在游戏区域内,怎么办?这里,我们要用到这个功能--GetPointWindow获得包含了指定点的窗口句柄--它的作用就是得到指定坐标上的窗口句柄。有什么用呢?这样想,我们只要得到四个方块下一格的句柄,如果这个句柄不是方块的句柄也不是游戏背景区域的句柄(这里大家思考下,为什么还要加上不是方块的句柄这个条件),那么我们就可以判断出这个方块已经到达了最底部了。1.2.FunctionCheckFK()//检查方块的下一格句柄3.CallFKStatic()4.getCheckHwnd1=getPointHwnd(getFKRect1(2)-15,getFKRect1(3)+15)5.getCheckHwnd2=getPointHwnd(getFKRect2(2)-15,getFKRect2(3)+15)6.getCheckHwnd3=getPointHwnd(getFKRect3(2)-15,getFKRect3(3)+15)7.getCheckHwnd4=getPointHwnd(getFKRect4(2)-15,getFKRect4(3)+15)8.IfgetCheckHwnd1getFKHwnd1andgetCheckHwnd1getFKHwnd2andgetCheckHwnd1getFKHwnd3andgetCheckHwnd1getFKHwnd4andgetCheckHwnd1MainHwndThen9.TracePrint110.CheckFK=false11.ElseIfgetCheckHwnd2getFKHwnd1andgetCheckHwnd2getFKHwnd2andgetCheckHwnd2getFKHwnd3andgetCheckHwnd2getFKHwnd4andgetCheckHwnd2MainHwndThen12.TracePrint213.CheckFK=false14.ElseIfgetCheckHwnd3getFKHwnd1andgetCheckHwnd3getFKHwnd2andgetCheckHwnd3getFKHwnd3andgetCheckHwnd3getFKHwnd4andgetCheckHwnd3MainHwndThen15.TracePrint316.CheckFK=false17.ElseIfgetCheckHwnd4getFKHwnd1andgetCheckHwnd4getFKHwnd2andgetCheckHwnd4getFKHwnd3andgetCheckHwnd4getFKHwnd4andgetCheckHwnd4MainHwndThen18.TracePrint419.CheckFK=false20.Else21.CheckFK=true22.EndIf23.EndFunction复制代码第五,下落问题解决了,这次我们要对方块进行左右移动,既要让方块保持下落,又要让方块左右移动,怎么办?这里就需要用到多线程了,另外,由于每个形状是由4个方块组成的,则就意味着,每次移动都要移动4个方块,问题来了,如果下落的同时,又左移了,会不会造成混乱呢?比如方块错位之类的。这里有一个知识点,多线程互斥锁,打个比方,有两个线程,一个线程对变量a进行自增1运算,一个线程对同一个变量a进行自减1运算,那么a的值变化如何?肯定是很混乱的,一会儿加,一会儿减的,这个时候,如果我想让他自增1运算10次后,再自减1,怎么办呢?造成混乱的原因就是,两个线程抢着用变量a,如果当一个线程在使用a的时候,另外一个线程无法使用a,那么这问题不就解决了?这就是线程互斥锁。刚开始的时候,小猫是用环境变量来实现的,后来发现按键精灵的多线程不怎么稳定,哪怕使用了环境变量,还是容易造成方块混乱,于是这里就要用到了mp9999ddd的多线程互斥锁插件这个插件。1.SubMoveFK()//移动方块2.Do3.MoveKey=04.IfSpeedUp=0orSpeedUp=1Then5.TracePrintSpeedUp&SpeedUp6.MoveKey=WaitKey()7.CallPlugin.jcqm.jMutexLock(Lock)8.TracePrint移动9.SelectCaseMoveKey10.Case3711.getCheckFK=CheckFK()12.IfgetCheckFKThen13.CallMoveLeft()14.EndIf15.Case3916.getCheckFK=CheckFK()17.IfgetCheckFKThen18.CallMoveRight()19.EndIf20.Case3821.CallChange()22.EndSelect23.CallPlugin.jcqm.jMutexUnLock(Lock)24.Delay5025.EndIf26.Loop27.EndSub28.29.SubMoveLeft()//左移30.CallFKStatic()31.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd1,getFKRect1(0)-30,getFKRect1(1))32.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd2,getFKRect2(0)-30,getFKRect2(1))33.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd3,getFKRect3(0)-30,getFKRect3(1))34.CallPlugin.WindowEx5_01.MoveWindow(getFKHWnd4,getFKRect4(0)-30,getFKRect4(1))35
本文标题:按键精灵教程之俄罗斯方块
链接地址:https://www.777doc.com/doc-2450956 .html