C - 设计报告 - 俄罗斯方块

更新时间:2024-01-18 15:05:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

目 录

一、 成员分工 ................................................... 3 二、需求分析 ................................... 错误!未定义书签。 2.1系统概述 ................................................... 2 2.2系统运行环境 ............................................... 2 2.3功能需求描述 ............................................... 3 三、总体设计 .................................................... 3 3.1屏幕的组成 ................................................. 3 3.2形状的组成 ................................................. 4 3.3形状的统一 ................................................. 4 3.4移动与旋转的统一 ........................................... 4 四、详细设计 ................................................... 10 4.1程序流程图 ................................................ 11 4.1.1数据流图 .............................................. 11 4.1.2系统功能模块 ........................................... 11 4.1.3 系统流程图 ............................................ 11 4.2程序模块详细设计 .......................................... 12

0

4.2.1界面的设计............................................. 12 4.2.2游戏界面背景 ........................................... 13 4.2.3游戏随机选择方块模块 ................................... 13 4.2.4游戏预览功能模块 ....................................... 13 4.2.5计分功能模块 ........................................... 14 4.2.6键盘控制功能 ........................................... 4.2.7等级设置 .............................................. 五、系统测试 ................................................... 六、运行效果 ................................................... 七、总结 ....................................................... 八、参考文献..............................................19

1

15 17 18 18 18

一、成员分工

为了顺利完成此次的课程设计,也是课程设计的要求,我们由杨洋(20095422)和王昕(20095418)两人组成一个课程小组,共同努力完成本次课程设计。

杨洋负责课程设计的 部分类的定义内容、等级加速、PPT部分 初始化、背景图片、报告书部分,所做工作占总工作量的50%。

王昕负责课程设计的 部分类的定义内容、部分类的定义及实现、背景音乐、分数输出、按等级加分、报告书部分,所做工作占总工作量的 50%。

二、需求分析

2.1系统概述

《俄罗斯方块》由莫斯科科学学院程序员Alexei Pajitnov所设计。该游戏最初是作为自我消遣的电脑游戏而被制作出来的。此后,由于政治和经济等多方面的原因,该游戏曾经被多家公司代理过。经过多轮诉讼的争夺后,该游戏的代理权最终还是被任天堂获得。俄罗斯方块对于任天堂来说意义重大,因为将它与GB搭配在一起后,产生了令人意想不到的效果,获得了巨大的成功。而对于中国玩家来说,俄罗斯方块可以说是第一次让国人认识到游戏是一种老少皆宜的娱乐方式,从某种程度上扭转了国人的\游戏是小孩子的东西\或\游戏是毒害儿童的元凶\等错误观念。一个最初的版本是Spectrum Holobyte为IBM兼容机开发的游戏。

该游戏是一款休闲智力型,与通常的此类游戏相比,这款游戏新增了在模块样式上的多彩性。还抛掉了以前那种枯燥的背景音乐,可以让自己随心所欲的背景音乐。于此同时还可以让自己开动脑筋来设计模块。还可以凭自己的喜好。可以设置画布的大小。

2.2系统运行环境

系统的运行对于运行环境的要求是: ? 硬件环境

2

目前,我们所开发的系统主要应用在中小规模的学校内部,因此,一般配置的计算机硬件就可以满足系统需求。考虑到学校规模的扩大和硬件价格的降低,为本系统配置在较优秀的服务器硬件上,可以充分发挥本系统的性能。

? 处理器:Intel Pentium 4 3.06 GX 或更高 ? 内存:256M(推荐) ? 硬盘空间:40GB

? 显卡:SVGA显示适配器

? 软件环境

? 操作系统:Windows 2000/XP

? 开发软件:Microsoft Visual Studio .NET 2003 ? 数据库:Microsoft SQL Server 2000

? 2.3功能需求描述

俄罗斯方块游戏是一个经典的小游戏,由于它简单有趣,因而得到了广泛的流行,男女老幼都适合。而俄罗斯方块游戏的设计工作复杂且富有挑战性,它包含的内容多,涉及的知识广泛,与图形界面联系较大,包括界面的显示与更新、数据收集、音乐处理等,在设计的过程中,必将运用到各方面的知识,这对于C#设计者而言,是个很好的锻炼机会。

游戏中,玩家依靠自己消层来得分,一下消四格是很有难度的,但是分数有很有诱惑,同时也是给了玩家自己更多的空间。当玩家游戏池中的砖块累积到顶端时游戏失败。

三、总体设计

3.1屏幕的组成

