俄罗斯方块游戏设计报告.docx
《俄罗斯方块游戏设计报告.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块游戏设计报告.docx(19页珍藏版)》请在冰豆网上搜索。
俄罗斯方块游戏设计报告
C语言课程设计
报告
设计题目:
俄罗斯方块游戏设计
院系:
班 级:
学号:
姓名:
指导教师:
设计地点:
开课时间:
学生姓名 成绩
评语:
指导教师(签名)
年月日
1.设计目的和任务
1.1目的:
在现今电子信息高速发展的时代,电子游戏已深入人们的日常生活,成为老少皆宜的娱乐方式。
俄罗斯方块,是一款风靡全球的游戏,最初是由苏联人制作的,规则简单,容易上手,且游戏过程变化无穷,可以让玩家充分感受游戏中的乐趣。
在游戏设计方面,俄罗斯方块是游戏编程的入门项目,因为它可以检验编辑人员对开发语言、环境和基本数据结构知识熟练程度。
1.2任务:
使用C#语言编写一个俄罗斯方块游戏系统,要求程序运行后有一个图形用户界面,并具备下面几个功能:
(1)实现各种方块的生产,包括形状和颜色等信息;
(2)实现各个方块的上下左右移动和旋转的功能;
(3)实现消行的功能;
(4)实现开始,暂停,结束等功能。
2.开发环境
2.1硬件环境:
服务器CPU:
PIII500以上,内存:
256M
客户机CPU:
P200MMX以上,内存:
32M以上
2.2软件环境:
VisualStudio2005.net2.0以上
3.设计题目
3.1题目名称:
俄罗斯方块游戏系统
3.2题目详细描述:
使用C#语言编写一个俄罗斯方块游戏系统,要求程序运行后有一个图形用户界面,实现各种方块的生产,包括形状和颜色等信息,完成左右下旋转的功能,在消行的同时分数加1,在点击暂停或者按下空格的时候暂停或开始游戏,最后结束游戏。
3.3功能要求:
功能
(1)实现各种方块的生产,包括形状和颜色等信息;
(2)实现各个方块的上下左右移动和旋转的功能;
(3)实现消行的功能;
(4)实现时间和得分的统计功能;
(5)实现开始,暂停,结束等功能;
要求
(1) 编写程序要严格按照C#编程规范进行代码编写。
(2) 必须按照个体软件的过程,编写有关的文档。
(3) 按照老师的要求,每个人必须独立完成。
(4) 按照实训的时间安排进行实训,实训结束后提交有关的表格与文档
4.相关技术以及知识点
4.1编写Block类:
在游戏项目规范说明书所创建的类图中定义了Block类,现在可以把它编写为最终的类接口形式,包括属性的数据类型以及方法所使用参数的数据类型。
每个确定的方块都与正方形的某种特定排列方式相对应,因此可以考虑Block类的3个新成员:
BlockType属性、方块类型的枚举集合、构造函数(用以在期望的位置、使用期望的色彩创建每个正方形)。
为了给玩家一个清楚的视觉提示,每种类型的方块颜色应该是固定的,因此创建一个数组来保存每种类型方块的前景色和背景色是一种较好的想法。
4.2PathGradientBrush类:
封装Brush对象,它通过渐变填充GraphicsPath对象的内部。
彩色渐变是从路径的中点到路径的外边界边缘的平滑的彩色渐变。
混合因子、位置和样式影响渐变起始和结束的位置,并且影响渐变变化的速度。
路径渐变画笔不遵循用于执行绘制操作的Graphics对象的SmoothingMode属性。
无论是否用平滑模式,用PathGradientBrush对象填充的区域都以同样的方式呈现。
4.3Random类:
伪随机数是以相同的概率从一组有限的数字中选取的。
所选数字并不具有完全的随机性,因为它们是用一种确定的数学算法选择的,但是从实用的角度而言,其随机程度已足够了。
Random类的当前实现基于DonaldE.Knuth的减法随机数生成器算法。
随机数的生成是从种子值开始。
如果反复使用同一个种子,就会生成相同的数字系列。
产生不同序列的一种方法是使种子值与时间相关,从而对于Random的每个新实例,都会产生不同的系列。
默认情况下,Random类的无参数构造函数使用系统时钟生成其种子值,而参数化构造函数可根据当前时间的计时周期数采用Int32值。
但是,因为时钟的分辨率有限,所以,如果使用无参数构造函数连续创建不同的Random对象,就会创建生成相同随机数序列的随机数生成器。
通过创建单个而不是多个Random对象可以避免此问题。
若要提高性能,请创建一个随时间推移能生成多个随机数的Random对象,而不要反复新建会生成同一个随机数的Random对象。
4.4GDI图形处理:
GDI+提供了一个抽象层,隐藏了不同视频卡之间的区别,这样就可以调用WindowsAPI函数完成指定的任务了,GDI还在内部指出在运行特定的代码时,如果让客户机的视频卡完成要绘制的图形。
GDI还可以完成其他任务。
大多数计算机都有多个显示设备---监视器、打印机。
GDI成功的使应用程序所使用的打印机看起来与屏幕一样。
如果要打印某些东西,而不是显示他们,只需告诉系统输出设备是打印机,再用相同的方式调用相同的WindowsAPI函数可以。
5.设计与实现
5.1设计流程图
图5.1.1
5.2游戏主体界面
图5.2.1
主界面关键部分代码:
namespace俄罗斯方块
{
publicpartialclassForm1:
Form
{
publicForm1()
{
InitializeComponent();
}
staticpublicint[,]mainField;
staticpublicintrow=20;//数组mainField[,]的行
staticpublicintline=15;//数组mainField[,]的列
privateBlockcurrentBlock;//主界面中活动的方块
privateBlocknextBlock;//副界面中的方块
privateintlevel=1;
privateintscore=0;
//菜单栏中NewGame
privatevoidmenuItemNew_Click(objectsender,EventArgse)
{
NewGame();
}
//菜单栏中Start,在暂停之后使用,继续进行游戏
privatevoidmenuItemStart_Click(objectsender,EventArgse)
{
timerInterval.Start();
menuItemStart.Enabled=false;
menuItemPause.Enabled=true;
btnPause.Text="Pause";
}
//菜单栏中Pause,用于暂停游戏
privatevoidmenuItemPause_Click(objectsender,EventArgse)
{
timerInterval.Stop();
menuItemStart.Enabled=true;
menuItemPause.Enabled=false;
btnPause.Text="Start";
}
//菜单栏中Exit,用于推出游戏
privatevoidmenuItemExit_Click(objectsender,EventArgse)
{
this.Close();
Application.Exit();
}
//菜单栏中beginnermodel
privatevoidmenuItemBeginer_Click(objectsender,EventArgse)
{
NewGame();
level=1;
timerInterval.Interval=500/level;
labeLevelVisual.Text=Convert.ToString(level);
}
//菜单栏中normalmodel
privatevoidmenuItemNormal_Click(objectsender,EventArgse)
{
NewGame();
level=2;
timerInterval.Interval=500/level;
labeLevelVisual.Text=Convert.ToString(level);
}
//菜单栏中insanemodel
privatevoidmenuItemInsane_Click(objectsender,EventArgse)
{
NewGame();
level=3;
timerInterval.Interval=500/level;
labeLevelVisual.Text=Convert.ToString(level);
}
privatevoidmenuItemOnMusic_Click(objectsender,EventArgse)
{
}
privatevoidmenuItemOffMusic_Click(objectsender,EventArgse)
{
}
//菜单栏中的config选项
privatevoidmenuItemConfig_Click(objectsender,EventArgse)
{
if(!
GameIsOver())
{
timerInterval.Stop();
MessageBox.Show("Left:
Arrow(←)\n\nRight:
Arrow((→)\n\nDown:
Arrow(↓)\n\nRotate:
Arrow(↑)");
timerInterval.Start();
}
else
MessageBox.Show("Left:
Arrow(←)\n\nRight:
Arrow((→)\n\nDown:
Arrow(↓)\n\nRotate:
Arrow(↑)");
}
//菜单栏中的version选项
privatevoidpicBoxMainField_Click(objectsender,EventArgse)
{
//picBoxMainField.Focus();
}
//focus
privatevoidpicBoxMainField_Paint(objectsender,PaintEventArgse)
{
//若没有此句,键盘焦点不能移到picBoxMainField中
picBoxMainField.Focus();
}
privatevoidlabeLevelVisual_Click(objectsender,EventArgse)
{
}
privatevoidlabScoreVisual_Click(objectsender,EventArgse)
{
}
//主界面中的Pause按钮
privatevoidbtnPause_Click(objectsender,EventArgse)
{
//按钮btnPause点击Pause后显示Start
if(btnPause.Text=="Pause")
{
timerInterval.Stop();
btnPause.Text="Start";
menuItemPause.Enabled=false;
menuItemStart.Enabled=true;
}
//按钮btnPause点击Start后显示Pause
else
if(btnPause.Text=="Start")
{
timerInterval.Start();
btnPause.Text="Pause";
menuItemPause.Enabled=true;
menuItemStart.Enabled=false;
}
}
//主界面中的NewGame按钮
privatevoidbtnNewGame_Click(objectsender,EventArgse)
{
NewGame();
}
//主界面中的Exit按钮
privatevoidbtnExit_Click(objectsender,EventArgse)
{
this.Close();
Application.Exit();
}
//Null
privatevoidForm1_Load(objectsender,EventArgse)
{
}
//Null
privatevoidForm1_KeyDown(objectsender,KeyEventArgse)
{
}
//显示newGame,这里是必须的
privatevoidForm1_Shown(objectsender,EventArgse)
{
NewGame();
}
//新游戏
privatevoidNewGame()
{
mainField=newint[row,line];//申请一个新的数组,存储整个界面方块信息
for(inti=0;i{
for(intj=0;j{
mainField[i,j]=0;
}
}
level=1;//游戏下落速度等级
score=0;//消去行数
timerInterval.Interval=500/level;//时间间隔随着等级增加而减少
labeLevelVisual.Text=level.ToString();//将等级显示在label上
labScoreVisual.Text=score.ToString();//将分数显示再label上
menuItemNew.Enabled=false;//菜单按钮newgame不能点击
menuItemPause.Enabled=true;//菜单按钮Pause可以点击
btnPause.Text="Pause";
btnPause.Enabled=true;//主界面按钮pause可以点击
timerInterval.Start();//计时器开始计时
this.Refresh();//刷新界面
currentBlock=newBlock();
currentBlock.MoveToCenterScreen();//为了美观,将方块出现的位置移动到中间
do
{
nextBlock=newBlock();
}while(nextBlock.Type==currentBlock.Type);//防止主界面中与副界面中出现的block相同
//先后绘制副主界面中的block
nextBlock.DrawBlock(picBoxSubField.CreateGraphics());
currentBlock.DrawBlock(picBoxMainField.CreateGraphics());
}
5.3游戏图形界面
一共七个图形
图5.3.1
图形部分设计代码(此类代码太多,文档中只列举其中一个)
privateclassBlock
{
privateBrick[,]Shape;
privatePointleft;
privatePointright;
privatePointtop;
privatePointbottom;
privateinttype;
publicintType
{
get{returntype;}
set{type=value;}
}
publicBlock()
{
Shape=newBrick[4,4];
for(inti=0;i<4;i++)
{
for(intj=0;j<4;j++)
{
Shape[i,j]=newBrick();
}
}
RandomRandType=newRandom();
type=RandType.Next(1,20);
switch(type)
{
case1:
//■□□□
//■□□□
//■□□□
//■□□□
Shape[0,0].X=0;
Shape[0,0].Y=0;
for(inti=0;i<4;i++)//
for(intj=0;j<4;j++)//
{
Shape[i,j].X=Shape[0,0].X+j;
Shape[i,j].Y=Shape[0,0].Y+i;
}
Shape[0,0].Filled=true;
Shape[1,0].Filled=true;
Shape[2,0].Filled=true;
Shape[3,0].Filled=true;
left.X=Shape[0,0].X;
left.Y=Shape[0,0].Y;
right.X=Shape[0,0].X;
right.Y=Shape[0,0].Y;
bottom.X=Shape[3,0].X;
bottom.Y=Shape[3,0].Y;
break;
5.4图形的移动与消行
移动方面代码示例:
//判断是否能向下移动
publicboolCanMoveDown()
{
boolcanDown=true;
if(bottom.Y>=19)
canDown=false;
if(bottom.Y<19)
{
for(inti=3;i>=0;i--)
{
for(intj=3;j>=0;j--)
{
if(Shape[i,j].Filled==true)
{
if(mainField[Shape[i,j].Y+1,Shape[i,j].X]==1)
canDown=false;
}
}
}
}
returncanDown;
}
消行方面代码示例:
privatevoidClearLine()
{
intlines=0;//同时消失的行数
intbricks;//同一行中的砖块brick数
for(inti=row-1;i>=0;i--)
{
bricks=0;
for(intj=line-1;j>=0;j--)
{
if(mainField[i,j]==1)
bricks++;
}
if(bricks==line)//如果同一行中的砖块brick个数达到了行数line,即该行满行
{
lines++;
for(intj=line-1;j>=0;j--)
{
mainField[i,j]=0;//将该行全部赋值为0,即消除该行
}
for(intm=i;m>0;m--)
{
for(intj=line-1;j>=0;j--)
{
mainField[m,j]=mainField[m-1,j];//将该行以上各行,均向下一行移动一行,这里用赋值完成
}
}
i++;//检查下一行
}
}
5.5得分的实现
if(lines==1)//如果同时消除1行,得1分
score+=1;
if(lines==2)//如果同时消除2行,得3分
score+=3;
if(lines==3)//如果同时消除3行,得5分
score+=5;
if(lines==4)//如果同时消除4行,得10分
score+=10;
labScoreVisual.Text=score.ToString();//主界面label显示分数score
if(score>20&&level==1)//score大于20分,进去第二个level
{
level++;
timerInterval.Interval=500/level;
labeLevelVisual.Text=level.ToString();
}
if(score>35&&level==2)//score大于35分,进入第三个level
{
level++;
timerInterval.Interval=500/level;
labeLevelVisual.Text=level.ToString();
}
}
6.总结
这次C#实训是我人生中最大的收获,这次实训,让我受益匪浅。
经过一周多的实训,我学到了很多知识,这为我接下来的学习做好铺垫。
在这一周里我通过问老师问同学,逐步完成了俄罗斯方块的设计。
现在我在一步一步的学习,制作出了俄罗斯方块,心中有一种自豪感。
这是我这一周来得到的成果。
俄罗斯方块的制作的完成,让我学到了很多。
在这个实训中我在编写代码的时候常常出错,经过同学的指教,才有了现在程序的正常运行。
在编代码的过程中我遇到了很多小麻烦,有些小问题弄得我焦皮烂愕。
实训中,有同学帮我把我的代码一遍遍的看了一下,帮我指出好多错误。
在这之后我也仔细认真的查过一边,并把一些代码记住,增加了自己的知识。
现在才感觉自己原来也是能做好的。
在实训中我遇到很多问题:
比如代码忘记了或者有些代码不认识。
我都会去翻书,或者去问同学。
在有些属性我不会用现在通过自己的摸索和同学的指教,我了解了很多、增加了我的知识。
在编程中经常会遇到崩溃的问题,这些我都重新弄了一下。
增加了对代码的熟悉度这次实训让我受益匪浅,我学到了很多知识。
这次实训让我学会了在以后的编程中要更加仔细更加认真
7.参考资料
《VisualC#2005程序设计教程》机械工业出版社
《VisualC#时尚编程百例》机械工业出版社
XX百科,
豆丁文档,
WelcomeTo
Download!
!
!
欢迎您的下载,资料仅供参考!
|