首页 C#开发俄罗斯方块小游戏

C#开发俄罗斯方块小游戏

举报
开通vip

C#开发俄罗斯方块小游戏三天教你做俄罗斯方块序言小花朵2010—07—12大学学C#的时候做了一个俄罗斯方块,发现挺多新手都想牛刀小试一把,我就重写了一遍,并写了这份文档教程,如果你理解快的话,三天就能做出来你的俄罗斯方块了。先看一下我的俄罗斯方块吧,游戏规则估计不用多说了,我的俄罗斯方块的特色是有美女脱衣表演哦,每升一级,美女就脱一件衣服哦!另外,你还可以自己设定各个参数,包括游戏窗口的大小,按键,背景音乐,甚至自定义砖块样式。□回区I俄罗斯方块-小花朵开始暂停选顶关于SCOREI。。LEVEL1□区193備罗斯方块-小花朵SCOREI...

C#开发俄罗斯方块小游戏
三天教你做俄罗斯方块序言小花朵2010—07—12大学学C#的时候做了一个俄罗斯方块,发现挺多新手都想牛刀小试一把,我就重写了一遍,并写了这份文档教程,如果你理解快的话,三天就能做出来你的俄罗斯方块了。先看一下我的俄罗斯方块吧,游戏规则估计不用多说了,我的俄罗斯方块的特色是有美女脱衣 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 演哦,每升一级,美女就脱一件衣服哦!另外,你还可以自己设定各个参数,包括游戏窗口的大小,按键,背景音乐,甚至自定义砖块样式。□回区I俄罗斯方块-小花朵开始暂停选顶关于SCOREI。。LEVEL1□区193備罗斯方块-小花朵SCOREI100ILEVEL|I|开始暂停选项关于参数配置|砖块样式控制0启用游戏音效环境回播迪背豈音乐音乐音量20C下一局游戏生效?默认傑存取消第一部分:基础知识了解认识GDI+GDI+的技术是建立在GDI上的。GDI+提供了一个抽象层,隐藏了不同视频卡之间的区别,这样就可以调用windowsAIP函数完成指定的任务了GDI+由.NET基类集组成,这些基类可用于在屏幕上完成定制绘图,能把合适的指令发送到图形设备的驱动程序上,确保在监视器屏幕上显示正确的输出,这里的输出包括打印到硬拷贝中。表1-1列出了GDI+基类的主要命名空间表1-1命名空间说明System.Drawing包含与一类绘图功能有关的大多数累、结构、枚举、委托System.Drawing.Drawing2D为大多数高级2D和矢量绘图操作提供了支持,包括消除锯齿、几何转换和图形路径System.Drawing.Imaging帮助处理图像(位图、Gif文件等)的各种类System.Drawing.Printing把打印机或打印预览窗口作为输出设备时使用的类System.Drawing.Design一些预定义的对话框、属性表和其他用户界面元素,与在设计期间扩展用户界面相关System.Drawing.Text与字体和字体系列执行高级操作的类在GDI+中,设备环境(DC)包装在.NET基类System.Drawing.Graphics中。大多数绘图工作都是调用Graphics的实例来完成的。实际上,因为Graphics类负责处理大多数绘图操作,所以GDI+中很少有操作不涉及到Graphics实例。理解如何处理这个对象是理解如何使用GDI+在现实设备上绘图的关键。绘制图形F面用一个小示例来说明如何在应用程序的窗口中绘图(文章所有的示例都在VisualStudio2005中NevProjectI3区fProjecItee:TemplateE:s|S]建立为C#的Windows应用程序)。启动VS2005,创建一个windows应用程序的项目,语言是C#,名字为Tetris(俄罗斯方块),然后切换到代码视图,在构造函数的最下面追加如下代码:VisnalStudioinstailedteaplatesWinlowe[j]ErTi:=LiBtDM亡屯DatitiaEeSt;±rt已广KitsWeb0-0therL:iTLgniagee(j)-OtherFrujectTypes[C°Wind口円三Appl1cat1•tn^[Windows'C叮lit.rolLiBr:ii_yj?]CrystaiReportsApplicationASF.BETWebApplicationjerf]ClaseLibr:it-yConsoleAppli>2:±tion亍£芒1J已eAppli■:ation幺ASF.HETWebServiceApplica..晶5总炷fchUrilirLt!T总mpl江ta弓...Aprojecttorcreating:=hlapplicationwithaWirnlowsTiser;匸止erfaceLocation:Browee...Solutiun:OKC:=ltlC6LFOX~b1.CS*FijTFTl1.CS[IleE1尹]宋■^Tetris.Formli^Forml0l-l;『3i4=:5=:6=.;7=:R:::y=rn:l:_i'.--,:jo!T4i:Ln6.7=:A=:■y::,0=:li:,2i:_.-i=「,4=.111A1X----1A----■1X1X-----------■-■"1」^'”4_■/」_■!.■■」BsingbysueingSyst.Coilectiuns.(THner1c:uzingSystem.CompuiLentMode1;uingSystem.Data;iieirigEyst屯rn.Drm#1n邑;uzingSystem.Text;Lueinp;System.Wirulci'A's.Forme;ErL;iui&s卫呂i二已TetrizBpublicpartialclizsForml:Fcn-m[puLLicFi:«riTilIJ[I口iti:□i工已C・jrriFu口已口t(j:(jr:iphicsg=this.Crs:.teGi-宜phics门;i'j'^X®.Griphi三对隸Penbl-uePen=newPen(Color.Bluej3);//定义-亍田笔鼻颜色为Blue>宽度为3g.DrawRectazigj.e(blueP&n_,U,0,50,50);//IHJ矩宠FenreiiF'en=newFentCulur.Red,£〕;/丿定里一TlfiJ笙丿臥色対红里丄宽,度対Eg.DrawEllipseiredPstl,U,50,SO,60);//I阳itife圆运行程序,我们期待的结果是在窗体上出现一个蓝色的矩形和一个红色的椭圆,但是实际运行结果呢?什么都没有显示,这是什么原因呢?原因就是在构造函数里执行画图代码的时候,窗口还没有显示出来,也就是说,还没有可以提供绘图的地方,所以,我们要看到期待中的蓝色矩形和红色椭圆,就必须在窗口显示出来以后再执行才能看到效果。知道了原因我们也就知道解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,回到设计视图,添加Form_Shown事件,通过下面的提示我们知道这个事件发生在窗口第一次显示的时候。然后我们把代码移动到Form_Shown事件中,再次运行一下程序,接下了就是见证奇迹的时刻了。ForMl期待中的蓝色矩形和红色椭圆如期出现了,矩形的坐标(0,0),大小(50,50)。椭圆的坐标(0,50),大小(80,50)。需要提醒一下的是如果是椭圆,则是外接矩形的坐标。这里坐标(x,y)表示从窗口的客户区域左上角开始向右的x个像素,向下y个像素——这些是现实出来的图形的左上角的坐标。外面注意到椭圆的顶部和矩形的下边有轻度的重叠,这与代码中给出的坐标有点不同,这是因为windows在重叠的区域放置了巨星和椭圆的线条。在默认情况下‘windows视图把图形边框所在的线条放到中心位置一一但这并不是总能做到的,因为线条是以像素为单位来绘制的,但每个图形的边框理论上位于两个像素之间。结果1个像素宽的线条就会正好位于图形顶边和左边的立面,而在右边和底边的外面。这样,从严格意义上讲,相邻的边框就会有1个像素的重叠。由于我们制定的线条宽度比较大,因此重叠区域也就比较大了。一般来说,可以设定Pen.Alignment属性来改变默认的操作方式,但这里使用默认的操作就足够了。接下了我们会发现一个问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 ,如果把这个窗口的绘图部分用别的窗体遮住,或者移动到屏幕的外边或者最小化,再恢复它,会发现绘制好的图形就不见了或者部分不见了。@For»l这是怎么回事?这个就要从windows处理屏幕数据的方式来说起了。如果窗口的一部分被隐藏了,windows通常会立刻删除与其中显示的内容相关的所有信息。这是必须的,否则存储屏幕数据的内存量就会是个天文数字。按照1024x768像素,24位彩色模式,屏幕上的每个点(像素)就会占据3个字节(byte),整个屏幕需要2.25MB的显存来存储这些数据。下面考虑一种最糟糕的情况:屏幕上有20个窗口,都是最大化状态‘windows就需要45MB的显存来存储,如果是32位的彩色模式,或者分辨率更大点,则消耗更多的显存,很显然,windows不能这样管理用户界面。在窗口的某一部分消失时,那些像素也就丢失了。因为windows释放了保存这些像素的显存。但要注意,窗口的一部分被隐藏了,当它检测到窗口不再被隐藏时,就请求拥有该窗口的应用程序重新绘制该部分的内容。这个规则有一些例外——窗口的一部分被挡住的时间比较短(如,菜单的拉出,临时挡住了下面的窗口)。但一般情况下,如果窗口的一部分被挡住,应用程序就需要在以后重新绘制那部分。换句话说,windows只需要花费一个屏幕的显存就可以处理N多个窗口同时打开的情况,这是我的理解。这就可以解释我们的程序为什么出问题了。我们的代码只是在第一次显示的时候才执行,并且只执行一次,不能在以后需要的时候自动重新绘制图形。备注:windows的标准控件非常专业,能够在windows需要的时候自动重新绘制他们自己。所以这就是在使用时不需要担心实际绘图过程的原因之一。使用OnPaint()绘制图形上面的解释可以让你觉得挺复杂的,但实际上并非如此,要让应用程序在需要的时候绘制自身是非常简单的。windows会利用Paint事件通知应用程序完成一些重新绘制的请求。有趣的是,Form类已经执行了这个事件的处理,因此不需要再添加处理代码了。我们添加OnPaint()事件,根据注释,我们知道这个事件会在控件需要重新绘制的时候发生。然后我们把代码再移动到这个事件里。Properties咗字Tetris.FormlV酉®Farm1_F1HusingSystem;2345678usingusingusingUEingiisingusingSystmrTi.Collec七匚口巩三.Generic;Sys+em.ComporLerLtModel;Systern.Ha+a;System.Hrawing;System.Text;System.WindowE.Furme;BrL:=uTieEp:=LceTmtrie;?ir12\(甜14:15!假-侃18右19i20?-21\曲电23:窗25?publicpartialclass,Torml:Form{publicForml():{”InitializeComponent(:);privatevoidForm1_5hown(dbjectsenderJEventArgseJ26:21128=囲30iprivatevoidForm1_Faint(^bjectsenderJ?aintEvent^rgser][_Graph!"g=e.GraphicE;^/^取Graphics对象FenblueFen=newPen(Color.Bluej3)://定义一亍凹笔』颜色为Eluej宽度为3g.DrawRectangle(bluePen,0』0,50」50);//1O矩我PenredPen.=newPen(Color.Red,2);//定爻一■画笔』颜色为红丝.宽度为2g.DrawEllipse(redFen,0,50,80,60);//画楠圆31}注意,我们修改了获取Graphics的方式,PaintEventArgs里包含一个Graphics实例,所以我们就不需要再调用CreateGraphics()来创建了。运行一下看看结果,发现bug消失了,我们已经成功的实现是在窗口上绘制我们需要的图形了,有了这些基础,我们就可以正式开工了。备注:这一部分主要摘抄自《C#高级编程(第四版),第25章第一节》第二部分:详细设计实现原理了解了基础知识以后我们就可以思考游戏的实现了,其实这个游戏实现的原理非常简单,就是不断的在窗口上画砖块,清砖块。注意这里的清砖块其实就是用背景颜色把某个区域给填充而已,本质还是绘制。具体的设计思路如下:通过timer定时执行某个操作来改变活动砖块的坐标,并更新窗口的绘图;通过键盘事件改变活动砖块的坐标以及形状,并更新窗口的绘图;每次更新都要检测是否有填满的行,或者是否游戏结束等等;针对消除的行数更新游戏得分,等级等信息抽象建模了解了基础知识以后就可以动手设计我们的俄罗斯方块的现实了,根据面向对象的设计思想,我们第一时间想到的就是抽象建模,提取的最明显的类,模块。既然如此我们就开始吧。我们知道游戏的规则是把一个一个不规则的砖块尽可能的填满到槽里,我们就从这些不规则的砖块当然,将来如果我们游戏设计的好,可以自己定义很多样式。到这里,我们就已经提取出了一个砖块的类了,我们新建一个类,类名为Brick。接下来,由于如何才能控制产生这些砖块呢?首先要知道总共有多少种砖块信息(样式,颜色),基于这个需要,我们再抽象出一个砖块模板类,用于描述一个砖块的样式,颜色等信息,这类就叫做BrickTemplate吧。然后为了能够统一管理这些BrickTemplate信息,我们需要设计一个类,用来维护这些砖块模板,以方便我们将来随时增加或者获取某个砖块模板,我们就定义一个TemplateArray类吧。然后呢,还差一个用来产生砖块的工厂,所以再定义一个BrickFactory类,用于生产砖块。到这里,我们对砖块的处理 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 已基本清晰了,规整一下如表2-1下:表2-1类说明BrickTemplate砖块的信息描述类,相当于一个模具,用来制作BrickTemplateArray管理砖块信息的管理类,用于维护BrickTemplateBrickFactory用于根据BrickTemplate产生一个实际的BrickBrick砖块实体类,用于描述一个实际砖块最后,我们还需要设计一个游戏画布类,负责实现游戏的展示以及逻辑处理。这个类是整个游戏的核心,就起名叫做GamePalette。至此,整个类级别的设计就基本结束,还有需要的等到时候用时再实现,方便期间,我们把这些逻辑模块放到一个文件夹中,解决方案的物理结构如下SolutionExplarer一TetrisSolutic-nEl-畧'Tetris'1.1pro1edJPr0perilesReferSTlCPE■Brick.ErickF=ictcry.■:BrickTAmplats、w'j;iJTi&F:ilette.TemplatpAjtay.c5Re5uiircesForml.c-Fcirmrilain.czFroei■:am.ce逻辑实现接下了我们逐步讲解各个类的具体实现,先从Brick类入手,上面一节我们说过了,这个类是一个具体的砖块类,这个类应具有以下属性和方法。这里详细介绍一下我们的设计思路,我们以一个小砖块元素为单位,每个砖块有5x5=25个坐标,其中只有一部分是有数据的,也就是有效的,这些有效的坐标也就形成了砖块的样式。比如,下图这个砖块样式的坐标数组就应该为{(1,2),(1,3),(2,2),(2,3)}。但是这个砖块有多大呢,由于我们是以一个小砖块元素为单位,所以,每个小砖块元素的坐标点对应为画j布上一个矩形区域|-=-ReptPi:-:-^],也就是说每个坐标点的是-(0.0)W)31!(3.2)(2,3)□个RectPix大小的块。(-2,-2)rI—ReciFIr-刊y)再考虑到砖块是活动的,所以砖块的实际坐标得加上在画布上的偏移,也就是说某个点的坐标(x,在画布上的实际坐标为(X+x,Y+y)。但是这样计算起来比较麻烦,所以我们采用坐标系平移的方法,把坐标中心放置在砖块的中心,即X轴向上,y轴向左偏移2个单位,这样就变成了上图所示,这样做的目的是为了方便计算。10=11112i1求1垂15=1闻17;18^&20k]丽述3J32!3东34135)46!4筒48e输5U52^詞57^60^1胆BBei67i冋69:|74!仮76iTil78h逼8甜S4i85^-sebi96^979S9900101112131眞申阿34^g希36^加-3Shl詐-接下来,我们开始具体讲解每个函数的实现:卩//〈unimary〉...|classBrick{privateFointE]m_FointE:砖块笙标数姐privateintm_X;疗砖块中业点在主歴布上的X坐标privateintm_Y:"砖块中业点在主画布上的Y坐标privateColorm_Color;//砖块颜色privateColorm_BgColor://背冒:颤色privateintm_Black5ies://单元椁像素privateSolidBrnahm_Brush;//单点放犬成矩腿privateEectangleFointTcRect(Foint:p)///Ciummary)'///构造砖块//////5^按样式祐扭背胃:<7li:ii-:dJTi'>i,ii,1/puLllcBr1cl;(Pu1匸止[]sa,Cc«lorculi:«ib,Cu1crbgColor,intsireE]E]///Ksiurimarv^飙砖换样式坐标///<7siiiTiiTiarp》///::'p:辽ame二zituIe临"p辽wi》//.i*1///砖块中壮点在主画布上的3[坐标4snuTiiTiary.>puhlicint"___|/打i.Eijinmary\>///砖块中心点在主画布上的T坐标///<:/S^JITlITl:辽putlici匸止』...|///iifTinnary》///砖块颜色//////顺时针旋转如度//./Q£Tunfnary》publlcvuidDeaziLRutat@0///<5iiiTirri&i'y'>///画砖块到画布//./Qsnunrnary^///fparoinitairie=gji,v>publlcvuidFaint(Graphic5匸p~J[.J///<5iunm:irv'>///撩除画布上的砖块!--.i,1Enjmrnary.:=-xpai"3irinaiTih'gp"K/p3r:am》publicvoiAErase(ij-r:±pkice「////7/构造函数293031i33i34=35]36b3V:///W块背冒:puLlicvoidDeasilRotate()唯一需要说明一下的是初始偏移我们设定为(2,2),这样就可以完整显示整个砖块了顺时针旋转inttenp;fortinti=0;i'、.m_Foints.Length;计十){temp二m_Foints[i].X:m_FoiiitsLi].X=-m_FciiitzLi].Y;m_Poi.lLtw[i].Y=temp;画砖块到画布lilt11N1皿114;-115^11/117|118j1谊i加12d123i124;IE引IE哄1271128^IE/130^1311-1371/?/Gummary》///画砖按到画布///summary/'///publicvuidF:ii.ntfGrajihicsgp〕toreac?L(Fo1tl七pinm_F口1ntz.Jlock(gp)FillRectangleGn—Brush』F^intTQ&ect(p));catchfExccpticm曲lConEole.Wri(ex);这个函数很好理解,把每个点放大为一个矩形区域,然后以砖块颜色填充这个区域。这个函数需要注意的地方是我们在使用Graphics对象的时候要先lock,这样防止同一时间其他地方也在使用这个对象,从而引发异常。•擦除画布上的砖块擦際画布上的砖块■C/eUJTiITi泄¥〉Cpamname=gj"'X/jiaram》近I38i划40iG44i石4Si托铤i53^5&\-////////////putlicvsiiErasel:Graphicegp、nsi口gfSuliifEirushzli二口亡代Suliilliruzh(m_BgCmlor))Eoreach(Fuint卫in.m_Foints){Lwk(.gj'.-ltrygp.JillRictsit^Ls(sb?FaintT&RsitCp〕〕:ca.tchCExceptionsk)Console.WriteLine(es);}1LJ192021空232425262Y2S可见,其实擦除就是用背景色把砖块颜色覆盖而已,本质上和上面画砖块是一样的。»点放大为区域/V单点敢大成矩形priva.teRectaitglePo1ntToReci(Po1nt丁〕Rer=newRectaiigle((m_X+p.K)1+P.Y)m_BlockSizeretui-nr;m_ElQck5ize■+1//krn_BlockSire41_//y2.,//width2)://heIght这个函数的功能前面介绍过了,就不多说了,这里的width和height要-2是为了留出中间的间隔缝隙为画网格保留的。至此,砖块类的基本功能已经实现了,我们现在可以测试一下这个砖块类是否能够正确运行,我们回到Form1的设计视图,修改如下:9For*l注意,这里我们不在Form上画,而是在PictureBox上画,其实只要有Paint功能的标准控件都可以来画,我们就选择picturebox控件,使用这个控件的好处还有很多,因为这个控件本事就是为显示图形图像设计的,所以将来如果需要可以提供更多的操作,比如我们将来想把背景换成一个图片之类的,用picturebox效率比较咼,不会闪烁。实现代码如下所示:11泊121314151617181910Z1Z22324publicp:=Lt_tialclassForml:FormBrickm_Brick=null;//砖块InitializeCumpcment(..'I;Foint[]points二newFoin+[]{newFoirL+(jj,~1tlewFijirLt(1.._1tlewFoin+(0.,0).,tlewFuirLt(0.,1)};m_Brick二newBrick(.pui巩te,Culor.Fuchsia,Culor.Black,20.);pri1/注tevoidpictureBox1_Faint(.objmeteender,Fiin+EventAi_gseJGraphicsg=e.Graphics;m_Brick.Faint[巨;l:privatevoidbuttonl_C1ick(objectsender,30131;迹-34H35!痛37138!-河40:R亦42[览4奉-48]餌50|-51!52;-m_Brick.Deasi1Rut;mtEl.):pictureBux1.Fiefresh:"逆时针prievuid匕口七turi2_Click(ubjectm_Brick.Cunt广t;mtE〔」:pictureBux1.Fiefresh:"向下privatevoidbutton3_Click(objectni_Brick.Y++;pictureBux1.Refrpsh://向右privatevoidbutton4_Click(objectni_Brick.:■:++;pictureBux1.Refrpsh:sender,sender,sender,这里需要注意一下,因为我们修改砖块的属性以后,必须通知picturebox再次重绘砖块才能看到效果,这也是我们为什么调用Refresh的原因,这个方法会导致picturebox的重绘。运行一下,会发现我们期待中的砖块已经显示出来了,同样可以测试其他功能是否能够正常工作Fonl好了,至此,我们对砖块的初步设计已成型,可以说砖块已经具有了灵魂,可以动了,接下来我们把其他配套的类来实现一下。砖块样式信息模板类是生产砖块的模具,很容易想到,它应该 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 要生产砖块的样式,以及颜色。但是如何记录砖块的样式呢?这个可以用任何你觉得可以描述的方法,我们前面说过用一个5x5大小的二维数组可以存储,然后5x5的二维数组可以演变为一个25的一维数组,比如我们可以用“0000000110001000010000000”来描述一个砖块样式,这时你可能迷惑了,这咋看出来是个砖块的样式?不要急,我们说过这个一维数组是从二维数组演变过来的,我再把它还原看看(每5个换行),就变成了下面的格式,如果我们忽略0,只看1,那么这个形状不就是我们刚才测试的那个砖块的形状么?00000000000011101000明白了这个,我们就来实现这个砖块样式信息的模板类吧,我们用String类型存储这个0101的样式编码,由于这个模板类很简单,也很容易理解,就不多讲了,直接看代码就可以看懂了。aft屈-•13Al.&i3疝-?5:⑧-31:-34i亦-37;疝-£⑴念-13:-///Csummary)'///砖块祥式信息模板类///claseBrickTemplate[pt-ivatestringm_Coh:Ff砖块样式備码privat«Cclurm_Cmlor;//蝕色J*1//1^SIJJTiITlwrg///构造砖块信息y//如'sujtiitiar打丿j,l.r'.i,1publicBrickTwmp1:±te(etriTLgco直冃Culcn-colur)ifCcmde==mill||code.Length!=£5||color==Cijlcir.EfTipty)thrownewF;-riTi日tExceptiqil("砖块样式信息错俣?");ni_Code二crule:iti_Co1町匸二cQl-jr;}打f(Eiunm:iry'>///菽取砖块样式編码_///Q1zujriniary)'卫ublic■trineCode[“Eet{reIuitlm_Cude;}}~」w艰“川镒下》///朕取砖块颤色丿Fr<7EiupniarQpublicColcrColcr{get{returnrTi_CuluE;}砖块的模具也实现了,根据前面的介绍,标准的游戏有7种砖块样式,也就是说游戏运行过程中,需要有7个这样的模具来随机调用生产砖块。那接下了就看看如何管理这些模具,也就是TemplateArray类的实现,这个也很简单,为了使程序更简单,我们只提供了添加(add)和清空(clear)功能,至于编辑和删除如果有兴趣可以自己添加。代码如下:T09o1■?」3456Td9013456Trio9・u1■?」345&T89o12345&**--------.1■a.1■■.1■->1■-■.1■M1一■.1■-.1■-1!%1■%.11■.—.I"11.—".111■.!.1■.1.1■.111■.1.1■.1.1■:-I:--;:I.///转块列表信息类///'©・0iiTiiii3ry〉claseTenpl3_teArray{^_privateAiTiyLiitm_List=newkrr:i5rLi-t0;//砖块桎植列表///'(sUJTilTi^y^///義取砖块模梗数/?/VEiunniarjrJ:-I-ublicin+Cinmt{「set{returrinList.Cijimt;}1"///€旨5川辺下》///疲取砖块複複///下标<-i,l,par:=jti》///(returns;?砖块種晨jiublicErickTemplat邑this[intimie:-:][set{returri(E!rickTernpli七屯]皿_1□丄三t[indm];}]"y//(eioitim:ary》///黍加新砖块模换///jiublicvoidAddC5trinecode.Coliirccilor){^ni_Liet.jldd{naiVErickTHrnpl:±+巨〔亡>:>df=.cc-1i:>r)〕:]~打丿^ElOITl///清空所有砖块模極///swrimary》publ1CT.-01dCle:li-I....In_List.Cl^a-i::i;然后就差生产砖块的机器了,这个机器的工作原理就是随机的从TemplateArray中获取一个砖块模具BrickTemplate,然后按照这个模具生产出相应的砖块Brick。前面我们把这个类定义为BrickFactory,那就看看这个转窑怎么实现的吧。10e1J-i冯13!1聆治1良1吗19:20!21!22122\-24却霑26!2T\28^塚-31^迄3龍341-35^36e37^話40s姫4庄昶45i///Ssummary?///砖怏产生机///NparamrL=airie="bglZulc-r“〉背昌色Vp吐旳》puBlicBri'zkFactoryfTemp1atekrr:iyinto,ColorLgCol□「」intrectPik,)m_BrickArra7-info;m_RectPix=rectTix;m_Bg|Calor=tgjColar:////////////Gummary〉随机驶取下一个砖块^ijjwiary;5t换对^publicErickGreateBrick(DRandomrd=newLanioni():intind.es=rd.NeKtCm_BrickArray.Count^://随机数stringcode=ickArray[inJsk].Cole;砖坯模换的编码〃棍据編码设定相应的有敖坐标Li5tKPoin=newListCPoinO();for(iRti=0;itcode.Length;i十十)i£(coleti]==Jf)67no9-u144-445552!加冏57L58;feintp=newFoint(i%5ji./5);//根据下标计算坐标POffset〔-乙-2);打建里坐标平穰』使坐标9,叩直在砖换中心list.Add(p);TOC\o"1-5"\h\z"生成砖块■■^^.BrickLrick—ne'tfBrickQ.ist.TgAit科l:;lBm_TiriizUlITay[inJeiz].Color〔m_E;gColor,n_RectFix;l;"随机施转g谑'"_~_~iftrd.Next(2)==1)brick.ContriRotate0;:r亡thjitlErlck;}这个类的功能很简单,就一个函数,而且也不复杂,代码注释也很详细,就不再详细解释了,自己体会一下吧。接下来我们测试一下这些配套设施能否正确的产生砖块,我们回到Forml的设计界面,添加一个button,用于随机更换砖块,并修改代码如下:11泊I16SEIS;19;21\24i空i27;希3Cdad-翅33:[]38|却汨44]publicp;±rti;ilcl5FormlBrickfictorym_FactoryBrickm_Brich=null;publicFijKfTllQ:Iorm二null;"砖块生成机/V砖块ImtialiEeCunijiorLerL七I.」;TemplateAfi-ay-匸跡TempiateArray0;array.iddC^OOOOO01000011100000000000\array.idd("0000000000111100000000000\ay.hdd("'OOOQO0Q110O11OOQOOOQQOOQO",array.XdAC'OOOOO00100011100000000000:array,kddC^OOOOO00100011000100000000ay.kdd("QQQQQOQQOOOIUOQLOOQQOOQO^array.kdd("0000000000011000110000000"匚olor.Blue);Color.(rreen):C?1or.Red);Color.DarkCyan);匚olor.OldLace^l;C?1or.Orange);匚olor.PeachPufE);m_Factory=BrickFactoryCarrUolor,現mck,E0);ra_Brick=actory.GreateBrickO:J-"pr1va七evoidpictureBck1_Paint(oBjectsender,PairttEwentArgse)"顺时针buttvril_CLi込('?bjuut45iE350]5156157h&2i&3^64[6■屋訟-誌-priv^tevoid"逆时针pri"向下priv:ate"向右priv:ate_"随机生成砖块■privatevoidbutton5_C1ick(objectEventAt~gse)voidVOIAvoidbuttijn2_C1ick(j:ibjectbuttonJ_C11匚kl.objectbutton-1!_C1iclc(objectzender..erLil^r,zerLiier,.rTi_E;yick二rTi_?:±ctory.Cr巨:ittErick("J:pictufeBoxi.JLhfresh0;EventAi'gsEventArgsEventJki-冃三EventArgse)e)l---Ie)e)代码中添加了一个BrickFactory对象,用于随机生成砖块,构造函数里清楚的介绍了如何初始化相应的数据,至于那些0101编码,估计你现在已经知道他们的含义了吧?对,就是对应那7中标准的砖块编码,至于颜色,根据自己的喜好,设定你喜欢的颜色就行了。测试结果如下游戏规则的实现如果你能够成功实现前面所介绍的功能,你已经完成50%了,而且这50%含金量很高,足够你开发一些其他的游戏了,比如简单点的贪吃蛇,或者经典的吃豆子等等小游戏了。不过我们还是要先完成我们俄罗斯方块的游戏再说,不能一知半解的就结束。我们的砖块虽然已经有了灵魂,但是还是不收束缚的灵魂,所以我们要做的就是控制它,不能让它无限制的移动,该落下的就落下,该停止的就停止。先看看这个游戏画布类应该具有哪些属性:IjHusiris|B:dnanespaceTetrisf;|硝9U1DNiii任1即14;l&i1瞄17IBId212122Z524于、2;ZT23293:i31九:H::3435363733B9classGanePalettmi¥i-egion.常屋區pr讨;reaiorLlvColoi'E]COLORS二nawColor[][Color.IVhiten匚alDr.Tonatu,Color.IhLstle,Color.Tuiquoise闪烁巍色privatereaionlyint[]TfflB_SPME=删irLt[]{TOO.6D0.550.500.450.400.3E0.3U:L25D.200};."等级对应的撞度prim址rc^lcrJyiM[]SDDZE.SPABS=newia+[]{100,SCO..ECO..IODO..lECd牛值?Tr^adr戸百ion.希ryion屈性区prBricl^o.a1oryni_Bi-i丈kFat-z-ry;//砖與产生机privateprivaprivatoprj矿乩七。privatepiriviteprivateprivst*privitcprivateprivatepriestsint.m_*idth.=15;r1/板宽mtrOtDght二Z5;//ffij^riCul&rL]币丄.:..:.r.h-:t-ay://El定砖块SJ色数姐」gCclor:背杲邑_GridCq1df;j/岡格两色i--:/X单元艳樣素二□;•"等皱二山"总分敕m_GirncOver=false是否洁腹rrCshoivGrid=false;//显示网箱m_Fause二falsem_Rafldy二Ea1e«:..■''JS:丁搽志I-1ol&rnCi?lprnintrTi_Sile:,intm_LevelintrTi_SbooLbijulbuulboolprivate1private1priv:±taprivate:private:#eitdjegiGraphiceiu:aletle;"游戏主画布Graphicem_Beictralette;Brickn_KunBrick:/?J5sbftlI^feBrickn_S^+Brick;〃下一个辟块System.Timers.Timern_rimerBrick,/^定时器■用耒更亲斤砖烧UlL[]杓造函数TH曲101102354[]曜性诃问罰涨有函数趺有画飘J54D541L]常量区COLORS:用于在消除满行砖块时闪烁该行,增加游戏可视化效果TIME_SPANS:用于设定不同等级下的砖块的下落速度SCORE_SPANS:用于消除满行砖块时计算得分变量区m_BrickFactory:很容易理解,用于在游戏过程中生产砖块m_Width,m_Height:游戏画布水平和垂直格子的数目m_CoorArray:用于记录游戏画布上各个格子的颜色m_BgColor,m_GridColor:画布背景色和网格颜色m_Size:单元格的大小m_Level,m_Score,m_GameOver,m_ShowGrid,m_Pause,m_Ready这些变量容易理解,不再多说。m_MainPalette,m_NextPalette:这两个分别对应游戏中主画面和next的画面m_TimerBrick:用于实时更新游戏状态,比如砖块下落,检查是否得分等等timer的用法不知道你熟悉不熟悉,timer对象可以定时触发一个事件,而且不影响这段时间内其他部分的代码执行(timer的用法待会再说。如果你了解多线程),这个地方也可以换成多线程的方式。接下来看看构造函数,很简单,就不多说了。旳3訥ii55^5痰笄皿陌E&67;6&斑T®和72iT屋同75iT&71\-斑-Td;虹洱ig构造函数F/j心则血迂了〉…|publicG:iJTieF:alette(intvidth,1ntheight_,THrTiplathMtayinfo,.ini呂it己」CulorTigl^olor.,(ir:iphicegjiF:ilette..'?r=iphicmgj'NextglintLevel,CulorgridColijr..b1;"?!shc'i'i-'-jrid)mj'iiith二-A-idth;m_Height二height;m_Coc-rAfr:±v=newC■:<]_c-r[w1dth,heig:ht];m_Egl3i:iluK二bglZijLijr:m_Fi1airJ';Bl已tt已二gpF:al已tt已;rTi_HeKtJ':=LLe七七已二gplI^Kt;ni_Sirt:二silt!:Level-level:i}riilColor=piT>1Co1c»r;Sh^-wGfid=sh.:iwGrid:EricWactory=tl已mBrickFactory(infligi^ulur,.zize)mmmmInitRand&mSrick0:/丿主成“化1行随机砖凄,増加游戏可1玩度i^EnirEgion再看看属性访问器,也很简单,不说了8081號838483899091自目=1ir自s=!Jr旨台IIIrN102!ffiregiorkJI性访问器///\51JITlin;3I"T/'///我取游戏是否结束标志H/<7EUiTirTiary>publictiuuLIsG:ajrieUver|^_|.r1//^.siuTimary》///菽取当前游戏等co-g)///X/Eummai"ji\>publieintLevel)..=|.rl.i,1/1^-.sujTiinary〉///家取当前分数//.i*1sijmrnary》publieintEcor4-1fferniregion接下来就是有含金量的函数了,这些函数共同形成了游戏规则以及游戏控制,先看看公有函数包含哪些36Tfe3现]372i[]39Z:339&k]402;e340血4233427;3■444勺448^3465=:3469464^1487^3sub]514^3Eisj]521H]525h]528^]53;=d-程飞gim共有函数|/丿/€旨则皿*丫》…|own(.)[F_/J住则皿工了》.…|public?■>!dDr■:'ppL-wriC4■Jpublic!bxilhlu化SFt〔〕LJp~abJ-1匚b°qJ.卅口feEigzhtl..j|.P7丿〔TUTiwary》….|pi丄blic:boolD已且t已Q|..J/丿丿〔ummary》...|public匚比上■:;■目〔〕「「fHEiuTiinary》….|iAStartQf-.]F/J(FTiihar:y>...|putilicvciidFauseC|L..|『打Jijjiiniary〉*…|pi止]-1匚PP1putilii:vijidF:白弓im〔〕;…「/打:仙血ary》…|pmlilicvolilClueel:;「fftrLiii'&gii:.rL这些函数是对外可见的,也就是通过这些接口我们来控制是玩游戏。我们着重介绍几个函数的作用MoveDown///心umnisry》///下移1个单位J//publicwuidDrupHii-i|i,口〔)[m_TimerBrick.StopI.J;/丿暂停疋时器while(WoveDowit0):〃循环调用向下移动>直到不能移动位置m_TimerBrick.StartQ;打重新启用定时器|这个函数很简单,也很容易理解,就是快速的调用MoveDown而已。DeasilRotate///Xsiimmary/'甲顺时针籬转叩度///■(/suiTiiTi!ii-y">//'/:■1tlKz.LengztlL;1++..I{"计整罐转洁的新坐标工匸止囂=ni_FjULE!ricl;.K一Ti_RiJTLE!rick.P■:///重画游戏画板///summary^///publicvoidFaintFaletteCGraphiC5gj〕{口以背寰色清底画布lock〔gp〕{d匚(jn_Eg!Col&F):}_"画网格i£C.n^EtLuwCTi-iJ.)FaintGriilLi口旦(gp〕;〃画已有砖块PaintBrlcks(gp):〃画当前
本文档为【C#开发俄罗斯方块小游戏】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: ¥21.0 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
茉莉花开
暂无简介~
格式:doc
大小:985KB
软件:Word
页数:36
分类:高中语文
上传时间:2022-07-23
浏览量:12