一个游戏一定要有一个界面供游戏者对游戏控制。这个界面中要包含让游戏者更加清楚游戏状态的信息,比如,一个方块在下落过程中,它的位置如何,形状是怎么样的,要如何放置这个方块,以及下一个方块是什么形状,这样关系着游戏者要如何放置方块,让整体有个更加的布局,有利于游戏的进行。屏幕由20行10列的网格组成。在界面的左边就是相关的游戏控制说明,右边是游戏的级别、分数显示,设置了游戏背景,设置了方块的形状、颜色及目前的得分情况,下一个预览方块。

3.2形状的组成

有几个方块形状是由四个方块组成,比如■■■■由四个方块横向排列而成,还有一个是三个构成,另一个是五个构成。共九种形状!

3.3形状的统一

■■■■等共24种形状(旋转前后的形状归为不同的形状),虽然在玩游戏时我们会去将各种不同的形状有个不同的命名(比如“条子”,“方块”等),但在设计游戏是它们却

3

是统一的,它们都是“形状”。这一点是游戏成功的基础。

为了使各种不同的形状达到统一的设计,我设计了如下解决方案:将形状始终放在4×4的格子中,以该4×4格子的第一个格子为“基础点”,只要给出组成形状的四个块相对于该基础点的相对坐标。

□□□□ □□□□ □□□□ □□□□

我们把每一列从下向上用十六进制1,2,4,8,然后加起来形成一个数 那么■■■■在其中就如图:其代码是0x0F00 ■□□□ ■□□□ ■□□□ 0x0F00 ■□□□ 同理: □□□□ □■■□ □■■□ □□□□ 0x0660

这样,我们只要知道某个形状的相对坐标值数组,就可以轻松地求出它的各方块的排列方式,也就是其形状(样子)。

3.4移动与旋转的统一

从上面我们可以看出形状的移动可以这样来实现:先通过DrawBlock(g_CurBlock, HIDE)把方块隐藏,让x--(左移),x++(右移)改变方块的坐标,然后用DrawBlock(g_CurBlock)函数又将其现实出来 ,从而实现其整体移动。

旋转:更具其旋转后的形状在类中写出其相应的坐标,让后调用类模块函数,在没有到一个变幻形状的命令时调用 g_Blocks类中的函数init函数实行变形

四、详细设计

对整个设计进行总体分析如下:

4

1.定义7种砖块的类型,用两个4*4的二维数组来表示。 2.在屏幕上用一个10*20表示游戏区域 3.上下左右的出界问题的考虑

3.砖块的变形问题

4.砖块的移动(向左向右向下)问题 5.满一行后消掉砖块 6.记分问题

7.用开始按扭启动游戏 8.暂停按扭暂停游戏 9.界面的设定 10.背景音乐的加入

系统功能设计

玩游戏前先要设置参数,键盘的设置比如说:左键,右键,下键,快速向下键。顺时针旋转,逆时针旋转。环境的设置也非常重要,比如:水平格子数,垂直格子数。格子数。前景色等,再者就是砖块的设置,砖块是自己设计的,但是系统也有默认砖块,都是最常用的模块。还可以改变模块的颜色。本系统主要设计以下几种功能: 1. 方块下落、变形功能

在整个俄罗斯方块游戏中,方块的设计是核心。这里设计了一个方块类:Square( ),用来生成方块以及实现块的左移、右移、向下、变形、重画、同步显示、初始化新块等。

2自动升级功能

当分数累积到一定大小时,系统将自动为玩家提高难度。这里设置了每消除10行方块,就增加一级难度。当难度增加的时候,方块会相应地改变颜色,以作为对玩家的提示。

3游戏音乐功能

游戏开始音乐就自动播放,游戏暂停与结束时音乐相应消除。

5

4.1程序流程图

4.1.1数据流图

数据流图是对系统数据流向的一种描述,并从本质上让程序的使用者,大致了解系

统的使用方法。本俄罗斯游戏的大致流程图如下:

输入模块 打屏 开幕 文抓 件图 夹截 添图 加

总控模块 处理模块 图1 系统功能模块结构图

6

输出模块 图控图片制片处窗另 理 口 存 为 1. 以系统功能设计分析

俄罗斯方块游戏根据功能的不同,设置了如下12个类:Square, Command, GameArea, GameSetting, GameOver, Help, ImagePanel, 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)。分别实现方块的重画、翻转、左移、右移、下落、同步显示等功能。

2、Command,处理控制类。这是一个实现ActionListener接口的类,主要处理点击按钮事件。类中定义了三个int型变量:button_play,button_quit,button_pause,和一个boolean型的变量:pause_resume,并赋值。在GameArea类中通过事件响应,在按钮执行方法中调用其值,使用switch语句,根据不同按钮不同的值,来响应不同的事件。

