俄罗斯方块实验报告.docx

上传人:b****6 文档编号:5286300 上传时间:2022-12-14 格式:DOCX 页数:34 大小:26.93KB
下载 相关 举报
俄罗斯方块实验报告.docx_第1页
第1页 / 共34页
俄罗斯方块实验报告.docx_第2页
第2页 / 共34页
俄罗斯方块实验报告.docx_第3页
第3页 / 共34页
俄罗斯方块实验报告.docx_第4页
第4页 / 共34页
俄罗斯方块实验报告.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

俄罗斯方块实验报告.docx

《俄罗斯方块实验报告.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块实验报告.docx(34页珍藏版)》请在冰豆网上搜索。

俄罗斯方块实验报告.docx

俄罗斯方块实验报告

 

程序设计实践报告

(2012/2013 学年 第 2 学期)

 

题目:

俄罗斯方块游戏设计

 

专业

学生姓名

班级学号

指导教师

指导单位软件工程系

日期2013.03.27

 

-

成绩评定参考标准:

程序设计实践环节评分为五级制,即:

优秀、良好、中等、及格、不及格。

根据程序设计实践过程中学生以下表现评定:

学习态度是否端正、实验课前准备是否充分、是否实现课题要求的功

能、算法设计是否合理、程序设计语言使用是否熟练、用户界面设计是否

科学、程序设计实践报告完成情况(包括:

内容是否详实、文字表达是否

流畅、格式是否符合规范、程序注释是否具体)、答辩表现、考勤等。

教师签名:

2013 年 3 月 27 日

简短评语

评分等级

-

 

俄罗斯方块游戏设计

一、 课题内容和要求

本程序的主要任务就是编写简单的俄罗斯方块游戏,要求设计比较美观和健全

的游戏界面,可以实现方块预览、方块的控制、显示更新、分数更新以及帮助等基

本功能,减少程序本身的错误,增强游戏的可操作性。

程序的设计将结合一些有关 C 语言图形界面设计的内容,该部分是之前没有接

触过的,要求利用这次机会,比较简约地了解相关内容及其简单应用。

本程序的实现是选用 Windows XP/7 操作系统以及Microsoft Visual Studio

2008 C++为编译器,用 C 语言完成程序设计的实践。

使用 Win32 控制台应用程序,

最终在 DOS 界面下形成程序的主界面。

 

二、概要设计

struct//此结构体数表是打印各个方块的依据

{//是该程序设计的灵魂

int vary_x[4];

int vary_y[4];

} vary[]={

{{0, 2, 4, 6},{0, 0, 0, 0}},{{0, 0, 0, 0},{0,-1,-2,-3}},

{{0, 2, 2, 0},{0, 0,-1,-1}},{{0,-2,-2,-4},{0 ,0,-1,-1}},

{{0, 0, 2, 2},{0,-1,-1,-2}},{{0, 2, 2, 4},{0, 0,-1,-1}},

{{0, 0,-2,-2},{0,-1,-1,-2}},{{0, 0, 2, 4},{0,-1, 0, 0}},

{{0, 0, 0, 2},{0,-1,-2,-2}},{{0, 0,-2,-4},{0,-1,-1,-1}},

{{0, 2, 2, 2},{0, 0,-1,-2}},{{0, 2, 4, 4},{0, 0, 0,-1}},

{{0,-2,-2,-2},{0, 0,-1,-2}},{{0, 0, 2, 4},{0,-1,-1,-1}},

{{0, 0, 0,-2},{0,-1,-2,-2}},{{0 ,2, 4, 2},{0, 0, 0,-1}},

{{0, 0, 2, 0},{0,-1,-1,-2}},{{0,-2, 0, 2},{0,-1,-1,-1}},

{{0, 0,-2, 0},{0,-1,-1,-2}},

};

本程序中关于方块的颜色、运动的速度都采用的数组常量的形式,数组的编号分别

