C#设计报告 俄罗斯方块.docx
《C#设计报告 俄罗斯方块.docx》由会员分享,可在线阅读,更多相关《C#设计报告 俄罗斯方块.docx(39页珍藏版)》请在冰豆网上搜索。
![C#设计报告 俄罗斯方块.docx](https://file1.bdocx.com/fileroot1/2023-2/13/f16c326f-c4e7-4603-a3a1-9e569d9125cb/f16c326f-c4e7-4603-a3a1-9e569d9125cb1.gif)
C#设计报告俄罗斯方块
项目实训报告书
学生姓名
课程名称C#课程设计
题目俄罗斯方块
专业班级
指导教师
完成日期
一.概述…………………………………………2
1.1背景………………………………………………2
1.2开发与运行环境………………………………..3
二.需求分析……………………………………3
三.系统设计…………………………………4
四.详细设计……………………………....5
4.1界面设计……………………………………..5
4.2代码设计……………………………………..7
五.结束语………………………………….25
六.参考文献……………………………….26
1.概述
1.1背景
《俄罗斯方块》由莫斯科科学学院程序员AlexeiPajitnov所设计。
该游戏最初是作为自我消遣的电脑游戏而被制作出来的。
此后,由于政治和经济等多方面的原因,该游戏曾经被多家公司代理过。
经过多轮诉讼的争夺后,该游戏的代理权最终还是被任天堂获得。
俄罗斯方块对于任天堂来说意义重大,因为将它与GB搭配在一起后,产生了令人意想不到的效果,获得了巨大的成功。
而对于中国玩家来说,俄罗斯方块可以说是第一次让国人认识到游戏是一种老少皆宜的娱乐方式,从某种程度上扭转了国人的"游戏是小孩子的东西"或"游戏是毒害儿童的元凶"等错误观念。
一个最初的版本是SpectrumHolobyte为IBM兼容机开发的游戏。
该游戏是一款休闲智力型,与通常的此类游戏相比,这款游戏新增了在模块样式上的多彩性。
还抛掉了以前那种枯燥的背景音乐,可以让自己随心所欲的背景音乐。
于此同时还可以让自己开动脑筋来设计模块。
还可以凭自己的喜好。
可以设置画布的大小。
1.2开发与运行环境
系统的运行对于运行环境的要求是:
●硬件环境
目前,我们所开发的系统主要应用在中小规模的学校内部,因此,一般配置的计算机硬件就可以满足系统需求。
考虑到学校规模的扩大和硬件价格的降低,为本系统配置在较优秀的服务器硬件上,可以充分发挥本系统的性能。
●处理器:
IntelPentium43.06GX或更高
●内存:
256M(推荐)
●硬盘空间:
40GB
●显卡:
SVGA显示适配器
●软件环境
●操作系统:
Windows2000/XP
●开发软件:
MicrosoftVisualStudio.NET2003
●数据库:
MicrosoftSQLServer2000
2.课程设计的目的和意义
俄罗斯方块游戏是一个经典的小游戏,由于它简单有趣,因而得到了广泛的流行,男女老幼都适合。
而俄罗斯方块游戏的设计工作复杂且富有挑战性,它包含的内容多,涉及的知识广泛,与图形界面联系较大,包括界面的显示与更新、数据收集、音乐处理等,在设计的过程中,必将运用到各方面的知识,这对于C#设计者而言,是个很好的锻炼机会。
2.1实验步骤:
1) 需求分析:
设计一个用户可参与,有背景音乐,可由用户控制任意暂停,可计时,可计分的俄罗斯方块游戏;
2) 概要设计:
一个游戏运行界面,计分面板,开始按扭,暂停按扭
3) 详细设计:
对整个设计进行总体分析如下:
1.定义7种砖块的类型,用两个4*4的二维数组来表示。
2.在屏幕上用一个10*20表示游戏区域
3.上下左右的出界问题的考虑
3.砖块的变形问题
4.砖块的移动(向左向右向下)问题
5.满一行后消掉砖块
6.记分问题
7.用开始按扭启动游戏
8.暂停按扭暂停游戏
9.界面的设定
10.背景音乐的加入
3系统功能设计
玩游戏前先要设置参数,键盘的设置比如说:
左键,右键,下键,快速向下键。
顺时针旋转,逆时针旋转。
环境的设置也非常重要,比如:
水平格子数,垂直格子数。
格子数。
前景色等,再者就是砖块的设置,砖块是自己设计的,但是系统也有默认砖块,都是最常用的模块。
还可以改变模块的颜色。
本系统主要设计以下几种功能:
1.方块下落、变形功能
在整个俄罗斯方块游戏中,方块的设计是核心。
这里设计了一个方块类:
Square(),用来生成方块以及实现块的左移、右移、向下、变形、重画、同步显示、初始化新块等。
2自动升级功能
当分数累积到一定大小时,系统将自动为玩家提高难度。
这里设置了每消除10行方块,就增加一级难度。
当难度增加的时候,方块会相应地改变颜色,以作为对玩家的提示。
3游戏音乐功能
游戏开始音乐就自动播放,游戏暂停与结束时音乐相应消除。
图1系统功能模块结构图
3.以系统功能设计分析
俄罗斯方块游戏根据功能的不同,设置了如下12个类:
Square,Command,GameArea,GameSetting,GameOver,Help,ImagePanel,JieMian,MyPanel,MyTimer,PlayMidi,WinListener,每个类的描述如下:
1、Square,方块类。
这个类中定义了生成方块的方法,用二维数组int[][]pattern,存放7种方块的四种状态。
在构造方法中以随机的形式生成方块,同时提供了以下几种方法:
reset(),leftTurn(),leftMove(),rightMove(),fallDown(),assertValid(intt,ints,introw,intcol),dispBlock(ints)。
分别实现方块的重画、翻转、左移、右移、下落、同步显示等功能。
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,关闭窗口类。
4.4.1界面设计
1、图片浏览器主界面如下图2:
图2.软件主界面图
2、参数设置如下图3:
图3设置图
3、图片调整界如图4:
4.2代码设计
1.输入模块:
1.1从文件夹中打开需要浏览的图片:
openImage()
privatevoidopenImage()
{
//如果当前正显示幻灯片,先关闭定时器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();
//得到图片所在文件夹的路径
stringfilePath="";
filePath=openFileDialog1.FileName.Substring
(0,openFileDialog1.FileName.LastIndexOf("\\"));
//打开目录,并将目录中所有.jpg.bmp.gif类型的图片放入FileInDir集合
System.IO.DirectoryInfodir=newSystem.IO.DirectoryInfo(filePath);
System.IO.FileInfo[]fileInfo=dir.GetFiles();
FileInDir.Clear();
foreach(FileInfofiinfileInfo)
{
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.Add(fi.FullName.ToString());
}
}//得到当前打开图片在FileInDir中的索引(index为定义的全局变量)
for(index=0;index{
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;
}
elseif(index==FileInDir.Count-1)
{
this.toolBarButton6.Enabled=false;
this.toolBarButton5.Enabled=true;
}
else
{
this.toolBarButton5.Enabled=true;
this.toolBarButton6.Enabled=true;
}
}
this.statusBarPanel1.Text=this.openFileDialog1.FileName.ToString();//在状态栏显示浏览图片的路径
FileInfoinfo=newFileInfo(this.openFileDialog1.FileName.ToString());
this.statusBarPanel3.Text="文件大小:
"+info.Length.ToString()+"B";
//显示图片文件的大小
}
}
从文件夹中拖进图片框:
这里用到两个事件:
_DragDrop和_DragEnter:
privatevoidpictureBox1_DragEnter(objectsender,System.Windows.Forms.DragEventArgse)
{//图片拖进图片框
if(e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect=DragDropEffects.Link;
else
e.Effect=DragDropEffects.None;
}
privatevoidpictureBox1_DragDrop(objectsender,System.Windows.Forms.DragEventArgse)
{//拖进后释放鼠标
if(e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[]files=(string[])e.Data.GetData(DataFormats.FileDrop);
for(inti=0;i{
test(files[i]);
}
}
}
抓屏和截图:
这里的代码用到了API函数,这是一段从网上找来的代码改的。
在抓屏这个功能中关键代码如下;
this.Visible=false;
IntPtrdc1=CreateDC("DISPLAY",null,null,(IntPtr)null);
//获取屏幕句柄,即源显示设备句柄
Graphicsg1=Graphics.FromHdc(dc1);
MyImage=newBitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height,g1);
//初始化Bitbmp实例
Graphicsg2=Graphics.FromImage(MyImage);
Visible=false;
dc1=g1.GetHdc();
IntPtrdc2=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;
截图功能代码如下:
privatevoidForm3_MouseDown(objectsender,System.Windows.Forms.MouseEventArgse)
{
if(!
isDoubleClick)
{
begin=true;
if(StartedCrop==false)
{
DeltaX=0;
DeltaY=0;
}
StartedCrop=true;
StartPoint=newPoint(e.X,e.Y);
SelectRect.Width=0;
SelectRect.Height=0;
SelectRect.X=e.X;
SelectRect.Y=e.Y;
Invalidate();
}
}
privatevoidForm3_MouseMove(objectsender,System.Windows.Forms.MouseEventArgse)
{
if(begin)
{
Formthisform=(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);
}
}
}
privatevoidForm3_MouseUp(objectsender,System.Windows.Forms.MouseEventArgse)
{
StartedCrop=false;
SelectRect.X=e.X-StartPoint.X;
SelectRect.Y=e.Y-StartPoint.Y;//鼠标截图的区域
this.Cursor=Cursors.Cross;
isDoubleClick=true;
}
privatevoidForm3_KeyUp(objectsender,System.Windows.Forms.KeyEventArgse)
{//响应键盘按下Esc退出,按下Enter则截图
switch(e.KeyCode)
{
caseKeys.Escape:
this.Close();
break;
caseKeys.Enter:
Qscreen();
break;
}
}
privatevoidForm3_Load(objectsender,System.EventArgse)
{//在抓屏后在对抓去的图片全屏并进行截图
IntPtrdc1=CreateDC("DISPLAY",null,null,(IntPtr)null);
//获取屏幕句柄,即源显示设备句柄
Graphicsg1=Graphics.FromHdc(dc1);
MyImage=newBitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height,g1);
//初始化Bitbmp实例
Graphicsg2=Graphics.FromImage(MyImage);
Visible=false;
dc1=g1.GetHdc();
IntPtrdc2=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,Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height)