3、GameArea,游戏界面类。GameArea继承了JFrame,是俄罗斯方块的主要游戏界面。这个类定义了GameSetting类的gameScr对象和ImagePanel类的imagepanel对象作为游戏区域面板和控制区域面板。在游戏区域,主要是根据相应格子的设置标志来显示相应的图形图片,这样就实现了俄罗斯方块的实时显示。

4、GameSetting, 游戏画布类。这个类生成的对象将作为游戏界面的方块下落区域,画布的设置为15行10列,当中的方格边长为30,类中还定义了一个二维数组int [][] scrArr作为屏幕数组,表示每一个方格。游戏区域中每一个方格是否存在游戏方块是由该方格的值来决定的,如果该方格的值为1,则表示该方格中存在游戏方块;如果该方格中的值为0,则表示该方格中不存在游戏方块,因此二维数组用于记录游戏区域中每个小方格的值。此外,类中还定义了画方块的方法,根据不同的难度画出不同颜色的方块。单击Play按钮时,系统调用initScr( )方法,初始化屏幕,将屏幕数组清零。当满足满行删除的条件时,系统调用deleteFullLine( )方法,进行删行加分,而且每删除十行,难度自动增加一级,方块颜色改变,并在难度显示框中相应显示。

5、GameOver,游戏结束弹出提示框类。当游戏结束时,系统弹出提示,包括玩家分数以及询问玩家要继续游戏还是退出。

6、Help,帮助类。在游戏界面,按F1键,弹出提示窗口,获取帮助。

7、ImagePanel,背景图片类。这个类继承了JPanel类,用来作为游戏界面中控制区域的容器,并添加图片。

8、JieMian,主界面类。这个类继承了JPanel类,作为游戏的第一个界面,也是难度选择界面。定义了9个单选按钮,当玩家未选任何难度就按Enter时,系统会弹出一个提示框,提示玩家先选难度再进入。

9、MyPanel,重写MyPanel类,使Panel的四周留空间。

10、MyTimer,定时线程类。类中定义了一个run()方法,用sleep()函数实现方块下落的快慢,即调节难度。

11、PlayMidi,添加音乐类。在游戏过程中添加背景音乐。 12、WinListener,关闭窗口类。

7

2.

4.1 界面设计

1、图片浏览器主界面如下图2:

图2. 软件主界面图 2、参数设置如下图3:

8

图3 设置图

3、图片调整界如图4:

4.2 代码设计

1.输入模块:

1.1 从文件夹中打开需要浏览的图片:

openImage()