对应方块形状的编号,这样就使得“方块形状——方块颜色——运动速度”一一对应起

来,更直观和方便地实现动态管理。

const int col[]={11,15,12,12,10,10,9};//控制方块的颜色

const int speed[]={0,12,9,6,3,1};//控制方块的下落速度

const int number[]={0,2,3,5,7,11,15};//对应方块的类型编号

本程序的主体部分是由多个函数的循环多层调用来实现的,主要由以下的九个函数

构成:

-

 

① void PrintNext ( int pkind)

//该函数控制“下一个图形预览”中的方块样式,是整个程序的“引导者”、“开拓者”,

将引导程序的动态实现,将决定着下面几个函数的调用

② void StraightFall (int depth)

//该函数控制方块的降落,是在整个程序中发挥着至关重要的作用,是整个动态过程的

“纽带”将具体分功能的实现连串起来。

③void ChoiceDirection (int *prev_count)

//该函数实现键盘对小方块的控制,在小方块降落的过程中要时刻“监视”,因此,在

②函数中,每当一些变量发生变化时,即要调用该函数

④ void Revolve(int **prev_count)

//该函数控制方块的旋转。

该函数必须依附于③,即每次有键盘的按动时,都要检验是

否按了“↑”如果按了,立即执行该函数,实行方块的翻转

⑤void LevelMove()

//该函数控制方块的移动方向。

该函数类似于第四个函数,也是依附于③

⑥ void GetDepth(int *pdepth)

//该函数可以得到小方块已累积的高度,从而判断小方块是否已经落下。

该函数是一个

在多处都需要调用的函数

⑦void CheckBoundary()

//该函数可以控制、防止方块越过边界。

一旦可能越过边界,则之前的方向控制无效,

在方块左右移动、变化形状时都需要调用该函数

⑧void CheckFull(int *pscore)

//检验是否有一行完全被覆盖,若有一行全部被排满的,即刻整体下移。

在②函数的最

后,立刻调用该函数

⑨ void GameOver()

//即当 depth为 0 时,游戏结束,显示动态结束画面。

在②函数的最开始,立刻调用该

函数

 

-

 

程序流程图大致如下:

 

初始化界面

 

在“下一个图新预览”

内产生随即类型的方块

 

在方块累积主界面产

生方块

 

判断depth是否为0

 

判断是否触动按键

 

 

判断触碰了何种按

 

根据按键进行相

应的操作

 

判断游戏是否结束

判断并防止方块

运动越界

 

继续降落直至

触底判断并进行消行操作

 

说明:

该程序的流程图略显复杂,但其实质,依旧是顺序、选择、循环的使用,唯一复

杂的就是循环的主体不再是简单的程序语句而是比较复杂的函数,这样就会使得程序的

-

 

结构比较冗杂,但如果把流程图画出来,就会清晰地看到问题依旧是很简单。

 

四、关键源码

for(i=0;i<4;i++)

{

gotoxy(x+vary[pkind].vary_x[i],y+vary[pkind].vary_y[i]);

puts("▆");

}//该循环是用来依据上述数表打印各种不同的小方块,是本程序中最基本的语句块

void GameOver()//该函数是用来实现游戏结束后的动画效果

{

color(391);

for(int i=31;i>=0;i--)//用两层循环来实现主界面方块的打印

for(int j=0;j<17;j++)

{

gotoxy(36-j*2,3+i);

puts("▆");

Sleep(5);//延时函数的调用,使得最终的程序界面更有动感

}

color(back);

for(int j=0;j<31;j++)

for(int i=0;i<17;i++)

{

board[i][j].having=0;

gotoxy(4+2*i,j+3);

puts("▆");

Sleep(5);

}

}

void Revolve(int **prev_count)//控制方块的旋转,该函数是整个程序中最难的一部分代码

