1、0项目实训报告书学生姓名 课程名称 C课程设计 题 目 俄罗斯方块 专业班级 指导教师 完成日期 1目录一概述21.1 背景21.2 开发与运行环境3二需求分析3三系统设计4四详细设计54.1 界面设计54.2 代码设计7五结束语.25六参考文献.2621. 概述1.1 背景俄罗斯方块由莫斯科科学学院程序员 Alexei Pajitnov 所设计。该游戏最初是作为自我消遣的电脑游戏而被制作出来的。此后,由于政治和经济等多方面的原因,该游戏曾经被多家公司代理过。经过多轮诉讼的争夺后,该游戏的代理权最终还是被任天堂获得。俄罗斯方块对于任天堂来说意义重大,因为将它与 GB 搭配在一起后,产生了令人意
2、想不到的效果,获得了巨大的成功。而对于中国玩家来说,俄罗斯方块可以说是第一次让国人认识到游戏是一种老少皆宜的娱乐方式,从某种程度上扭转了国人的“游戏是小孩子的东西“ 或“游戏是毒害儿童的元凶“ 等错误观念。一个最初的版本是 Spectrum Holobyte 为 IBM 兼容机开发的游戏。该游戏是一款休闲智力型,与通常的此类游戏相比,这款游戏新增了在模块样式上的多彩性。还抛掉了以前那种枯燥的背景音乐,可以让自己随心所欲的背景音乐。于此同时还可以让自己开动脑筋来设计模块。还可以凭自己的喜好。可以设置画布的大小。1.2 开发与运行环境系统的运行对于运行环境的要求是: 硬件环境目前,我们所开发的系统
3、主要应用在中小规模的学校内部,因此,一般配置的计算机硬件就可以满足系统需求。考虑到学校规模的扩大和硬件价格的降低,为本系统配置在较优秀的服务器硬件上,可以充分发挥本系统的性能。 处理器:Intel Pentium 4 3.06 GX 或更高 内存:256M(推荐) 硬盘空间:40GB 显卡:SVGA 显示适配器 软件环境 操作系统:Windows 2000/XP 开发软件:Microsoft Visual Studio .NET 2003 数据库:Microsoft SQL Server 200032. 课程设计的目的和意义俄罗斯方块游戏是一个经典的小游戏,由于它简单有趣,因而得到了广泛的流行
4、,男女老幼都适合。而俄罗斯方块游戏的设计工作复杂且富有挑战性,它包含的内容多,涉及的知识广泛,与图形界面联系较大,包括界面的显示与更新、数据收集、音乐处理等,在设计的过程中,必将运用到各方面的知识,这对于 C#设计者而言,是个很好的锻炼机会。2.1 实验步骤:1) 需求分析:设计一个用户可参与,有背景音乐,可由用户控制任意暂停,可计时,可计分的俄罗斯方块游戏;2) 概要设计:一个游戏运行界面,计分面板,开始按扭,暂停按扭3) 详细设计:对整个设计进行总体分析如下:1定义 7 种砖块的类型,用两个 4*4 的二维数组来表示。 2在屏幕上用一个 10*20 表示游戏区域3上下左右的出界问题的考虑3
5、砖块的变形问题4砖块的移动(向左向右向下)问题5满一行后消掉砖块6记分问题7用开始按扭启动游戏8暂停按扭暂停游戏9界面的设定10背景音乐的加入3 系统功能设计玩游戏前先要设置参数,键盘的设置比如说:左键,右键,下4键,快速向下键。顺时针旋转,逆时针旋转。环境的设置也非常重要,比如:水平格子数,垂直格子数。格子数。前景色等,再者就是砖块的设置,砖块是自己设计的,但是系统也有默认砖块,都是最常用的模块。还可以改变模块的颜色。本系统主要设计以下几种功能:1. 方块下落、变形功能在整个俄罗斯方块游戏中,方块的设计是核心。这里设计了一个方块类:Square( ),用来生成方块以及实现块的左移、右移、向下
6、、变形、重画、同步显示、初始化新块等。2 自动升级功能当分数累积到一定大小时,系统将自动为玩家提高难度。这里设置了每消除 10 行方块,就增加一级难度。当难度增加的时候,方块会相应地改变颜色,以作为对玩家的提示。3 游戏音乐功能游戏开始音乐就自动播放,游戏暂停与结束时音乐相应消除。总控模块输入模块 处理模块 输出模块图片处理图片另存为打开文件夹添加屏幕抓图截图控制窗口5图 1 系统功能模块结构图3. 以系统功能设计分析俄罗斯方块游戏根据功能的不同,设置了如下 12 个类:Square, Command, GameArea, GameSetting, GameOver, Help, ImageP
7、anel, JieMian, MyPanel, MyTimer, PlayMidi, WinListener,每个类的描述如下:1、Square ,方块类。这个类中定义了生成方块的方法,用二维数组 int pattern,存放 7种方块的四种状态。在构造方法中以随机的形式生成方块,同时提供了以下几种方法:reset( ), leftTurn( ),leftMove( ),rightMove( ),fallDown( ),assertValid(int t,int s,int row,int col),dispBlock(int s)。分别实现方块的重画、翻转、左移、右移、下落、同步显示等功能。
8、2、Command,处理控制类。这是一个实现 ActionListener 接口的类,主要处理点击按钮事件。类中定义了三个 int 型变量:button_play,button_quit,button_pause,和一个 boolean型的变量:pause_resume,并赋值。在 GameArea 类中通过事件响应,在按钮执行方法中调用其值,使用 switch 语句,根据不同按钮不同的值,来响应不同的事件。3、GameArea,游戏界面类。 GameArea 继承了 JFrame,是俄罗斯方块的主要游戏界面。这个类定义了 GameSetting 类的 gameScr 对象和 ImagePan
9、el 类的 imagepanel 对象作为游戏区域面板和控制区域面板。在游戏区域,主要是根据相应格子的设置标志来显示相应的图形图片,这样就实现了俄罗斯方块的实时显示。4、GameSetting, 游戏画布类。这个类生成的对象将作为游戏界面的方块下落区域,画布的设置为 15 行 10 列,当中的方格边长为 30,类中还定义了一个二维数组 int scrArr 作为屏幕数组,表示每一个方格。游戏区域中每一个方格是否存在游戏方块是由该方格的值来决定的,如果该方格的值为 1,则表示该方格中存在游戏方块;如果该方格中的值为 0,则表示该方格中不存在游戏方块,因此二维数组用于记录游戏区域中每个小方格的值。
10、此外,类中还定义了画方块的方法,根据不同的难度画出不同颜色的方块。单击 Play 按钮时,系统调用 initScr( )方法,初始化屏幕,将屏幕数组清零。当满足满行删除的条件时,系统调用 deleteFullLine( )方法,进行删行加分,而且每删除十行,难度自动增加一级,方块颜色改变,并在难度显示框中相应显示。图 3-8 系统功能模块结构图65、GameOver,游戏结束弹出提示框类。当游戏结束时,系统弹出提示,包括玩家分数以及询问玩家要继续游戏还是退出。6、Help,帮助类。在游戏界面,按 F1 键,弹出提示窗口,获取帮助。7、ImagePanel,背景图片类。这个类继承了 JPanel
11、 类,用来作为游戏界面中控制区域的容器,并添加图片。8、JieMian,主界面类。这个类继承了 JPanel 类,作为游戏的第一个界面,也是难度选择界面。定义了 9 个单选按钮,当玩家未选任何难度就按 Enter 时,系统会弹出一个提示框,提示玩家先选难度再进入。9、MyPanel,重写 MyPanel 类,使 Panel 的四周留空间。10、MyTimer,定时线程类。类中定义了一个 run()方法,用 sleep()函数实现方块下落的快慢,即调节难度。11、PlayMidi,添加音乐类。在游戏过程中添加背景音乐。12、WinListener ,关闭窗口类。4. 4.1 界面设计1、图片浏览
12、器主界面如下图 2:图 2. 软件主界面图72、参数设置如下图 3:图 3 设置图3、图片调整界如图 4:4.2 代码设计1.输入模块:1.1 从文件夹中打开需要浏览的图片:openImage()private void openImage()/ 如果当前正显示幻灯片,先关闭定时器2this.timer1.Enabled = false;if(this.openFileDialog1.ShowDialog() = DialogResult.OK)8 if(this.pictureBox1 .Image !=null)this.pictureBox1 .Image.Dispose ();pict
13、ureBox1.Image = Image.FromFile(this.openFileDialog1.FileName);/设置全局变量entireFilePath,用于保存文件名(在上一张、下一张、幻灯片显示时记录当前/图片的位置)this.entireFilePath = this.openFileDialog1.FileName.ToString();this.statusBarPanel2.Text = “图片大小:“+this.pictureBox1.Image.Size.Width.ToString();this.statusBarPanel2.Text += “*“ + thi
14、s.pictureBox1.Image.Size.Height.ToString();/得到图片所在文件夹的路径string filePath = “;filePath = openFileDialog1.FileName.Substring(0,openFileDialog1.FileName.LastIndexOf(“);/打开目录,并将目录中所有.jpg.bmp.gif类型的图片放入FileInDir集合System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(filePath);System.IO.FileInfo fileIn
15、fo = dir.GetFiles();FileInDir.Clear();foreach(FileInfo fi in fileInfo)if(fi.Extension = “.JPG“ | fi.Extension = “.jpg“ | fi.Extension = “.jpeg“ | fi.Extension = “.tif“ | fi.Extension = “.png“ | fi.Extension = “.bmp“ | fi.Extension = “.BMP“ | fi.Extension = “.gif“ | fi.Extension = “.GIF“ )FileInDir.A
16、dd(fi.FullName.ToString();/得到当前打开图片在FileInDir中的索引(index为定义的全局变量)for(index = 0;index 1)/确定图片浏览的上一张和下一张按钮的可用性this.toolBarButton7.Enabled = true;if(index = 0)/当索引值为第一章时上一张按钮不可用this.toolBarButton5.Enabled = false;this.toolBarButton6.Enabled = true;9else if(index = FileInDir.Count-1)this.toolBarButton6.E
17、nabled = false;this.toolBarButton5.Enabled = true;elsethis.toolBarButton5.Enabled = true;this.toolBarButton6.Enabled = true;this.statusBarPanel1.Text = this.openFileDialog1.FileName.ToString();/在状态栏显示浏览图片的路径FileInfo info =new FileInfo (this.openFileDialog1 .FileName .ToString ();this.statusBarPanel3
18、 .Text =“文件大小:“+ info.Length.ToString () +“B“;/显示图片文件的大小从文件夹中拖进图片框:这里用到两个事件:_DragDrop 和_DragEnter:private void pictureBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)/图片拖进图片框if(e.Data.GetDataPresent(DataFormats.FileDrop) e.Effect = DragDropEffects.Link; else e.Effect = DragDropEff
19、ects.None;private void pictureBox1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) / 拖进后释放鼠标if (e.Data.GetDataPresent(DataFormats.FileDrop) string files = (string)e.Data.GetData(DataFormats.FileDrop); for ( int i = 0; i255)r=255;if(r255)g=255;if(g255)b=255;if(bg?r:g;Result=Resultb?Resu
20、lt:b;break;case 2:/加权平均值法Result=(int)(0.7*r)+(int)(0.2*g)+(int)(0.1*b);break;bitmap.SetPixel(x,y,Color.FromArgb(Result,Result,Result); this.pictureBox1.Image=bitmap;private void rhView()/以柔化方式显示图像int Height=this.pictureBox1.Image.Height;int Width=this.pictureBox1.Image.Width;Bitmap bitmap=new Bitmap
21、(Width,Height);Bitmap MyBitmap=(Bitmap)this.pictureBox1.Image;Color pixel;/高斯模板int Gauss=1,2,1,2,4,2,1,2,1; for(int x=1;x255?255:r;r=r255?255:g;g=g255?255:b;b=b=Width)dx=Width-1;if(dy=Height)dy=Height-1;pixel=MyBitmap.GetPixel(dx,dy);bitmap.SetPixel(x,y,pixel);this.pictureBox1.Image=bitmap;private v
22、oid RhView()24/以锐化方式显示图像int Height=this.pictureBox1.Image.Height;int Width=this.pictureBox1.Image.Width;Bitmap bitmap=new Bitmap(Width,Height);Bitmap MyBitmap=(Bitmap)this.pictureBox1.Image;Color pixel;/拉普拉斯模板int Laplacian=-1,-1,-1,-1,9,-1,-1,-1,-1; for(int x=1;x255?255:r;r=r255?255:g;g=g255?255:b;b
23、=b=iPictureBoxHeight /图片全图片框显示/如果图片长和高都大于图片框长和高else if(iImageWidth=iPictureBoxHeight)this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Normal;/图片正常显示elsethis.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;/图片自动大小显示 2.6 对图片进行明暗度,对比度,色相,饱和度的调整,此功能还没有实现。5 结束语用
24、了我几周的时间,终于把俄罗斯方块游戏完成了。这段时间里,我搜集资料、查看书籍,本来以为在大专时学过,很简单,但是实际操作起来非常困难,在编写过程中遇到许多问题。在系统分析阶段,针对俄罗斯方块游戏,初步地定下了要实现的功能,并将整个游戏分成若干个部分。在程序编写阶段,出现了不少技术上的问题。出于基础不扎实这方面的原因,在程序设计的时候遇到了不少问题,甚至被布局管理器的简单问题弄得焦头烂额。但在一次次的错误运行中,我们对面向对象程序设计的概念理解得更加深刻,也因此重新燃起斗志。可是在如方块预览方面,我们始终不能完成这一功能,这也是缺陷的所在。鉴于水平能力问题,对于俄罗斯方块的核心程序我们并未能形成
25、一个有机的概念,对于其核心算法也未能准确掌握。诸如某些库函数已提供的方法,我们也不太了解。出于这样的原因,我们上网查找了大量资料,借鉴了前人程序的一些方法,经过深入研究学习后,再加工提炼,在原有的基础上加入我们自26己的想法,并进行设计。在设计开发过程中,我们不但需要处理好各个类之间的集成关系和继承机制,还要处理各个类的相应的封装,并且还要协调好各个模块之间的逻辑依赖关系和数据通信关系。通过这次的课程设计,我们更深地体会到软件工程的理念,并以一个程序员应有的素质来要求自己,大致掌握了软件开发的基本过程,也感受到团队合作的重要性。俄罗斯方块游戏的设计对于每个 C#语言设计者来说,都是一个很好的提高和进阶的锻炼机会。6 参考文献1 C应用程序开发上海科学普及出版社.主编:秦斌 曾斌;2004.32 Visual C#.NET 应用编程 150 例.电子工业出版社.尹立宏.2003.83 Microfoft Visual C#.NET 2003 开发技巧大全中国水利水电出版社.杨会珍 范书义.2005.44 网上搜索的相关代码