private void openImage() {

9

// 如果当前正显示幻灯片,先关闭定时器2 this.timer1.Enabled = false;

if(this.openFileDialog1.ShowDialog() == DialogResult.OK) {

if(this.pictureBox1 .Image !=null) this.pictureBox1 .Image.Dispose (); pictureBox1.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 += \this.pictureBox1.Image.Size.Height.ToString(); //得到图片所在文件夹的路径 string filePath = \

filePath = openFileDialog1.FileName.Substring

(0,openFileDialog1.FileName.LastIndexOf(\

10

//打开目录,并将目录中所有.jpg.bmp.gif类型的图片放入FileInDir集合

System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(filePath);

System.IO.FileInfo[] fileInfo = dir.GetFiles(); FileInDir.Clear();

foreach(FileInfo fi in fileInfo) {

if(fi.Extension == \\

\fi.Extension == \fi.Extension == \

fi.Extension == \\ {

FileInDir.Add(fi.FullName.ToString()); }

}//得到当前打开图片在FileInDir中的索引(index为定义的全局变量)

for(index = 0;index

11

if(FileInDir[index].ToString() == entireFilePath) { break; } }

if(FileInDir.Count > 1)

{//确定图片浏览的上一张和下一张按钮的可用性 this.toolBarButton7.Enabled = true; if(index == 0)

{//当索引值为第一章时上一张按钮不可用 this.toolBarButton5.Enabled = false; this.toolBarButton6.Enabled = true; }

else if(index == FileInDir.Count-1) {

this.toolBarButton6.Enabled = false; this.toolBarButton5.Enabled = true; } else {

this.toolBarButton5.Enabled = true;

12

this.toolBarButton6.Enabled = true; } }

this.statusBarPanel1.Text =

this.openFileDialog1.FileName.ToString();//在状态栏显示浏览图片的路径

FileInfo info =new FileInfo (this.openFileDialog1 .FileName .ToString ()); this.statusBarPanel3 .Text =\文件大小:\info.Length.ToString () +\//显示图片文件的大小 } }

从文件夹中拖进图片框:这里用到两个事件:_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 = DragDropEffects.None;

13

}

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; i< files.Length ;i++) {

test(files[i]); } } }

抓屏和截图:这里的代码用到了API函数,这是一段从网上找来的代码改的。在抓屏这个功能中关键代码如下;

this.Visible = false ;

IntPtr dc1 = CreateDC ( \null , null , ( IntPtr ) null ) ;

//获取屏幕句柄,即源显示设备句柄

Graphics g1 = Graphics.FromHdc ( dc1 ) ; MyImage = new Bitmap

14

( Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , g1 ) ; //初始化Bitbmp实例

Graphics g2 = Graphics.FromImage ( MyImage ) ; Visible = false ; dc1 = g1.GetHdc ( ) ; IntPtr dc2 = g2.GetHdc ( ) ; //获取Bitbmp实例对应的句柄 BitBlt ( dc2 , 0 , 0 , Screen.PrimaryScreen.Bounds.Width,

Screen.PrimaryScreen.Bounds.Height , dc1 , 0 , 0 , 13369376 ) ; //利用Bitblt函数,把当前屏幕拷贝到创建的Bitbmp实例中

g1.ReleaseHdc ( dc1 ) ; g2.ReleaseHdc ( dc2 ) ; this.Visible = true ; this.SetBounds ( 0 ,

0 ,pictureBox1 .Width ,this.pictureBox1 .Height) ; //this.Cursor = Cursors.Cross ; this.pictureBox1 .Image =MyImage; 截图功能代码如下:

private void Form3_MouseDown(object sender,

15

System.Windows.Forms.MouseEventArgs e) {

if(!isDoubleClick) {

begin = true;

if ( StartedCrop == false ) {

DeltaX = 0 ; DeltaY = 0 ; }

StartedCrop = true ;

StartPoint = new Point ( e.X , e.Y ) ; SelectRect.Width = 0 ; SelectRect.Height = 0 ; SelectRect.X = e.X ; SelectRect.Y = e.Y ; Invalidate ( ) ; } }

private void Form3_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) {

16

if(begin) {

Form thisform = ( Form ) sender ; if ( StartedCrop ) {

DeltaX = e.X - StartPoint.X ; if ( DeltaX < 0 ) DeltaX = 0 ;

DeltaY = e.Y - StartPoint.Y ; if ( DeltaY < 0 ) DeltaY = 0 ;

ControlPaint.DrawReversibleFrame

( thisform.RectangleToScreen ( SelectRect ) , Color.Black , FrameStyle.Dashed ) ;

SelectRect.Width = e.X - SelectRect.X ; SelectRect.Height = e.Y - SelectRect.Y ; ControlPaint.DrawReversibleFrame

( thisform.RectangleToScreen ( SelectRect ) , Color.Black , FrameStyle.Dashed ) ; } } }

17

private void Form3_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {

StartedCrop = false ;

SelectRect.X = e.X-StartPoint.X ;

SelectRect.Y = e.Y-StartPoint.Y ;//鼠标截图的区域 this.Cursor = Cursors.Cross ; isDoubleClick = true; }

private void Form3_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)

{//响应键盘按下Esc退出,按下Enter则截图 switch(e.KeyCode ) {

case Keys.Escape : this.Close(); break; case Keys.Enter : Qscreen(); break; } }

18

private void Form3_Load(object sender, System.EventArgs e)

{//在抓屏后在对抓去的图片全屏并进行截图

IntPtr dc1 = CreateDC ( \null , null , ( IntPtr ) null ) ;

//获取屏幕句柄,即源显示设备句柄

Graphics g1 = Graphics.FromHdc ( dc1 ) ; MyImage = new Bitmap ( Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , g1 ) ; //初始化Bitbmp实例

Graphics g2 = Graphics.FromImage ( MyImage ) ; Visible = false ; dc1 = g1.GetHdc ( ) ; IntPtr dc2 = g2.GetHdc ( ) ; //获取Bitbmp实例对应的句柄 BitBlt ( dc2 , 0 , 0 , Screen.PrimaryScreen.Bounds.Width ,

Screen.PrimaryScreen.Bounds.Height , dc1 , 0 , 0 , 13369376 ) ; //利用Bitblt函数,把当前屏幕拷贝到创建的Bitbmp实例中

g1.ReleaseHdc ( dc1 ) ;

19

g2.ReleaseHdc ( dc2 ) ; //this.Visible = true ; this.SetBounds ( 0 , 0 , Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height ) ;

this.Cursor = Cursors.Cross ;//鼠标为十字型鼠标 }

private void Form3_Paint(object sender, System.Windows.Forms.PaintEventArgs e) {

if ( MyImage != null ) {

e.Graphics.DrawImage ( MyImage , ClientRectangle , 0 , 0 , MyImage.Width , MyImage.Height , GraphicsUnit.Pixel ) ; } }