{

int i;

before.x=current.x;

before.y=current.y;

(**prev_count)++;

(**prev_count)%=connection[pri_kind].sum;

current.x=current.x+connection[pri_kind].connection_x[**prev_count];

current.y=current.y+connection[pri_kind].connection_y[**prev_count];

CheckBoundary();//调用检验边界函数,防止方块在旋转过程中越出程序界面

for(i=0;i<4;i++)

-

 

{

int m=(current.x-4+vary[number[pri_kind]+**prev_count].vary_x[i])/2;

int n=current.y+vary[number[pri_kind]+**prev_count].vary_y[i]-3;

if(board[m][n].having||m>16||m<0||n>31)

{

current.x=current.x-connection[pri_kind].connection_x[**prev_count];

current.y=current.y-connection[pri_kind].connection_y[**prev_count];

revolve=0;

(**prev_count)--;

before.x=current.x;

before.y=current.y;

return ;

}

}

color(back);//用背景色把旋转前的方块覆盖

for(i=0;i<4;i++)

{

if(before.y+vary[kind].vary_y[i]>2)

{

gotoxy(before.x+vary[kind].vary_x[i],before.y+vary[kind].vary_y[i]);

puts(" ");

}

}

kind=number[pri_kind]+**prev_count;

color(col[pri_kind]);//打印旋转后的新的方块

for(i=0;i<4;i++)

{

if(current.y+vary[kind].vary_y[i]>2)

{

gotoxy(current.x+vary[kind].vary_x[i],current.y+vary[kind].vary_y[i]);

puts("▆");

}

}

Sleep(speed[rank]);//根据等级来决定旋转、下落的速度

before.x=current.x;

before.y=current.y;

}

int main()//主函数是将一切子函数连串在一起的工具