private void Form3_DoubleClick(object sender, System.EventArgs e) {

this.Left = 0 ; this.Top = 0 ;

Bitmap theImage = new Bitmap ( DeltaX , DeltaY ) ;

20

Graphics g = Graphics.FromImage ( theImage ) ; Rectangle destRect = new Rectangle ( 0 , 0 , DeltaX , DeltaY ) ;

g.DrawImage ( MyImage , destRect , StartPoint.X , StartPoint.Y , theImage.Width , theImage.Height , GraphicsUnit.Pixel ) ;

//利用DrawImage方法实现对源图片的截取 MyImage = ( Bitmap ) theImage.Clone ( ) ; this.SetBounds ( 0 , 0 , MyImage.Width , MyImage.Height ) ;

//根据捕获的图片设定窗体的边界 this.Cursor = Cursors.Cross ; Invalidate ( ) ;

//MyImage.Save ( @\

//MessageBox.Show ( @\已经保存为C:\\Captured.jpg!\

this.pictureBox1 .Image =MyImage; this.Close (); }

2.处理模块:

2.1图片文件管理:报考对图片的打开,保存,另存为,和软件的退出。代码如下:

21

private void menuItem3_Click(object sender, System.EventArgs e)

{//保存图片在C盘且图片文件名为Captured.jpg if(this.pictureBox1.Image !=null) {

this.pictureBox1 .Image.Save(@\//FileInDir[index].ToString());

MessageBox.Show ( @\已经保存为C:\\Captured.jpg!\//\ } else

MessageBox.Show (\没有要保存的图片!\ }

private void menuItem4_Click(object sender, System.EventArgs e)

{ //图片另存为

if(this.pictureBox1 .Image !=null) {

this.saveFileDialog1.Filter=\图像文件

(*.JPG)|*.JPG|图像文件(*.BMP)|*.BMP|图像文件(*.GIF)|*.GIF|图像文件(*.PNG)|*.PNG|所有文件(*.*)|*.*\

22

this.saveFileDialog1.ShowDialog();

string StrFileName=this.saveFileDialog1.FileName; //if (saveFileDialog1.ShowDialog() == DialogResult.OK) // 文件名

if(StrFileName.Trim()==\ return;

this.pictureBox1.Image .Save (StrFileName); } else

MessageBox.Show (\没有要保存的图片!\ }

2.2对图片浏览并进行放大缩小,关键代码如下: private void viewImage(bool mark) {

//如果图片框中当前有显示图片时才可进行该方法 if(this.pictureBox1.Image != null) {

//如是mark值为-1,则向前显示 if(!mark) {

23

if(index == 0) {

MessageBox.Show(\这是第一张了\ //index = FileInDir.Count-1; } else {

this.pictureBox1.Image =

Image.FromFile(FileInDir[--index].ToString());//图片框中加载按索引显示图片

//VbycView(); //rad();

shiheView(); } }

//如果为1,则向后显示 else {

if(index == FileInDir.Count-1) {

MessageBox.Show(\这是最后一张\ //index=0;

24

} else {

this.pictureBox1.Image = Image.FromFile(FileInDir[++index].ToString()); //rad(); //VbycView();

shiheView();//按合适的显示方式显示在图片框中

} }

entireFilePath2 = FileInDir[index].ToString();

this.statusBarPanel1 .Text = FileInDir[index].ToString();

FileInfo info =new FileInfo (this.statusBarPanel1 .Text );

this.statusBarPanel3 .Text =\文件大小:\info.Length.ToString ()+\//显示滚动图片的文件大小 } else {

25

MessageBox.Show(\请先打开图片\ } }

private void preView() {//上一张图片

this.pictureBox1 .Image .Dispose ();//释放图片框占用的资源

viewImage(false); }

private void nextView() {//下一张图片

this.pictureBox1 .Image .Dispose (); viewImage(true); }

private void max() { //放大图片

int w=pictureBox1 .Image .Width ;//图片的宽 int h=pictureBox1 .Image .Height ;//图片的高 // int b=w/h; w=w+25; h=h+20; NewBitmap=new

26

Bitmap(this.pictureBox1 .Image,w,h);//(int)this.numericUpDown1.Value,(int)this.numericUpDown2.Value);新建位图并显示在图片框中

this.pictureBox1.Image=NewBitmap; }

private void min() { //缩小图片

int w=pictureBox1 .Image .Width ; int h=pictureBox1 .Image .Height ;; //int b=w/h; w=w-25; h=h-20;

NewBitmap=new Bitmap(this.pictureBox1.Image,w,h); this.pictureBox1.Image=NewBitmap;//将改变后的位图显示在图片框中 }

2.3对图片进行幻灯片播放:此关键功能包括对图片的动态显示,背景音乐播放,和自动浏览,关键代码如下: 动态效果的函数: private void rad() { //随机出现动态显示

string[] aa={\

27

Random rr = new Random();

string bb = aa[rr.Next(0,aa.Length)]; switch(bb)

{//建立一个随机数组,并随机运行图片动态显示的函数 case \ utdView(); break; case \ rtlView(); break; case \

lblsView(); break; case \ ksView(); break; case \ fzView(); break; case \ VbycView(); break;

28

case\ HbycView(); break; } }

private void HbycView() {//水平百叶窗方式显示

MyBitmap=(Bitmap)this.pictureBox1.Image.Clone(); int dh=MyBitmap.Height/30; int dw=MyBitmap.Width;

Graphics g=this.pictureBox1.CreateGraphics(); g.Clear(Color.Gray);

Point []MyPoint=new Point[30]; for(int y=0;y<30;y++) {

MyPoint[y].X=0; MyPoint[y].Y=y*dh; }

Bitmap bitmap=new

Bitmap(MyBitmap.Width,MyBitmap.Height); for(int i=0;i

29

for(int j=0;j<30;j++) {

for(int k=0;k

bitmap.SetPixel(MyPoint[j].X+k,MyPoint[j].Y+i,MyBitmap.GetPixel(MyPoint[j].X+k,MyPoint[j].Y+i)); } }

this.pictureBox1.Refresh(); this.pictureBox1.Image=bitmap; System.Threading.Thread.Sleep(50); } }

private void VbycView() {//垂直百叶窗显示图像

MyBitmap=(Bitmap)this.pictureBox1.Image.Clone(); int dw=MyBitmap.Width/50; int dh=MyBitmap.Height;

Graphics g=this.pictureBox1.CreateGraphics();//创建一个Graphics对象

g.Clear(Color.Gray); //清除整个绘图面,并以灰色填充

30

为背景色

Point []MyPoint=new Point[50]; for(int x=0;x<50;x++) {

MyPoint[x].Y=0; MyPoint[x].X=x*dw; }

Bitmap bitmap=new

Bitmap(MyBitmap.Width,MyBitmap.Height);//处理由像素数据定义的图像

for(int i=0;i

for(int j=0;j<50;j++) {

for(int k=0;k

bitmap.SetPixel(MyPoint[j].X+i,MyPoint[j].Y+k,MyBitmap.GetPixel(MyPoint[j].X+i,MyPoint[j].Y+k));//指定位图像素的颜色

} }

31

this.pictureBox1.Refresh(); this.pictureBox1.Image=bitmap;

System.Threading.Thread.Sleep(50);//阻塞线程指定的时间 } }

private void rtlView() {//从左到右的显示

int iWidth=this.pictureBox1.Width; //图像宽度 int iHeight=this.pictureBox1.Height; //图像高度 //取得Graphics对象

Graphics g=this.pictureBox1.CreateGraphics(); g.Clear(Color.Gray); //初始为全灰色 for(int x=0;x<=iWidth;x=x+2) {

g.DrawImage(this.pictureBox1.Image,0,0,x,iHeight); } }

private void utdView() {//从上到下拉伸显示

int iWidth=this.pictureBox1.Width; //图像宽度

32

int iHeight=this.pictureBox1.Height; //图像高度 //取得Graphics对象

Graphics g=this.pictureBox1.CreateGraphics(); g.Clear(Color.Gray); //初始为全灰色 for(int y=0;y<=iHeight;y++) {

g.DrawImage(this.pictureBox1.Image,0,0,iWidth,y); } }

private void ksView() {//四周扩散显示

int iWidth=this.pictureBox1.Width; //图像宽度 int iHeight=this.pictureBox1.Height; //图像高度 //取得Graphics对象

Graphics g=this.pictureBox1.CreateGraphics(); g.Clear(Color.Gray); //初始为全灰色 for(int x=0;x<=iWidth/2;x++) {

Rectangle DestRect=new Rectangle(iWidth/2-x, iHeight/2-x,2*x,2*x);

Rectangle SrcRect=new Rectangle(0,0,

33

this.pictureBox1.Image.Width,this.pictureBox1.Image.Height);

g.DrawImage(this.pictureBox1.Image,DestRect,SrcRect, GraphicsUnit.Pixel); } }

private void fzView() {//反转图像

int iWidth=this.pictureBox1.Width; //图像宽度 int iHeight=this.pictureBox1.Height; //图像高度 //取得Graphics对象

Graphics g=this.pictureBox1.CreateGraphics(); g.Clear(Color.Gray); //初始为全灰色 for(int x=-iWidth/2;x<=iWidth/2;x++) {

Rectangle DestRect=new Rectangle(0,iHeight/2-x, iWidth,2*x); Rectangle SrcRect=new

Rectangle(0,0,this.pictureBox1.Image.Width,this.pictureBox1.Image.Height);

34

g.DrawImage(this.pictureBox1.Image,DestRect,SrcRect,GraphicsUnit.Pixel); } }

private void lblsView() {//两边拉伸显示

int iWidth=this.pictureBox1.Width; //图像宽度 int iHeight=this.pictureBox1.Height; //图像高度 //取得Graphics对象

Graphics g=this.pictureBox1.CreateGraphics(); g.Clear(Color.Gray); //初始为全灰色 for(int y=0;y<=iWidth/2;y++) {

Rectangle DestRect=new Rectangle(iWidth/2-y,0, 2*y,iHeight); Rectangle SrcRect=new

Rectangle(0,0,this.pictureBox1.Image.Width,this.pictureBox1.Image.Height);

g.DrawImage(this.pictureBox1.Image,DestRect,SrcRect,GraphicsUnit.Pixel);

35

} }

背景音乐的代码:这里得应用Directx控件, private string filterText=\

Files(*.wav;*,mpa;*.mp2;*.mp3;*.wma)|*.wav;*,mpa;*.mp2;*.mp3;*.wma|\ \

Files(*.mid,*.midi,*.rmi)|*.mid,*.midi,*.rmi|\ \ private Audio ourAudio=null;

double ourfileLen=0;//设置媒体大小的变量 private void OpenFile() {

if(ourAudio!=null) {

ourAudio.Stop(); ourAudio=null; }

OpenFileDialog ofdOpen=new OpenFileDialog(); ofdOpen.Filter=filterText; ofdOpen.Title=\打开媒体文件\

//string filename = this.openFileDialog1.FileName;

36

if(ofdOpen.ShowDialog()==DialogResult.OK) {

this.textBox2.Text =ofdOpen.FileName ; //OpenFileDialog ofdOpen=new OpenFileDialog(); ofdOpen.Filter=filterText; ofdOpen.Title=\打开媒体文件\

if((ofdOpen.FileName!=null)&&(ofdOpen.FileName!=string.Empty)) { try {

if(ourAudio==null) {

ourAudio=new Audio(ofdOpen.FileName);

ourAudio.Ending+=new System.EventHandler(this.ClipEnded);

ourfileLen=ourAudio.Duration; //ourAudio.Play(); } else

37

{

ourAudio.Open(ofdOpen.FileName,true); } } catch {

MessageBox.Show(\这个文件不能被打开\无效的文件\ } } } }

2.4图片的滤镜效果和 private void fsView() {//以反色方式显示图像

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;

for(int x=1;x

38

for(int y=1;y

int r,g,b;

pixel=MyBitmap.GetPixel(x,y); r=255-pixel.R; g=255-pixel.G; b=255-pixel.B;

bitmap.SetPixel(x,y,Color.FromArgb(r,g,b)); } }

this.pictureBox1.Image=bitmap; }

private void fdView() {//以浮雕方式显示图像

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 pixel1,pixel2; for(int x=0;x

for(int y=0;y

39

{

int r=0,g=0,b=0;

pixel1=MyBitmap.GetPixel(x,y); pixel2=MyBitmap.GetPixel(x+1,y+1); r=Math.Abs(pixel1.R-pixel2.R+128); g=Math.Abs(pixel1.G-pixel2.G+128); b=Math.Abs(pixel1.B-pixel2.B+128); if(r>255) r=255; if(r<0) r=0; if(g>255) g=255; if(g<0) g=0; if(b>255) b=255; if(b<0) b=0;

bitmap.SetPixel(x,y,Color.FromArgb(r,g,b)); }

40

}

this.pictureBox1.Image=bitmap; }

private void hbView()

{//以黑白方式显示图像

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;

for (int x=0; x

pixel=MyBitmap.GetPixel(x,y); int r,g,b,Result=0;

r = pixel.R; g = pixel.G; b = pixel.B;

//实例程序以加权平均值法产生黑白图像 int iType=2; switch(iType) {

41

case 0://平均值法 Result=((r+g+b)/3); break; case 1://最大值法 Result=r>g?r:g;

Result=Result>b?Result: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;

42

Bitmap bitmap=new Bitmap(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;x

int r=0,g=0,b=0; int Index=0; //int a=0;

for(int col=-1;col<=1;col++) for(int row=-1;row<=1;row++) {

pixel=MyBitmap.GetPixel(x+row,y+col);

r+=pixel.R*Gauss[Index]; g+=pixel.G*Gauss[Index]; b+=pixel.B*Gauss[Index]; Index++; } r/=16;

43

g/=16; b/=16;

//处理颜色值溢出 r=r>255?255:r; r=r<0?0:r; g=g>255?255:g; g=g<0?0:g; b=b>255?255:b; b=b<0?0:b;

bitmap.SetPixel(x-1,y-1,Color.FromArgb(r,g,b)); }

this.pictureBox1.Image=bitmap; }

private void whView()

{//以雾化方式显示图像

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; for(int x=1;x

44

for(int y=1;y

System.Random MyRandom=new Random();

int k=MyRandom.Next(123456); //像素块大小 int dx=x+k; int dy=y+k; if(dx>=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 void RhView()

{//以锐化方式显示图像

int Height=this.pictureBox1.Image.Height; int Width=this.pictureBox1.Image.Width; Bitmap bitmap=new Bitmap(Width,Height);

45

Bitmap MyBitmap=(Bitmap)this.pictureBox1.Image; Color pixel; //拉普拉斯模板

int []Laplacian={-1,-1,-1,-1,9,-1,-1,-1,-1};

for(int x=1;x

int r=0,g=0,b=0; int Index=0; //int a=0;

for(int col=-1;col<=1;col++) for(int row=-1;row<=1;row++) {

pixel=MyBitmap.GetPixel(x+row,y+col);

r+=pixel.R*Laplacian[Index]; g+=pixel.G*Laplacian[Index]; b+=pixel.B*Laplacian[Index]; Index++; }

//处理颜色值溢出

46

r=r>255?255:r; r=r<0?0:r; g=g>255?255:g; g=g<0?0:g; b=b>255?255:b; b=b<0?0:b;

bitmap.SetPixel(x-1,y-1,Color.FromArgb(r,g,b)); }

this.pictureBox1.Image=bitmap; }

2.5图片的显示方式: private void shiheView() { //图片的显示方式

double iPictureBoxWidth = this.pictureBox1.Width; double iPictureBoxHeight = this.pictureBox1.Height; double iImageWidth = this.pictureBox1.Image.Size.Width; double iImageHeight = this.pictureBox1.Image.Size.Height; // 如果图片长小于图片框长

if(iImageWidth<=iPictureBoxWidth &&

47

iImageHeight<=iPictureBoxHeight) {

this.pictureBox1.SizeMode =

System.Windows.Forms.PictureBoxSizeMode.CenterImage;//图片居中显示 }

// 如果图片高小于图片框高

else if(iImageHeight>=iPictureBoxHeight && iImageWidth>=iPictureBoxWidth) {

this.pictureBox1.SizeMode =

System.Windows.Forms.PictureBoxSizeMode.StretchImage;//图片全图片框显示 }

//如果图片长和高都大于图片框长和高 else if(iImageWidth<=iPictureBoxWidth && iImageHeight>=iPictureBoxHeight) {

this.pictureBox1.SizeMode =

System.Windows.Forms.PictureBoxSizeMode.Normal;//图片正常显示 }

48

else {

this.pictureBox1.SizeMode =

System.Windows.Forms.PictureBoxSizeMode.AutoSize;//图片自动大小显示 } }

2.6对图片进行明暗度,对比度,色相,饱和度的调整,此功能还没有实现。 5结束语

用了我们大概一周的时间,终于把俄罗斯方块游戏完成了。这段时间里,我搜集资料、查看书籍,本来以为在大专时学过,很简单,但是实际操作起来非常困难,

在编写过程中遇到许多问题。

在系统分析阶段,针对俄罗斯方块游戏,初步地定下了要实现的功能,并将整个游戏分成若干个部分。在程序编写阶段,出现了不少技术上的问题。出于基础不扎实这方面的原因,在程序设计的时候遇到了不少问题,甚至被布局管理器的简单问题弄得焦头烂额。但在一次次的错误运行中,我们对面向对象程序设计的概念理解得更加深刻,也因此重新燃起斗志。可是在如方块预览方面,我们始终不能完成这一功能,这也是缺陷的所在。

鉴于水平能力问题,对于俄罗斯方块的核心程序我们并未能形成一个有机的概念,对于其核心算法也未能准确掌握。诸如某些库函数已提供的方法,我们也不太了解。出于这样的原因,我们上网查找了大量资料,借鉴了前人程序的一些方法,经过深入研究学习后,再加工提炼,在原有的基础上加入我们自己的想法,并进行设计。

在设计开发过程中,我们不但需要处理好各个类之间的集成关系和继承机制,还要处理各个类的相应的封装,并且还要协调好各个模块之间的逻辑依赖关系和数据通信关系。通过这次的课程设计,我们更深地体会到软件工程的理念,并以一个程序员应有的素质来要求自己,大致掌握了软件开发的基本过程,也感受到团队合作的重要性。俄罗斯方块游戏的设计对于每个C#语言设计者来说,都是一个很好的提高和进阶的锻炼机会。

49

本文来源:https://www.bwwdw.com/article/4h5o.html

Top