{

srand((unsigned long)time(0));

gotoxy(5,5);

printf("一切准备就绪,游戏是否开始?

\n");

gotoxy(4,6);

printf("开始游戏请按 S 键,否则按任意其他键退出。

\n");

-

 

char c;

c=getchar();

if (c!

='S') exit(0);

system("CLS");

system("color 24");//设置背景颜色

int score=0;//检验文件是否能够成功打开

FILE *fp=fopen("C:

\\els.txt","r");

if(fp==NULL)

{

fp=fopen("C:

\\els.txt","w");

fprintf (fp,"%d",score);

fclose(fp);

}

PrintGarphy();//打印程序的边界和基本框架以及其中的文字

kind=rand()%7;//随机函数来随机确定方块的形状

int depth;

while

(1)//是一个无限循环,不断地重复着游戏的过程

{

int pkind=rand()%7;

PrintNext(pkind);

current.x=20;//方块初始出现的位置

current.y=2;

GetDepth(&depth);

if(depth==0)

{

GameOver();//当剩余的高度为 0 时,游戏结束

score=0;

rank=1;

}

pri_kind=kind;

if(kind==6) kind=15,current.x-=2;

else if(kind==5) kind=11;

else if(kind==4) kind=7;

else if(kind==3) kind=5;

else if(kind==2) kind=3,current.x+=2;

else if(kind==1) kind=2;

else kind=0,current.x-=2;

StraightFall(depth);//调用方块下落函数

for(int i=0;i<4;i++)

{

int m=(current.x-4+vary[kind].vary_x[i])/2;

int n=current.y-3+vary[kind].vary_y[i];

board[m][n].having=1;

board[m][n].color=col[pri_kind];

}

-

 

CheckFull(&score);//检验是否有满行的出现,若有,整体下呀,并加分

kind=pkind;

}

return 0;

}

五、测试数据及其结果分析

 

程序正式运行前所给的提示信息

 

这是程序主界面,由 PrintGarphy() 打印生成

 

-

 

程序主界面

 

运行过程中的程序界面

 

-

 

这是游戏结束时,动态界面的一瞬间截图

 

-

 

六、程序设计实践中的关键技术难题以及解决办法

【问题 1】在左右方向改变方块的位置时,若一直按住左键或右键,会出现方块部分或整

体越过程序界面的现象。

【分析】在程序中层已经定义和调用了函数 void Getdepth()用来计算已经累计的高度,

并由 depth 的值是否为 0 来判断是否游戏结束,是否方块已经降落。

因此,在程序中还应当定义另一个函数,用来判断是否方块越界,并在其变换和左

右移动时调用,以防止方块的越界。

【解决方法】在主程序中定义一个新的函数 void CheckBoundary(),其定义如下:

void CheckBoundary()

{

int i,n,m;

for(i=0;i<4;i++)

{

m=current.x+vary[kind].vary_x[i];

if(m<4||m>36)

{

current.x+=(m<4?

2:

-2);

i=0;

}

}

for(i=0;i<4;i++)

{

m=(current.x+vary[kind].vary_x[i]-4)/2;

n=current.y+vary[kind].vary_y[i]-3;

if(n<0||n>31||board[m][n].having)

{

if(level==1)

current.x+=2;

else if(level==2)

current.x-=2;

level=0;

break;

}

}

-

 

【问题2】在程序的调用中,发现程序每一次运行,“最高分”都会从0开始记。

即使我把

HighScore 设为全局变量,依旧是出现该问题。

【分析】程序的每一次运行,都会把每一个变量初始化。

尽管全局变量的作用域是从变

量定一开始一直到程序结束,然而,依旧不是“永久”,随着程序的结束而覆灭。

因而,

解决的办法就是,及时的把最高分写到计算机的文件中,来求得“永久”的保存。

【解决方法】

在程序中添加以下代码,一旦有新的最高分生成,则立刻写入文件C:

\\els.txt.

FILE *fp=fopen("C:

\\els.txt","r")

fscanf (fp,"%d",&t);

fclose(fp);

if(*pscore>t)

{

fp=fopen("C:

\\els.txt","w");

fprintf (fp,"%d",*pscore);

fclose(fp);

color(43);

gotoxy(51,16);

printf("%d",*pscore);

}

fclose(fp);

 

七、总结与展望

两周的编程实践,对于自身编程水平是个不小的提高。

实践是认识的来源、实践是

认识发展的动力,第一次接触实践课,让我深刻感受到了实践出真知的道理。

因此,在

以后的学习中,要树立实践的意识,提高把理论知识上升为实践的能力。

做成事情的前提是有一个合理可行的规划。

在本次程序设计实践的开始阶段,由于

编译器的选择问题(即 Visual C 和 Turbo C),项目几乎停滞不前,导致许多时间白白浪

费。

因此在以后的实践中,要在任务正式开展之前,就要做好充分的规划,避免手忙脚

乱。

适当的借鉴和对案例的充分分析加之对书本、互联网等工具的充分使用,才能把一

项比较庞大的工程做好。

在这次的程序设计中,我在互联网上找到了至少 30 个有关俄罗

斯方块的例子,其中能够无差错运行的少之又少。

本人花费了很大的功夫仔细地研究了

那六七个案例,体悟它们程序实现的方法,找到之间的区别和相同之处。

在阅读每一个

程序时,多多少少都会有不完全理解甚至是根本看不懂的地方,这个时候,书本网络就

-

 

是一个极好的工具。

在两周的时间里,除了思考和面对电脑,剩余的时间几乎就在图书

馆里找资料,在追求知识的过程中,也有了许多新的发现。

独立的思考是一切成功的基础。

把一切的感知和灵感都要归咎与自己的思考。

每一

个案例的分析都是我独立思考的结果,以后的学习生活中都要善于思考、勤于思考。

分部编写各个函数,并对其逐一进行测试,化大为小,是本次实践的一大收获,是

编写较复杂程序的有效方法。

这样有利于条理的清晰,避免错误。

合作与交流是成功的捷径。

与同课题的同学合作甚至是与不同课题同学的交流,都

会让我产生思想的火花,在困惑自己许久的问题上带来突破。

在程序中,本人很想再编写一个计时器,用来计量游戏已经运行的时间,几经尝试

都没有成功。

初步猜想,可能需要多线程的控制,下一步在这个问题上力求有所突破。

 

-

 

源代码:

/*

* Copyright (C) 2013,ZhangXu,Nanjing University of Posts and Telecommunications

* All rights reserved.

* 当前版本:

1.2.1

* 作者:

ZhangXu

* 完成日期:

2013 年 3 月 29 日

*/

 

#include 

#include 

#include 

#include 

const int back=34;

const int col[]={11,15,12,12,10,10,9};//用数组记录不同方块的颜色

const int speed[]={0,12,9,6,3,1};//用数组记录不同的降落速度

const int number[]={0,2,3,5,7,11,15};

int kind;

int pri_kind;

int rank=1;//等级状态标记,由此确定下落的速

int revolve=0;

int level=0;

struct

{

-

 

int x;

int y;

}current,before;

struct

{

int x;

int y;

int color;

bool having;

}board[17][32];

struct

{

int vary_x[4];

int vary_y[4];

} vary[]={

{{0, 2, 4, 6},{0, 0, 0, 0}},{{0, 0, 0, 0},{0,-1,-2,-3}},

{{0, 2, 2, 0},{0, 0,-1,-1}},{{0,-2,-2,-4},{0 ,0,-1,-1}},

{{0, 0, 2, 2},{0,-1,-1,-2}},{{0, 2, 2, 4},{0, 0,-1,-1}},

{{0, 0,-2,-2},{0,-1,-1,-2}},{{0, 0, 2, 4},{0,-1, 0, 0}},

{{0, 0, 0, 2},{0,-1,-2,-2}},{{0, 0,-2,-4},{0,-1,-1,-1}},

{{0, 2, 2, 2},{0, 0,-1,-2}},{{0, 2, 4, 4},{0, 0, 0,-1}},

{{0,-2,-2,-2},{0, 0,-1,-2}},{{0, 0, 2, 4},{0,-1,-1,-1}},

{{0, 0, 0,-2},{0,-1,-2,-2}},{{0 ,2, 4, 2},{0, 0, 0,-1}},

{{0, 0, 2, 0},{0,-1,-1,-2}},{{0,-2, 0, 2},{0,-1,-1,-1}},

{{0, 0,-2, 0},{0,-1,-1,-2}},

};

struct

{

int sum;

int connection_x[5];

-

 

int connection_y[5];

}connection[]={

{2,{-2,2},{0,1}},

{1,{0},{0}},

{2,{2,-2},{0,0}},

{2,{-2,2},{0,0}},

{4,{-2,0,4,-2},{0,0,-1,1}},

{4,{-4,2,-2,4},{0,0,-1,1}},

{4,{-2,2,0,0},{0,0,0,0}},

};

void gotoxy(int x, int y)//光标位置确定函数

{

COORD pos;

pos.X = x;

pos.Y = y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);

}

void color(int b)//该函数的调用可以决定输出内容的颜

{

HANDLE hConsole = GetStdHandle((STD_OUTPUT_HANDLE)) ;

SetConsoleTextAttribute(hConsole, b) ;

}

void PrintGarphy()

{

color(1593);//初始化控制台窗口,获取窗口句柄,

设置边框颜色

int i,j;

gotoxy(2,2);//确定光标从第二行第二列开始,以

下开始打印边框

-

 

for(i=0;i<28;i++)

printf("▓");

gotoxy(2,35);

for(i=0;i<28;i++)

printf("▓");

for(i=0;i<33;i++)

{

gotoxy(2,3+i);

printf("▓");

}

for(i=0;i<33;i++)

{

gotoxy(38,3+i);

if(i==7||i==18)

printf("▓▓▓▓▓▓▓▓▓▓");

else

printf("▓");

}

for(i=0;i<33;i++)

{

gotoxy(56,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1