c语言俄罗斯方块游戏程序设计报告
- 格式:doc
- 大小:1005.50 KB
- 文档页数:33
俄罗斯方块程序设计原理1.用户界面设计:一个优秀的俄罗斯方块程序应具备直观、易用的用户界面。
程序设计师要注意设计游戏界面的布局、颜色和字体,以提供良好的用户体验。
此外,程序还应具备用户交互功能,包括使用方向键移动积木、旋转积木以及加速下落等操作。
2.游戏逻辑设计:俄罗斯方块的游戏逻辑决定了程序整体的运作方式。
最基本的逻辑是积木的生成和移动。
积木的生成是随机的,每个积木由四个方块组成,不同的积木可以通过旋转变换形状,程序需要实现生成和管理不同形状的积木。
积木的移动包括左右移动、旋转和加速下落等操作,程序应对用户的操作进行相应的处理。
3.游戏规则设计:俄罗斯方块游戏的规则是游戏的核心。
规则包括积木的下落、碰撞检测、行消除和计分等。
积木在游戏区域内以固定的速度下落,当积木下落到底部或者碰到其他积木时停止下落。
碰撞检测是判断积木是否和其他积木发生碰撞,程序需要实现相应的算法来检测碰撞并改变积木的状态。
行消除是指当积木填满一整行时,该行会被消除,上方的积木会下落填补空缺。
计分系统会根据消除的行数给予相应的分数奖励。
4.游戏状态管理:俄罗斯方块游戏涉及多种状态,包括游戏开始、游戏结束和游戏暂停等。
程序需要实现相应的状态管理,包括记录当前游戏状态、计时、显示得分等。
当游戏结束时,程序需要显示玩家的最终得分并提供重新开始的选项。
5.难度设计:俄罗斯方块游戏可以通过增加难度来增加游戏的挑战性。
难度可以通过下落速度的增加、计分规则的调整以及积木形状的改变来实现。
程序需要实现相应的难度逻辑,根据玩家的游戏水平和表现来动态调整游戏难度。
总结来说,俄罗斯方块程序设计涉及用户界面设计、游戏逻辑设计、游戏规则设计、游戏状态管理和难度设计等方面。
程序设计师需要综合考虑这些方面的要求,并结合相应的算法和数据结构来实现一个优秀的俄罗斯方块程序。
一个成功的俄罗斯方块程序应具备直观、易用的用户界面、流畅的游戏体验以及合理的难度和计分规则,给玩家带来愉悦的游戏体验。
南京邮电大学通达学院算法与数据结构设计报告( 2016/ 2017学年第二学期)专业软件工程嵌入式学号姓名学号姓名学号姓名学号姓名指导教师陈兴国指导单位计算机学院计算机科学与技术系日期2017-5-26俄罗斯方块一、课题内容实现俄罗斯方块游戏。
主要功能为游戏界面显示、上下左右键响应以及当前得分统计。
通过该课题全面熟悉数组、字符串等的使用。
掌握设计的基本方法及友好界面的设计。
课题要求:1、游戏界面显示:下落方块和方块堆、左右移动、旋转、删除行等特效以及得分。
2、动作选择:上下左右键对应于旋转、加速、左右移动的功能。
3、得分统计判断:判定能否消除行、并统计得分总数等。
扩展要求:1、用户数据管理。
二、算法设计与分析I、俄罗斯方块游戏需要解决的问题包括(1)、随机产生方块并自动下移(2)、用(3)、用键和Q退出,按space暂停II、俄罗斯方块游戏需要设计的功能函数包括(1)、声明俄罗斯方块的结构体(2)、函数原型声明(3)、制作游戏窗口(4)、制作俄罗斯方块(5)、判断是否可动(6)、随机产生俄罗斯方块类型序号(7)、判断是否满行并删除满行的俄罗斯方块(8)暂停,继续功能(9)新游戏创建(10)用户的创建,分数用户名的保存,查看分数Tetris类(主要类)该类包含m a i n方法,应为应用程序的主类。
该类用来创建游戏的用户界面,事件处理功能和menu餐单,用户信息的存储。
整个程序从该类的m a i n方法开始执行。
成员变量:String userName;构造方法:Tetris内部类:Members,TetrisblockTetrisblok类:用来设计游戏界面。
游戏界面显示在由Tetrisblok类创建的整个用户界面的中(Center)区,游戏的即时分数、方块的效果图及方的预览功能都在整个类里面实现。
用来封装俄罗斯小方块。
一个方块的属性是由方块1位置即x和y的坐标、颜色决定的。
成员变量private int blockType;Timer timer=null;private int turnState;private int x;private int y;private int i = 0;int j = 0;static int score = 0;int flag = 0;int delay=1000;开始的时候在障碍物的问题上总是出现数组越界错误2.俄罗斯方块的变形问题,不是顺时针变形,原来是方块数组的排序出现错误2.在添加事件的时候点击新游戏分数不刷新,后来在tetris类中的newgame中添加了score=0之后解决了问题4.在实现加速和减速的问题上,一开始speed控制的是在时间间隔不变的情况下,变化方块每次跳动的距离,发现比较麻烦后来改用在每次跳动距离不变的情况下,改变事件发生的间隔,间隔越短就越快,但是只能大于0并且小于15005.在点击暂停按钮之后然后点击新游戏会出现错误6.在内部类调用外部类的变量的时候出现错误;7.在程序刚开始运行的时候,弹出来的Input框,如果我没有进行任何处理的话,会报空指针异常虽然我在下面加上了如果username==null但是并没有运行,后来知道原来在if选项中我的(“”)||username==null写颠倒过来了导致。
俄罗斯⽅块-C代码声明:代码转⾃有兴趣的同学⼀起研习#include<stdio.h>#include<stdlib.h>#include<time.h>#include<windows.h>#include<conio.h>#define SPACE 32#define LEFT 75#define RIGHT 77#define DOWN 80#define ESC 27#define Wall 2#define Box 1#define Kong 0#define FACE_X 29#define FACE_Y 20 //界⾯尺⼨void gotoxy(int x,int y); //移动光标int color(int c); //颜⾊void hidden_cursor(); //隐藏光标void inter_face(); //初始化界⾯void init_dia(); //初始化⽅块信息void draw_dia(int base,int space_c,int x,int y); //覆盖⽅块void draw_kong(int base,int space_c,int x,int y); //画⽅块int pd(int n,int space_c,int x,int y); //判断是否到底void start_game(); //开始游戏int xc();//消除void read_file(); //读写最⾼记录void write_file(); //写最⾼纪录int grade=0;//当前分数int max=0;//最⾼记录int nn=0;struct Face{int data[FACE_X][FACE_Y+10]; //数值,为1是⽅块,为0是空格int color[FACE_X][FACE_Y+10]; //对应⽅块的颜⾊}face;typedef struct Diamonds{ int space[4][4]; //4*4矩阵,为1为⽅块,为0 为空}Dia;Dia dia[7][4]; //⼀维基础7个⽅块,⼆维表⽰旋转次数int main(){system("cls");system("title 俄罗斯⽅块");color(7);system("mode con cols=60 lines=30"); //窗⼝宽度⾼度hidden_cursor();srand(time(NULL));read_file();grade=0;inter_face();init_dia();nn=rand()%7;while(1){start_game();}return 0;}/////////////////////////////////////////////////void start_game(){ int n,ch,t=0,x=0,y=FACE_Y/2-2,i,j;int space_c=0;//旋转次数draw_kong(nn,space_c,4,FACE_Y+3);n=nn;nn=rand()%7; //随机⽣成下⼀块color(nn);draw_dia(nn,space_c,4,FACE_Y+3);while(1){color(n);draw_dia(n,space_c,x,y);//画出图形if(t==0)t=15000;while(--t){ if(kbhit()!=0)//有输⼊就跳出break;}if(t==0){if(pd(n,space_c,x+1,y)==1){ draw_kong(n,space_c,x,y);x++; //向下降落}else{for(i=0;i<4;i++){for(j=0;j<4;j++){if(dia[n][space_c].space[i][j]==1){face.data[x+i][y+j]=Box;face.color[x+i][y+j]=n;while(xc());}}}return;}}else{ch=getch();switch(ch) //移动{case LEFT: if(pd(n,space_c,x,y-1)==1) //判断是否可以移动{ draw_kong(n,space_c,x,y);y--;}break;case RIGHT: if(pd(n,space_c,x,y+1)==1){ draw_kong(n,space_c,x,y);y++;}break;case DOWN: if(pd(n,space_c,x+1,y)==1){ draw_kong(n,space_c,x,y);x++;}break;case SPACE: if(pd(n,(space_c+1)%4,x+1,y)==1){ draw_kong(n,space_c,x,y);space_c=(space_c+1)%4;}break;case ESC : system("cls");gotoxy(FACE_X/2,FACE_Y);printf("---游戏结束!---\n\n");gotoxy(FACE_X/2+2,FACE_Y); printf("---按任意键退出!---\n");getch();exit(0);break;case 'R':case 'r': main();exit(0);case 'S':case 's': while(1){ if(kbhit()!=0)//有输⼊就跳出break;}break;}}}}int xc(){int i,j,k,sum;for(i=FACE_X-2;i>4;i--){sum=0;for(j=1;j<FACE_Y-1;j++){sum+=face.data[i][j];}if(sum==0)break;if(sum==FACE_Y-2) //满⼀⾏,减掉{grade+=100;color(7);gotoxy(FACE_X-4,2*FACE_Y+2); printf("分数:%d",grade);for(j=1;j<FACE_Y-1;j++){face.data[i][j]=Kong;gotoxy(i,2*j);printf(" ");}for(j=i;j>1;j--){ sum=0;for(k=1;k<FACE_Y-1;k++){sum+=face.data[j-1][k]+face.data[j][k]; face.data[j][k]=face.data[j-1][k];if(face.data[j][k]==Kong){gotoxy(j,2*k);printf(" ");}else{gotoxy(j,2*k);color(face.color[j][k]);printf("■");}}if(sum==0)return 1;}}}for(i=1;i<FACE_Y-1;i++)if(face.data[1][i]==Box){char n;Sleep(2000); //延时system("cls");color(7);gotoxy(FACE_X/2-2,2*(FACE_Y/3));if(grade>max){printf("恭喜您打破记录,⽬前最⾼纪录为:%d",grade); write_file();}else if(grade==max)printf("与纪录持平,请突破你的极限!");elseprintf("请继续努⼒,你与最⾼记录只差:%d",max-grade); gotoxy(FACE_X/2,2*(FACE_Y/3));printf("GAME OVER!\n");do{gotoxy(FACE_X/2+2,2*(FACE_Y/3));printf("是否重新开始游戏(y/n): ");scanf("%c",&n);gotoxy(FACE_X/2+4,2*(FACE_Y/3));if(n!='n' && n!='N' && n!='y' && n!='Y')printf("输⼊错误,请重新输⼊!");elsebreak;}while(1);if(n=='n' || n=='N'){gotoxy(FACE_X/2+4,2*(FACE_Y/3));printf("按任意键退出游戏!");exit(0);}else if(n=='y' || n=='Y')main();}}return 0;}//////////////////////////////////////////////void read_file() //读取最⾼记录{FILE *fp;fp=fopen("俄罗斯⽅块记录.txt","r+");if(fp==NULL){fp=fopen("俄罗斯⽅块记录.txt","w+");fwrite(&max,sizeof(int),1,fp);}fseek(fp,0,0);fread(&max,sizeof(int),1,fp);fclose(fp);}void write_file() //保存最⾼记录{FILE *fp;fp=fopen("俄罗斯⽅块记录.txt","r+");fwrite(&grade,sizeof(int),1,fp);fclose(fp);}///////////////////////////////////////////////int pd(int n,int space_c,int x,int y) //判断是否到底{int i,j;for(i=0;i<4;i++)for(j=0;j<4;j++){if(dia[n][space_c].space[i][j]==0)continue;else if(face.data[x+i][y+j]==Wall || face.data[x+i][y+j]==Box) return 0;}}return 1;}void draw_kong(int base,int space_c,int x,int y){int i,j;for(i=0;i<4;i++){for(j=0;j<4;j++){gotoxy(x+i,2*(y+j));if(dia[base][space_c].space[i][j]==1)printf(" ");}}}void draw_dia(int base,int space_c,int x,int y){int i,j;for(i=0;i<4;i++){for(j=0;j<4;j++){gotoxy(x+i,2*(y+j));if(dia[base][space_c].space[i][j]==1)printf("■");}}}void init_dia(){int i,j,k,z;int tmp[4][4];for(i=0;i<3;i++)dia[0][0].space[1][i]=1;dia[0][0].space[2][1]=1; //⼟形for(i=1;i<4;i++)dia[1][0].space[i][1]=1;dia[1][0].space[1][2]=1; //L形--1for(i=1;i<4;i++)dia[2][0].space[i][2]=1;dia[2][0].space[1][1]=1; //L形--2for(i=0;i<2;i++){ dia[3][0].space[1][i]=1;dia[3][0].space[2][i+1]=1; //Z形--1dia[4][0].space[1][i+1]=1;dia[4][0].space[2][i]=1;//Z形--2dia[5][0].space[1][i+1]=1;dia[5][0].space[2][i+1]=1;//⽥字形}for(i=0;i<4;i++)dia[6][0].space[i][2]=1;//1形//////////////////////////////////基础7个形状for(i=0;i<7;i++){for(z=0;z<3;z++){for(j=0;j<4;j++){for(k=0;k<4;k++){tmp[j][k]=dia[i][z].space[j][k];}}for(j=0;j<4;j++){for(k=0;k<4;k++){dia[i][z+1].space[j][k]=tmp[4-k-1][j];}}}}///////////////////////////////////旋转后的21个形状}//////////////////////////////////////void inter_face()//界⾯{ int i,j;for(i=0;i<FACE_X;i++){ for(j=0;j<FACE_Y+10;j++){ if(j==0 || j==FACE_Y-1 || j==FACE_Y+9) { face.data[i][j]=Wall;gotoxy(i,2*j);printf("■");}else if(i==FACE_X-1){ face.data[i][j]=Box;gotoxy(i,2*j);printf("■");}elseface.data[i][j]=Kong;}}gotoxy(FACE_X-18,2*FACE_Y+2); printf("左移:←");gotoxy(FACE_X-16,2*FACE_Y+2); printf("右移:→");gotoxy(FACE_X-14,2*FACE_Y+2); printf("旋转:space");gotoxy(FACE_X-12,2*FACE_Y+2); printf("暂停: S");gotoxy(FACE_X-10,2*FACE_Y+2); printf("退出: ESC");gotoxy(FACE_X-8,2*FACE_Y+2);printf("重新开始:R");gotoxy(FACE_X-6,2*FACE_Y+2);printf("最⾼纪录:%d",max);gotoxy(FACE_X-4,2*FACE_Y+2);printf("分数:%d",grade);}//////////////////////////////////////////////////void gotoxy(int x,int y) //移动坐标{COORD coord;coord.X=y;coord.Y=x;SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );}//////////////////////////////////////////////////void hidden_cursor()//隐藏光标{HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO cci;GetConsoleCursorInfo(hOut,&cci);cci.bVisible=0;//赋1为显⽰,赋0为隐藏SetConsoleCursorInfo(hOut,&cci);}int color(int c){switch(c){case 0: c=9;break;case 1:case 2: c=12;break;case 3:case 4: c=14;break;case 5: c=10;break;case 6: c=13;break;default: c=7;break;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改⽂字颜⾊return 0;}。
邮电大学通达学院算法与数据结构设计报告(2016/ 2017学年第二学期)专业软件工程嵌入式学号姓名学号姓名学号姓名指导教师指导单位计算机学院计算机科学与技术系日期2017-5-26目录课题容---------------------------------------1算法设计与分析---------------------------------1 算法实现---------------------------------------9测试数据及结果分析----------------------------38 调试过程中的问题------------------------------40 总结------------------------------------------41俄罗斯方块一、课题容实现俄罗斯方块游戏。
主要功能为游戏界面显示、上下左右键响应以及当前得分统计。
通过该课题全面熟悉数组、字符串等的使用。
掌握设计的基本方法及友好界面的设计。
课题要求:1、游戏界面显示:下落方块和方块堆、左右移动、旋转、删除行等特效以及得分。
2、动作选择:上下左右键对应于旋转、加速、左右移动的功能。
3、得分统计判断:判定能否消除行、并统计得分总数等。
扩展要求:1、用户数据管理。
2、游戏玩法:由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。
这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。
没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。
基本规则1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。
2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。
俄罗斯方块c语言源代码俄罗斯方块游戏是一款非常受欢迎的游戏,使用C语言编写源代码实现其功能。
下面是俄罗斯方块游戏的C语言源代码:1. 创建窗口函数: // 创建窗口函数 void CreateWindow(int width, int height) { // 使用SDL库创建窗口 SDL_Init(SDL_INIT_EVERYTHING); SDL_Window *window = SDL_CreateWindow("Tetris",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,width, height, 0); // 设置刷新时间SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); }2. 创建游戏函数: // 创建游戏函数 void CreateGame() { // 设置随机数种子srand((unsigned int)time(NULL)); // 加载游戏资源 LoadResources(); // 初始化游戏数据InitGameData(); // 初始化游戏界面InitGameUI(); // 开始游戏循环 GameLoop(); // 清理游戏资源 CleanupGame(); }3. 绘图函数: // 绘图函数 void Draw(int x, inty, Color color) { // 使用SDL库在指定位置绘制指定颜色的矩形 SDL_Rect rect; rect.x = x;rect.y = y; rect.w = BLOCK_SIZE; rect.h = BLOCK_SIZE; SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);SDL_RenderFillRect(renderer, &rect); }。
北京理工大学珠海学院课程设计说明书题目:学院:专业班级:学号:学生姓名:指导教师:年月日北京理工大学珠海学院课程设计任务书2009 ~2010学年第一学期学生姓名:专业班级:指导教师:工作部门:计算机科学技术学院一、课程设计题目二、课程设计内容(含技术指标)1.2.3.三、进度安排1.2.3.四、基本要求1.2.3.课程负责人签名:年月日课程设计分工安排摘要该演示程序只需要一个玩家,游戏区域上方不断地出现预定义形状的方块,然后由玩家累积方块满一行后消去以获得分数。
本程序开始是用控制台实现的,然后用MFC封装,使游戏不再像在控制台中运行那样闪动,界面也更加好看。
该游戏还需要一些改进,就是玩家游戏达到一定分数够不能自动升级,再就是当游戏结束够就必须退出游戏重新来过,不能进行选择继续进行游戏。
关键词:左移右移加速移动直接落底刷新加分显示目录摘要 (I)第一章需求分析 (1)1.1功能: (1)1.2操作: (1)第二章总体设计 (2)2.1外部功能图 (2)2.2 主函数功能图 (2)2.3 整个游戏的流程图 (3)2.4 move()函数N-S图 (4)2.5 update( )的N-S图 (5)第三章详细设计与实现 (6)3.1俄罗斯方块的构造和储存 (6)3.2 方块的移动 (7)3.3方块的变形 (7)3.4 方块移动和变形中所做的一些判断 (8)3.5 显示方块 (10)3.6 图形的更新 (12)3.7 其他 (14)第四章测试 (15)4.1游戏中的界面 (15)4.2 消行前的界面 (15)4.3 消行后的界面 (16)4.4 游戏结束时的界面 (17)参考文献 (18)心得体会 (19)第一章需求分析1.1功能:(1)本游戏程序玩家人数应为一人;(2)游戏区域上方不断地出现预定义形状的方块,下坠方块可以通过旋转改变其显示形状,并且不断地往下坠,直到它接触到游戏区域底部或者其它之前已经累叠起的下坠方块。
#include <stdio.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <stdlib.h>#ifdef__cplusplus#define __CPPARGS ...#else#define __CPPARGS#endif#define MINBOXSIZE 15 /* 最小方块的尺寸*/#define BGCOLOR 7 /* 背景着色*/#define GX 200#define GY 10#define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_HOME 0x4700#define VK_END 0x4f00#define VK_SPACE 0x3920#define VK_ESC 0x011b#define VK_ENTER 0x1c0d/* 定义俄罗斯方块的方向(我定义他为4种)*/#define F_DONG 0#define F_NAN 1#define F_XI 2#define F_BEI 3#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/#define NEXTROW 12 /* 要出的下一个方块的横从标*/#define MAXROW 14 /* 游戏屏幕大小*/#define MAXCOL 20#define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/#define SCROW 60int gril[22][16]; /* 游戏屏幕坐标*/int col=1,row=7; /* 当前方块的横纵坐标*/int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6;int num=0; /*游戏分*/int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*//* 以下我用了一个3维数组来纪录方块的最初形状和方向*/int boxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/* 随机得到当前方块和下一个方块的形状和方向*/void boxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random(7);}/*初始化图形模试*/void init(int gdrive,int gmode){int errorcode;initgraph(&gdrive,&gmode,"e:\\tc");errorcode=graphresult();if(errorcode!=grOk){printf("error of: %s",grapherrormsg(errorcode));exit(1);}}/* 在图形模式下的清屏*/void cls(){setfillstyle(SOLID_FILL,0);setcolor(0);bar(0,0,640,480);}/*在图形模式下的高级清屏*/void clscr(int a,int b,int c,int d,int color){setfillstyle(SOLID_FILL,color);setcolor(color);bar(a,b,c,d);}/*最小方块的绘制*/void minbox(int asc,int bsc,int color,int bdcolor){int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color);if(color!=BGCOLOR){setcolor(bdcolor);line(a+1,b+1,a-1+MINBOXSIZE,b+1);line(a+1,b+1,a+1,b-1+MINBOXSIZE);line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); }}/*游戏中出现的文字*/void txt(int a,int b,char *txt,int font,int color){setcolor(color);settextstyle(0,0,font);outtextxy(a,b,txt);}/*windows 绘制*/void win(int a,int b,int c,int d,int bgcolor,int bordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/* 当前方块的绘制*/void funbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor); }/*下一个方块的绘制*/void nextfunbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor);}/*时间中断定义*/#define TIMER 0x1cint TimerCounter=0;void interrupt ( *oldhandler)(__CPPARGS);void interrupt newhandler(__CPPARGS){TimerCounter++;oldhandler();}void SetTimer(void interrupt (*IntProc)(__CPPARGS)){oldhandler=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*由于游戏的规则,消掉都有最小方块的一行*/void delcol(int a){int i,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR);gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0);}/*消掉所有都有最小方块的行*/ void delete(){int i,j,zero,delgx=0;char *nm="00000";for(i=1;i<21;i++){zero=0;for(j=1;j<15;j++)if(gril[j]==0)zero=1;if(zero==0){delcol(i);delgx++;}}num=num+delgx*delgx*10;dj=num/10000;sprintf(nm,"%d",num);clscr(456,173,500,200,4);txt(456,173,"Number:",1,15);txt(456,193,nm,1,15);}/*时间中断结束*/void KillTimer(){disable();setvect(TIMER,oldhandler); enable();}/* 测试当前方块是否可以向下落*/ int downok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i+1][row+j])k=0;return(k);/* 测试当前方块是否可以向左行*/int leftok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j-1])k=0;return(k);}/* 测试当前方块是否可以向右行*/int rightok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j+1])k=0;return(k);}/* 测试当前方块是否可以变形*/int upok(){int i,j,k=1,a[4][4];for(i=0;i<4;i++)for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx+1][i];for(i=3;i>=0;i--)for(j=3;j>=0;j--)if(a[j] && gril[col+i][row+j])k=0;return(k);}/*当前方块落下之后,给屏幕坐标作标记*/ void setgril(){int i,j,a[4][4];funbox(0,0,minboxcolor,0);for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j])gril[col+i][row+j]=1;col=1;row=7;}/*游戏结束*/void gameover(){int i,j;for(i=20;i>0;i--)for(j=1;j<15;j++)minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);txt(103,203,"Game Over",3,10);}/*按键的设置*/void call_key(int keyx){switch(keyx){case VK_DOWN: { /*下方向键,横坐标加一。
俄罗斯方块C语言代码#include#include#include#include#ifdef uuuucplusplus#define__cppargs...#else#定义_ucpargs#endif#defineminboxsize15/*最小方块的尺寸*/#definebgcolor7/*背景着色*/#定义200#定义10#definesjnum10000/*每当玩家打到一万分等级加一级*//*按键码*/#定义左0x4B00#定义右0x4D00#定义下0x5000#定义上0x4800#definevk_home0x4700#definevk_end0x4f00#definevk_space0x3920#definevk_esc0x011 b#definevk_enter0x1c0d/*定义俄罗斯方块的方向(我把它定义为4)*/#definef_uuu0#definef_uu1#definef_u2#definef_3#definenextcol20/*要出的下一个方块的纵坐标*/#definenextrow12/*要出的下一个方块的横从标*/#definemaxrow14/*游戏屏幕大小*/#definemaxcol20#definesccol100/*游戏屏幕大显示器上的相对位置*/#definescrow60intgril[22][16];/*游戏屏幕坐标*/intcol=1,row=7;/*当前方块的横纵坐标*/intboxfx=0,boxgs=0;/*当前庙宇块的形状和方向*/intnextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/intminboxcolor=6,nextminboxcolor=6;intnum=0;/*游戏分*/intdj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/*在游戏级别之下*//*我使用了一个三维组来记录盒子的初始形状和方向*/intboxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0 ,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1 ,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1 ,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0 ,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0 ,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1 ,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1 ,1,0,0,0,1,0,0,0,0,0,0}}};/*随机得到当前方块和下一个方块的形状和方向*/voidboxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;如果(nextminboxcolor==4 | | nextminboxcolor==7 | | nextminboxcolor==8)nextminboxcolor=9;nextboxfx=f_2;dong;nextboxgs=random(7);}/*初始化图形模试*/voidinit(intgdrive,intgmode){interrocode;initgraph(&gdrive,&gmode,\errorcode=graphresult();如果(错误代码!=grok){printf(\exit(1);}}/*图形模式下的屏幕清除*/void CLS(){setfillstyle(solid_fill,0);setcolor(0);巴(0,0640480);}/*在图形模式下的高级清屏*/voidclscr(inta,intb,intc,intd,intcolor){setfillstyle(solid_fill,color);setcolor(color);bar(a,b,c,d);}/*最小正方形的绘制*/voidminbox(intasc,intbsc,intcolor,intbdcolor){inta=0,b=0;a=sccol+asc;b=scrow+b sc;clscr(a+1、b+1、a-1+minboxsize、b-1+minboxsize、颜色);如果(color!=bgcolor){setcolor(bdcolor);line(a+1,b+1,a-1+minboxsize,b+1);线路(a+1、b+1、a+1、b-1+minboxsize);line(a-1+minboxsize,b+1,a-1+minboxsize,b-1+minboxsize);line(a+1,b-1+minboxsize,a-1+minboxsize,b-1+minboxsize);}}/*游戏中的文字*/voidtxt(inta,intb,char*txt,intfont,intcolor){setcolor(color);settextstyle(0,0,字体);outtextxy(a,b,txt);}/*windows绘制*/voidwin(inta,intb,intc,intd,intbgcolor,intbordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/*当前方块的绘制*/voidfunbox(inta,intb,intcolor,intbdcolor){inti,j;intboxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];对于(i=0;i<4;i++)对于(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*minboxsize,(i+col+b)*minboxsize,color,bdcolor);}/*下一个方块的绘制*/voidNextFunbX(inta,intb,intcolor,intbdcolor){inti,j;intboxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];对于(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*minboxsize,(i+b)*minboxsize,color,bdcolor);}/*时间中断定义*/#definetimer0x1cinttimercounter=0;voidinterrupt(*oldhandler)(__cppargs);voidinterruptnewhandler(__cppargs){timer counter++;oldhandler();}voidsettimer(voidinterrupt(*intproc)(__cppargs)){oldhandler=getvect(timer);dis able();setvect(定时器,intproc);启用();}/*由于游戏的规则,消掉都有最小方块的一行*/voiddelcol(inta){因蒂,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*minboxsize,i*minboxsize,bgcolor,bgcolor);gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*minboxsize,i*minboxsize,minboxcolor,0);}。
计算机工程学院课程设计说明书课程名称:______________________________________ 设计项目:______________________________________ 学生姓名:______________________________________ 学号:______________________________________ 专业:______________________________________ 班级:______________________________________ 指导教师:____________________________________________年______月一、任务与具体要求二、设计说明书包括的内容三、应完成的图纸四、评语及成绩指导教师(签字)_____________________年____月____日目录1.系统概述 (2)2.原有程序概况 (3)3.现在系统操作界面 (5)4.现在程序详细设计 (7)5.用户手册 (14)6.测试计划 (15)7.课程设计心得体会 (16)8.参考书籍及资料 (17)系统概述1.1现状分析在个人电脑日益普及的今天,一些有趣的桌面游戏已经成为人们在使用计算机进行工作学习之余休闲娱乐的首选,而俄罗斯方块游戏是人们最熟悉的小游戏之一,它以其趣味性强,易上手等诸多特点得到了大众认可,因此开发此游戏软件可满足人们的一些娱乐需求.此俄罗斯方块游戏可以为用户提供一个可在普通个人电脑上运行的,界面美观的,易于控制的俄罗斯方块游戏。
1。
2项目要求俄罗斯方块是一款适合大众的游戏软件,它适合不同年龄的人玩.本软件实现的基本功能如下:●游戏区:玩家可以在游戏区中堆积方块,并能够在游戏过程中随时了解得分情况和下一个将要出现方块的提示。
●游戏控制:玩家可以通过游戏控制功能来控制游戏开始,暂停,结束游戏,游戏难度的设置以及音效控制.●玩家游戏信息存储及删除:玩家的得分在前五名时,将会记录在排行榜上,同时可为玩家清空排行榜。
1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,}; /*方块模板*/int shape,dir,next_shape,next_dir;struct position{int x;int y;} now_position; /*纪录现在方块的位置*/int speed_level=1;int fall_to_land,be_lined; /*判断方块是否着地的*/ /*----------------------------------------*/void clscreen();void setxy(int x,int y);void display_back();void display_interface();void display_fk(int x,int y,int shape,int dir);void init();//int getkey();/*取键盘的扫描码*/void getinput();void m_sound(int freq,int time);void eras_fk(int x,int y,int shape,int dir);/*擦除方块*/void fk_down(bool quickly = false);bool is_illegal(int x,int y,int changed_dir);/*判断方块移动后坐标是否非法,非法1,合法0*/int get_random(int n); /*生成一个0----n-1的随机数*/void check_line(); /*检查是否有行可以消去,如果有就消去*/void game_over();/*----------------------------------*/int main(){int i;init();while (true){display_back();now_position.x=10;now_position.y=2;/*复原初始坐标*/be_lined=0; /*一个方块刚出现时没有成行*/shape=next_shape;dir=next_dir;next_shape=get_random(7);next_dir=get_random(4);eras_fk(55,5,shape,dir);/*擦去前一个方块*/display_fk(55,5,next_shape,next_dir);/*显示下一个方块*/display_fk(now_position.x,now_position.y,shape,dir);/*显示目前方块*/fall_to_land=0;while (!fall_to_land){for (i=15000-1500*speed_level;i>0;i--){getinput();}/*接受键盘输入*/fk_down(); /*方块自动下落*/}//m_sound(350,500); /*块落下的声音*/ check_line(); /*检查有没有可消去的行*/if (be_lined)m_sound(250,1000);elsem_sound(350,500);}return0;}/*------------------------------------*/void init(){int i,j;for (i=0;i<20;i++)for (j=0;j<10;j++)background[i][j]=0;/*背景数组赋初值0*/next_shape=(get_random(7)+5)/7;next_dir=(get_random(4)+2)/4;/*预先产生一个方块*/display_interface();/*画界面*/}void display_interface(){clscreen();setxy(40,5);printf("The Next: ");setxy(1,1);}/*-----------------------------------------*/void display_back()/*显示背景*/{int i,j;for (i=0;i<20;i++){for (j=0;j<10;j++){setxy(2*(j+1),i+2); /*数组下标到屏幕坐标的变换*/if (!background[i][j])/*背景数组中值为0*/printf(" ");elseprintf("[]");}}}/*---------------------------------------*/void display_fk(int x,int y,int shape,int dir)/*显示方块*/{int i,j;for (i=0;i<4;i++){for (j=0;j<4;j++){if (fang_kuai[shape][dir][i][j]){setxy((x+2*j),(y+i));/*结合现在方块的位置*/printf("[]");}}}}/*-----------------------------------*/void getinput(){if(GetAsyncKeyState(VK_LEFT)){if (!is_illegal(now_position.x-2,now_position.y,dir)){eras_fk(now_position.x,now_position.y,shape,dir);now_position.x=now_position.x-2;display_fk(now_position.x,now_position.y,shape,dir);Sleep(1000);}elsem_sound(440,500);/*如果没有遇阻,方块位置左移一格*/}else if(GetAsyncKeyState(VK_RIGHT)){if (!is_illegal(now_position.x+2,now_position.y,dir)){eras_fk(now_position.x,now_position.y,shape,dir);now_position.x=now_position.x+2;display_fk(now_position.x,now_position.y,shape,dir);Sleep(1000);}elsem_sound(440,500);/*如果没有遇阻,方块位置右移一格*/}else if(GetAsyncKeyState(VK_UP)){if (!is_illegal(now_position.x,now_position.y,(dir+1)%4)){eras_fk(now_position.x,now_position.y,shape,dir);dir=(dir+1)%4;display_fk(now_position.x,now_position.y,shape,dir);Sleep(1000);}}else if(GetAsyncKeyState(VK_DOWN)){fk_down(true);}else if(GetAsyncKeyState(VK_SPACE)){game_over();}}/*------------------------------------*/void m_sound(int freq,int time){Beep(freq,time);}/*--------------------------------*/void eras_fk(int x,int y,int shape,int dir)/*擦除方块*/{int i,j;for (i=0;i<4;i++){for (j=0;j<4;j++){if (fang_kuai[shape][dir][i][j]){setxy((x+2*j),(y+i));/*结合现在方块的位置*/printf(" ");}}}}/*----------------------------------------------------*/ void fk_down(bool quickly) /*方块下落*/{int i,j,x,y;if (!is_illegal(now_position.x,now_position.y+1,dir))/*下落没有阻碍*/{eras_fk(now_position.x,now_position.y,shape,dir);now_position.y=now_position.y+1;display_fk(now_position.x,now_position.y,shape,dir);if(quickly){Sleep(10);}else{Sleep(1000);}}else/*不可再下落了*/{/*方块并入背景*/x=now_position.x;y=now_position.y; /*x,y表示方便*/for (i=0;i<4;i++){for (j=0;j<4;j++){if (fang_kuai[shape][dir][i][j]==1) background[(y-2+i)][(x/2-1+j)]=1;}}fall_to_land=1; /*告诉主程序方块着地*/}}/*-----------------------------------------------------*/ bool is_illegal(int x,int y,int changed_dir){int i,j;bool illegal=false;/*先判断有没有出界,如果有x,y在界外并且此x,y处方块数组为1,就返回1*/for (i=0;i<4;i++)for (j=0;j<4;j++)if (fang_kuai[shape][changed_dir][i][j]==1&&((x+j*2)>21 || (x+j*2)<2 || (y+i)>21 || (y+i)<2))illegal=true;/*再判断是否有原方块阻碍*/if (!illegal){for (i=0;i<4;i++)for (j=0;j<4;j++)if (fang_kuai[shape][changed_dir][i][j]==1&&background[(y-2+i)][(x/2-1+j)]==1)illegal=true;/*有阻碍返回一*/}return illegal;}/*-----------------------------------------------------*/int get_random(int n){int x;Sleep(500);/*randomize();x=random(n);*/srand( (unsigned)time(NULL));x=rand()%n;return(x);}/*--------------------------------------------------------------*/void check_line() /*待修改*/{/*检查背景数组*/int i,j,k;int line,n;for (i=19;i>=0;i--){k=1; /*开始默认成行*/for (j=9;j>=0;j-- ){if (background[i][j]==0) /*不成行的条件*/k=0;}if (k==1) /*如果成行*/{be_lined=1; /*成行标志*/for (line=i;line>0;line--)for (n=9;n>=0;n--)background[line][n]=background[line-1][n];/*逐次下移一行*/i=i+1; /*把下一次待检的行重新设定*/}}}/*--------------------------------------------------------------*/void game_over(){clscreen();setxy(35,1);printf("GAME OVER");exit(0);}void clscreen(){system("cls");}void setxy(int x,int y){HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);COORD place;place.X = x;place.Y = y;SetConsoleCursorPosition(hConsole, place);}/* Colors defined for SetColor(int) */enum {BLACK = 0,DARK_BLUE = 1,DARK_GREEN = 2,TEAL = 3,DARK_RED = 4,DARK_PURPLE = 5,GOLD = 6,GREY = 7,DARK_WHITE = 8,BLUE = 9,GREEN = 10,CYAN = 11,RED = 12,PURPLE = 13,YELLOW = 14,WHITE = 15};void SetColor(const int foreground, const int background) {int Color = foreground + (background * 16);HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);}你把这段拿回去看哈吧,这是一个俄罗斯方块的程序,就是在控制台运行的,就是用你所说的纯数字和字符所运行,你现在只能在dos 下显示那些纯数字的东西,是因为你很多技术性的手法,你还不会,但你学习到一定程度后,你就会有所领悟,也不要太心急,当你练好内功后,修炼招数,应该会很快的!希望对你有帮助。
百度文库- 让每个人平等地提升自我C语言版俄罗斯方块项目详细设计说明书杰普物联网研发中心Briup IOT R&D Center文档类型:☐需求文档☐计划文档☑设计文档☐测试文档☐用户文档☐工程文档☐维护文档密级:☑公开资料☐内部资料☐保密资料☐机密资料版权声明上海杰普软件有限公司版权所有,保留一切权利。
未经本公司书面许可,任何单位和个人不得擅自摘抄、复制本文档的部分或全部,并以任何形式传播。
产品支持服务我们将不断改进我们的产品和用户手册,使其更完善、更便于使用,您的意见和建议对我们的工作非常重要,您可以用您喜欢的任何方式与我们联系。
我们的联系地址和电话是:公司地址:邮编:215300电话:传真:网址:文档修改/审批记录目录1简介 (6)1.1目的 (6)1.2范围 (6)1.3参考资料 (6)1.4术语定义及说明 (6)2系统详细设计 (7)2.1主流程 (7)2.2功能模块框图 (7)2.3非功能模块介绍 (7)3模块详细设计 (8)3.1游戏模块 (8)3.1.1功能概述 (8)3.1.2界面概述 (8)3.1.3类(结构)设计 (9)3.1.4关键逻辑与算法说明 (9)3.1.5访问的表或其他数据实体 (9)3.1.6调用外部接口说明 (9)3.1.7提供调用接口说明 (10)3.1.8模块内部使用的公共函数、包的说明 (10)3.1.9流程逻辑 (10)3.1.10尚未解决的问题 (11)3.2预览模块 (11)3.2.1功能概述 (11)3.2.2界面概述 (11)3.2.3类(结构)设计 (11)3.2.4关键逻辑与算法说明 (12)3.2.5访问的表或其他数据库实体 (12)3.2.6调用外部接口说明 (12)3.2.7提供调用接口说明 (12)3.2.8模块内部使用的公用函数/包等的说明 (12)3.2.9流程逻辑 (13)3.2.10尚未解决的问题 (13)3.3等级积分表模块 (13)3.3.1功能概述 (13)3.3.2界面概述 (13)3.3.3类设计 (14)3.3.4关键逻辑与算法说明 (14)3.3.5访问的表或其他数据实体 (14)3.3.6调用外部接口说明 (14)3.3.7提供调用接口说明 (14)3.3.8模块内部使用的公共函数、包的说明 (14)3.3.9流程逻辑 (14)3.3.10尚未解决的问题 (14)4限制条件 (14)5测试计划 (14)6附录: (14)1简介1.1 目的阐述C语言实现俄罗斯方块游戏的界面的功能和界面设计。
本科中期实习报告姓名:学号:专业:院系:指导教师:完成日期:2012 年12 月25 日制实习报告名称俄罗斯方块游戏的开发注: 本表与实习报告装订在一起。
俄罗斯方块游戏实习报告 实习时间2012年12月5日至 2009年12月18日 共 2 周 实习地点 实验楼4楼,信息学院实践教学中心机房指导教师 李秀娟 职称 讲师二级学院、系 信息学院 软件工程系 实习内容(后附实习报告)1.面向对象设计思想。
2.VC++集成开发环境、游戏软件中的多媒体处理。
3.游戏案例讲解。
指 导教师评 语及成绩成绩: 签字(盖章): 年 月 日系意见签字(盖章):年 月 日一、实习目的这次实习目的之一是为了让我们体会到自己在专业知识方面的欠缺和不足,意识到自己做为计算机软件工程专业的学生,要想在以后的职业中崭露头角,除了要有过硬的理论知识,健康的体魄外,还必须具备良好的心理素质,使自己在以后的途中无论经历什么样的困难,都立于不败之地。
实习的另一目的是让学生对自己这一年来的所学到计算机知识、所培养的能力以实践的方式来检验,培养自己主动学习知识、分析问题、解决问题的能力和团队合作精神与人协调处理事物的能力,这两点正是本次实训的根本目的。
二、实习内容(一)实习过程实习的过程大致可以分为两个阶段:第一阶段老师讲课及相关培训阶段;第二阶段:自行实践阶段。
第一阶段12月3日—12月7日:主要完成了专业老师对游戏的介绍,对程序设计基础知识相关培训。
第二阶段12月8日—12月15日:游戏项目的编码、测试与整合等。
(二)实习内容项目名称:俄罗斯方块游戏2.1 游戏简介随着信息技术的迅速发展,给人们带来了各种各样的信息和更多更新的娱乐。
其中游戏又最为常见和普遍。
所以我们实现了一个俄罗斯方块的小游戏,来对所学到的知识进行实践。
俄罗斯方块游戏属于经典小游戏,游戏规则简单,但又不乏趣味。
而计算的一大领域也是游戏,所以,成为游戏开发者,几乎是每个编程者的梦想。
#include<stdio.h>#include<stdlib.h>#include<dos.h>#include<graphics.h> /*系统提供的头文件*/#define TIMER 0x1c /*定义时钟中断的中断号*/#define VK_LEFT 0x4b00/*左移键*/#define VK_RIGHT 0x4d00/*右移键*/#define VK_DOWN 0x5000 /*加速键*/#define VK_UP 0x4800 /*变形键*/#define VK_SPACE 0x3920 /*变形键*/#define VK_END 0x4f00 /*暂停键*/#define VK_ESC 0x011b#define VK_ENTER 0x1c0d#define BSIZE 16 /*方块的边长是16个象素*/#define MAX_SHAPE 19 /*总共有19种各形态的方块*/#define BOARD_WIDTH 10 /*游戏面板的宽度,以方块的宽度为单位*/#define BOARD_HEIGHT 20/*游戏面板的高度,以方块的宽度为单位*/#define BGCOLOR BLACK /*背景色*/#define FORECOLOR WHITE /*前景色*/#define FALSE 0#define TRUE 1#define EMPTY 0#define FILLED 1#define BOARD_LEFT_X 10 /*游戏面板左上角的横坐标*/#define BOARD_LEFT_Y 5 /*游戏面板左上角的纵坐标*//*定义全局变量*/extern int Gameboard[BOARD_WIDTH+2][BOARD_HEIGHT+2];extern int nCurrent_block_index ; /*当前下落的方块的索引号*/ extern int nNext_block_index ; /*下一个方块的索引号*/extern int nSpeed, nScore; /*速度和得分*/extern int nSpeedUpScore; /*第一次要加速需达到的分数*/extern int bAccel, bOver;extern int nOriginX, nOriginY;/*某一形状的原点的绝对坐标*/ extern unsigned int TimerCounter; /* 计时变量,每秒钟增加18 */struct block{int arrXY[8];int nColor;int nNext;}; /*保存某一形状信息的结构体*/typedef struct block BLOCK;extern BLOCK arrayBlock[19];void interrupt newtimer(void);void SetTimer(void interrupt(*IntProc)(void));void KillTimer();void InitializeGraph();void InitializeGameboard() ;void DrawSquare(int x, int y);void DrawBlock(int BlockIndex, int sx, int sy,int color); int IsConflict(int BlockIndex, int x, int y);void HandleLeft(int BlockIndex,int *x, int *y);void HandleRight(int BlockIndex,int *x, int *y);void HandleUp(int *BlockIndex,int *x, int *y);int HandleDown(int BlockIndex,int *x, int *y);int IsLineFull(int y);void KillLine(int y);int KillLines(int y);int IsGameOver();int GameOver();void StartGame();void ProcessInGame();void game();void win();void help();void design();void show_win();void main(){win();menu();}void help(){clrscr();help();textcolor(WHITE);gotoxy(20,4);cprintf("\xDB\xDB\xDB\xDB\xB2 HELP ABOUT THE Game \xB2\xDB\xDB\xDB\xDB"); gotoxy(4,6);cprintf(" [ 1 ] - Metamorphose : Press the left key square moves left "); gotoxy(30,8);cprintf("Press the left key square move to the right");gotoxy(30,10);cprintf("Press down key square accelerate whereabouts");gotoxy(4,12);cprintf(" [ 2 ] - Speed up : Press the button oblong rotating ");gotoxy(4,14);cprintf(" [ 3 ] - Game Start : Press Enter to button to start the game"); gotoxy(4,16);cprintf(" [ 4 ] - Game Over : Press the ESC key to quit the game");gotoxy(30,18);cprintf("YOU WANT TO BE HELPFUL");gotoxy(6,23);printf("Press any key to go to the MAIN MENU ........");getche();}menu(){int x;do{{clrscr();design();textcolor(WHITE);cprintf("\xDB\xDB\xDB\xDB\xB2 Tetris Game \xB2\xDB\xDB\xDB\xDB");gotoxy(3,4);cprintf("--------------------------------------------------------------------------");gotoxy(35,5);cprintf("MAIN MENU");gotoxy(26,8);cprintf(" 1 - New Game ");gotoxy(26,9);cprintf(" 2 - Rank ");gotoxy(26,10);cprintf(" 3 - HELP ");gotoxy(26,11);cprintf(" 4 - The Game Explain ");gotoxy(26,12);cprintf(" 5 - EXIT ");x=toupper(getch());switch(x){case '1':game();break;case '2':cprintf("At present there is no ranking");break;case '3':help();break;case '4':cprintf("This game by LuWenJun,ChenLong,QiWei jointly compiled,Deficiencies still please forgive me");break;case '5':exit(0);break;default:clrscr();design();gotoxy(17,12);printf("\a\xDB\xB2 WRONG ENTRY : PRESS ANY KEY AND TRY AGAIN"); getche();}}}while(x!='5');return x;}void win(){int i,graphdriver,graphmode,size,page;char s1[30],s2[30];graphdriver=DETECT;initgraph(&graphdriver,&graphmode,"c:\\turboc2");cleardevice();setbkcolor(BLUE);setviewport(40,40,600,440,1);setfillstyle(1,2);setcolor(YELLOW);rectangle(0,0,560,400);floodfill(50,50,14);rectangle(20,20,540,380);setfillstyle(1,13);floodfill(21,300,14);setcolor(BLACK);settextstyle(1,0,6);outtextxy(100,60,"Welcom You");setviewport(100,200,540,380,0);setcolor(14);setfillstyle(1,12);rectangle(20,20,420,120);settextstyle(2,0,9);floodfill(21,100,14);sprintf(s1,"Let's our play Tetris Game!");setcolor(YELLOW);outtextxy(60,40,s1);sprintf(s2,"Press any key to play....");setcolor(1);settextstyle(4,0,3);outtextxy(110,80,s2);getch();closegraph();}void design(){int i;clrscr();textcolor(14);gotoxy(2,2);cprintf("\xC9");gotoxy(3,2);for(i=1;i<=74;i++)cprintf("\xCD");gotoxy(77,2);cprintf("\xBB");gotoxy(2,3);cprintf("\xBA");gotoxy(2,4);cprintf("\xBA");gotoxy(2,5);cprintf("\xBA");gotoxy(2,6);cprintf("\xBA");gotoxy(2,7);cprintf("\xBA");gotoxy(2,8);cprintf("\xB A");gotoxy(2,9);cprintf("\xBA");gotoxy(2,10);cprintf("\xBA");gotoxy(2,11);cprintf("\ xBA");gotoxy(2,12);cprintf("\xBA");gotoxy(2,13);cprintf("\xBA");gotoxy(2,14);cprintf("\xBA");gotoxy(2,15);cprintf(" \xBA");gotoxy(2,16);cprintf("\xBA");gotoxy(2,17);cprintf("\xBA");gotoxy(2,18);cprintf("\xBA");gotoxy(2,22);cprintf(" \xCC");gotoxy(2,19);cprintf("\xBA");gotoxy(2,20);cprintf("\xBA");gotoxy(2,21);cprintf(" \xBA");gotoxy(2,24);cprintf("\xC8");gotoxy(2,23);cprintf("\xBA");gotoxy(3,24);for(i=1;i<=74;i++)cprintf("\xCD");gotoxy(77,18);cprintf("\xBA");gotoxy(77,19);cprintf("\xBA");gotoxy(77,20);cprint f("\xBA");gotoxy(77,21);cprintf("\xBA");gotoxy(77,24);cprintf("\xBC");gotoxy(77,23);cprintf("\xBA");gotoxy(3,22);for(i=1;i<=74;i++)cprintf("\xCD");gotoxy(77,22);cprintf("\xB9");gotoxy(77,3);cprintf("\xBA");gotoxy(77,4);cprintf("\xBA");gotoxy(77,5);cprintf("\xBA");gotoxy(77,6);cprintf("\xBA");gotoxy(77,7);cprintf("\xBA");gotoxy(77,8);cprintf(" \xBA");gotoxy(77,9);cprintf("\xBA");gotoxy(77,10);cprintf("\xBA");gotoxy(77,11);cprintf ("\xBA");gotoxy(77,12);cprintf("\xBA");gotoxy(77,13);cprintf("\xBA");gotoxy(77,14);cprintf("\xBA");gotoxy(77,15);cprint f("\xBA");gotoxy(77,16);cprintf("\xBA");gotoxy(77,17);cprintf("\xBA");textcolor(RED);}void show_win(void){union REGS in, out;in.x.ax = 0x1;int86(0x33, &in, &out);}/*********************************************************** 函数原型:void InitializeGraph() * * 传入参数:无 ** 返回值:无 ** 函数功能:初始化进入图形模式***********************************************************/void InitializeGraph(){int gdriver = VGA, gmode=VGAHI, errorcode;/* 初始化图形模式*/initgraph(&gdriver, &gmode, "c:\\turboc2");/* 读取初始化结果 */errorcode = graphresult();if (errorcode != grOk) /* 错误发生 */{printf("Graphics error: %s\n", grapherrormsg(errorcode));printf("Press any key to halt:");getch();exit(1); /* 返回错误码 */}}/*********************************************************** 函数原型:void InitializeGameboard() ** 传入参数:无** 返回值:无** 函数功能:初始化游戏面板以及下一形状提示框、计分框和难度框 ***********************************************************/void InitializeGameboard(){/* 绘制游戏面板(即游戏区域)*/setfillstyle(SOLID_FILL,BGCOLOR);bar(BSIZE*BOARD_LEFT_X,BSIZE*BOARD_LEFT_Y,BSIZE*(BOARD_LEFT_X+BOARD_WIDTH),BSIZE*(BOARD_LEFT_Y+BOARD_HEIGHT));setcolor(WHITE);rectangle(BSIZE*BOARD_LEFT_X,BSIZE*BOARD_LEFT_Y,BSIZE*(BOARD_LEFT_X+BOARD_WIDTH),BSIZE*(BOARD_LEFT_Y+BOARD_HEIGHT));/*绘制下一形状提示框*/setcolor(BLUE);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(5+1), "next");setfillstyle(SOLID_FILL, BGCOLOR);bar(BSIZE*(24.5+2), BSIZE*6, BSIZE*(24.5+2+5), BSIZE*(6+5));setcolor(YELLOW);rectangle(BSIZE*(24.5+2), BSIZE*6, BSIZE*(24.5+2+5), BSIZE*(6+5));/*绘制速度框*/setcolor(BLUE);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(12+1), "level");setfillstyle(SOLID_FILL, BGCOLOR);bar(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1)); setcolor(RED);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(13+1), "0");/*绘制计分框*/setcolor(BLUE);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(19+1), "score");setfillstyle(SOLID_FILL, BGCOLOR);bar(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1)); setcolor(RED);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(20+1), "0");}int Gameboard[BOARD_WIDTH+2][BOARD_HEIGHT+2];int nCurrent_block_index;/* 当前下落的方块的索引号*/int nNext_block_index ; /*下一个方块的索引号*/int nSpeed, nScore; /*速度和得分*/int nSpeedUpScore = 1000; /*第一次要加速需达到的分数*/int bAccel, bOver;int nOriginX=5, nOriginY=1;/*某一形状的原点的绝对坐标*/ BLOCK arrayBlock[19]={/*x1,y1,x2,y2,x3,y3,x4,y4, color, next*/{ 0,-2, 0,-1, 0, 0, 1, 0, CYAN, 1}, /* */{-1, 0, 0, 0, 1,-1, 1, 0, CYAN, 2}, /* # */{ 0,-2, 1,-2, 1,-1, 1, 0, CYAN, 3}, /* # */{-1,-1,-1, 0, 0,-1, 1,-1, CYAN, 0}, /* ## */{ 0,-2, 0,-1, 0, 0, 1,-2,MAGENTA, 5}, /* */{-1,-1,-1, 0, 0, 0, 1, 0,MAGENTA, 6}, /* ## */{ 0, 0, 1,-2, 1,-1, 1, 0,MAGENTA, 7}, /* # */{-1,-1, 0,-1, 1,-1, 1, 0,MAGENTA, 4}, /* # */{-1, 0, 0,-1, 0, 0, 1, 0,YELLOW, 9}, /* */{-1,-1, 0,-2, 0,-1, 0, 0,YELLOW, 10}, /* */{-1,-1, 0,-1, 0, 0, 1,-1,YELLOW, 11}, /* # */{ 0,-2, 0,-1, 0, 0, 1,-1,YELLOW, 8}, /* ### */{-1, 0, 0,-1, 0, 0, 1,-1, BROWN, 13}, /* ## */{ 0,-2, 0,-1, 1,-1, 1, 0, BROWN, 12}, /* ## */{-1,-1, 0,-1, 0, 0, 1, 0, WHITE, 15}, /* ## */{ 0,-1, 0, 0, 1,-2, 1,-1, WHITE, 14}, /* ## */{ 0,-3, 0,-2, 0,-1, 0, 0, RED, 17},/* # */{-1, 0, 0, 0, 1, 0, 2, 0, RED, 16},/* # *//* # *//* # */{ 0,-1, 0, 0, 1,-1, 1, 0, BLUE, 18},/* ## *//* ## */};/*********************************************************** 函数原型:void StartGame () ** 传入参数:无** 返回值:无 ** 函数功能:游戏开始时调用的函数,其中绘制界面需调用函数 ** InitializeGameboard(), 接下来需初始化游戏面板的 ** 各个方块和一些全局变量的初值 ***********************************************************/void StartGame(){int i,j;/*设置游戏面板中每个方块的初始值*/for(j=0;j<=BOARD_HEIGHT;j++)for(i=0;i<BOARD_WIDTH+2;i++){if(i==0 || i==BOARD_WIDTH+1)Gameboard[i][j] = FILLED;elseGameboard[i][j] = EMPTY;}for(i=0;i<BOARD_WIDTH+2;i++)Gameboard[i][BOARD_HEIGHT+1] = FILLED;InitializeGameboard();/*设置游戏变量的初值*/nNext_block_index = -1; /*游戏初始,没有下一个形状的索引号*/nSpeed = 0;nScore = 0;}/*********************************************************** 函数原型:void ProcessInGame() ** 传入参数:无** 返回值:无** 函数功能:核心函数,主要用于处理在游戏中的各种事件(如按下各种按键) ***********************************************************/void ProcessInGame(){int key;bioskey(0);randomize();while(1){if(nNext_block_index==-1){nCurrent_block_index = rand()%19;nNext_block_index = rand()%19;/*绘制下一个提示形状*/DrawBlock(nNext_block_index,19,6,arrayBlock[nNext_block_index].nColor );}else{nCurrent_block_index = nNext_block_index;DrawBlock(nNext_block_index, 19,6,BGCOLOR ); /* 消除原来的提示形状 */nNext_block_index = rand()%19;DrawBlock(nNext_block_index,19,6,arrayBlock[nNext_block_index].nColor ); /*绘制下一个提示形状 */}nOriginX=5, nOriginY=1;TimerCounter = 0;DrawBlock(nCurrent_block_index, nOriginX,nOriginY, arrayBlock[nCurrent_block_index].nColor );/*在面板内绘制当前形状*/while(1){if (bioskey(1))key=bioskey(0);else key=0;bAccel = FALSE;switch(key){case VK_LEFT: /* 左移 */HandleLeft(nCurrent_block_index,&nOriginX,&nOriginY );break;case VK_RIGHT: /* 右移 */HandleRight(nCurrent_block_index,&nOriginX,&nOriginY );break;case VK_UP: /* 旋转 */case VK_SPACE:HandleUp(&nCurrent_block_index, &nOriginX,&nOriginY);break;case VK_DOWN: /* 下落加速键 */bAccel=TRUE;break;case VK_END: /* 暂停*/bioskey(0);break;case VK_ESC: /* 退出游戏 */bOver=TRUE;return;}if(bAccel || TimerCounter>(20-nSpeed*2))if(HandleDown(nCurrent_block_index,&nOriginX,&nOriginY))break;if(bOver)return;}}}/*********************************************************** 函数原型:void main() ** 传入参数:无 ** 返回值:无 ** 函数功能:入口函数,包含俄罗斯方块程序的主流程 ***********************************************************/void game(){InitializeGraph();SetTimer(newtimer); /*设置新的时钟中断*/while(1){StartGame();ProcessInGame();if(GameOver())break;bOver = FALSE;}KillTimer();closegraph();}unsigned int TimerCounter=0; /* 计时变量,每秒钟增加18 *//*********************************************************** 函数原型:void interrupt (*oldtimer)(void) ** 传入参数:无** 返回值:无** 函数功能:指向原来时钟中断处理过程入口的中断处理函数指针(句柄) ***********************************************************/void interrupt (*oldtimer)(void);/*********************************************************** 函数原型:void interrupt newtimer(void) ** 传入参数:无 ** 返回值:无 ** 函数功能:新的时钟中断处理函数 ***********************************************************/void interrupt newtimer(void){(*oldtimer)();TimerCounter++;}/*********************************************************** 函数原型:void SetTimer(void interrupt(*)(void)) ** 传入参数:无 ** 返回值:无 ** 函数功能:设置新的时钟中断处理函数 ***********************************************************/void SetTimer(void interrupt(*IntProc)(void)){oldtimer=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*********************************************************** 函数原型:void KillTimer() ** 传入参数:无 ** 返回值:无 ** 函数功能:恢复原先的时钟中断处理函数 ***********************************************************/void KillTimer(){disable();setvect(TIMER,oldtimer);enable();}/*********************************************************** 函数原型:void DrawSquare(int x, int y) ** 传入参数:游戏面板中的横坐标x,纵坐标y ** 返回值:无 ** 函数功能:在坐标(x, y)处绘制方块 ***********************************************************/void DrawSquare(int x, int y){if(y<1)return;bar(BSIZE*(x+9)+1,BSIZE*(y+4)+1,BSIZE*(x+10)-1,BSIZE*(y+5)-1);}/*********************************************************** 函数原型:void DrawBlock(int BlockIndex, int sx, int sy,int color) ** 传入参数:形状的索引BlockIndex,绝对横坐标x,绝对纵坐标y,颜色color ** 返回值:无** 函数功能:在坐标(sx, sy)处绘制颜色为color的形状***********************************************************/void DrawBlock(int BlockIndex, int sx, int sy,int color){int i,c;setfillstyle(SOLID_FILL, color);for(i=0;i<7;i+=2)DrawSquare(arrayBlock[BlockIndex].arrXY[i]+sx,arrayBlock[BlockIndex].arrXY[i+1]+sy);}/*********************************************************** 函数原型:int IsConflict(int BlockIndex, int x, int y) ** 传入参数:形状的索引BlockIndex,绝对横坐标x,绝对纵坐标y ** 返回值:无冲突返回0,有冲突返回1 ** 函数功能:判断形状是否能存在于坐标(x, y)处 * **********************************************************/int IsConflict(int BlockIndex, int x, int y){int i;for (i=0;i<=7;i++,i++){if (arrayBlock[BlockIndex].arrXY[i]+x<1 || arrayBlock[BlockIndex].arrXY[i]+x>10)return TRUE;if (arrayBlock[BlockIndex].arrXY[i+1]+y<1)continue;if(Gameboard[arrayBlock[BlockIndex].arrXY[i]+x][arrayBlock[BlockIndex].arrXY[i+1]+ y])return TRUE;}return FALSE;}/*********************************************************** 函数原型:int HandleLeft(int BlockIndex,int *x, int *y) * * 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的 ** 指针*y ** 返回值:无** 函数功能:按下左方向键时的处理函数***********************************************************/void HandleLeft(int BlockIndex,int *x, int *y) /*按下左方向键时的处理函数*/{if(!IsConflict(BlockIndex,*x-1,*y)){DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/(*x)--;DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/}}/*********************************************************** 函数原型:int HandleRight(int BlockIndex,int *x, int *y) ** 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的 ** 指针*y ** 返回值:无** 函数功能:按下右方向键时的处理函数***********************************************************/void HandleRight(int BlockIndex,int *x, int *y)/*按下右方向键时的处理函数*/{if(!IsConflict(BlockIndex,*x+1,*y)){DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/(*x)++;DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/}}/*********************************************************** 函数原型:int HandleUp(int BlockIndex,int *x, int *y) ** 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的 ** 指针*y ** 返回值:无** 函数功能:按下上方向键(旋转键)时的处理函数***********************************************************/void HandleUp(int *BlockIndex,int *x, int *y) /*按下旋转键时的处理函数*/{int NextBlockIndex, i;static int arrayOffset[5]={0,-1,1,-2,2};NextBlockIndex = arrayBlock[*BlockIndex].nNext;for(i=0;i<5;i++)if(!IsConflict(NextBlockIndex, *x+arrayOffset[i],*y)){DrawBlock(*BlockIndex, *x, *y, BGCOLOR); /*擦除原先的形状*/*BlockIndex = arrayBlock[*BlockIndex].nNext;(*x) += arrayOffset[i];DrawBlock(*BlockIndex, *x, *y, arrayBlock[*BlockIndex].nColor); /*绘制当前形状*/}}/*********************************************************** 函数原型:int HandleDown(int BlockIndex,int *x, int *y) * * 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的 ** 指针*y ** 返回值:仍在自由下落返回0,无法下落了返回1 ** 函数功能:按下向下方向键或自由下落时的处理函数***********************************************************/int HandleDown(int BlockIndex,int *x, int *y)/*按下下方向键或自由下落时的处理函数*/{char ScoreBuffer[10]={0},SpeedBuffer[10]={0};int i;int NumLinesKilled=0;/*if(TimerCounter>(20-nSpeed*2))*/{TimerCounter = 0; /*重置时钟中断*/if(!IsConflict(BlockIndex,*x,*y+1)) /*仍在下落*/{DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/(*y)++;DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/return FALSE;/*仍在下落返回FALSE*/}else /*无法再下落了*/{DrawBlock(BlockIndex,*x,*y,FORECOLOR);for (i=0;i<=7;i++,i++){if ((*y)+arrayBlock[BlockIndex].arrXY[i+1]<1)continue;Gameboard[(*x)+arrayBlock[BlockIndex].arrXY[i]][(*y)+arrayBlock[BlockIndex].arrX Y[i+1]]=1;}NumLinesKilled = KillLines(*y);if(NumLinesKilled>0){switch(NumLinesKilled){case 1:nScore+=100;case 2:nScore+=300;case 3:nScore+=500;case 4:nScore+=800;}/*重绘计分框*/setfillstyle(SOLID_FILL,BLACK);bar(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));itoa(nScore,ScoreBuffer, 10);setcolor(RED);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(20+1), ScoreBuffer);if(nScore > nSpeedUpScore){nSpeed++;nSpeedUpScore+= nSpeed*1000;/*重绘速度框*/setfillstyle(SOLID_FILL,BLACK);bar(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1)); itoa(nSpeed,SpeedBuffer,10);setcolor(YELLOW);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(13+1), SpeedBuffer);}if(IsGameOver())bOver = TRUE;return TRUE; /*下落到底返回TRUE*/}}}/*********************************************************** 函数原型:int IsLineFull(int y) ** 传入参数:纵坐标y ** 返回值:填满返回1,否则返回0 ** 函数功能:判断第y行是否已被填满***********************************************************/int IsLineFull(int y){int i;for(i=1;i<=10;i++)if(!Gameboard[i][y])return FALSE;return TRUE;}/*********************************************************** void KillLine(int y) ** 传入参数:纵坐标y ** 返回值:无 ** 函数功能:消去第y行***********************************************************/void KillLine(int y){int i,j;for(j=y;j>=2;j--)for(i=1;i<=10;i++){if(Gameboard[i][j]==Gameboard[i][j-1])continue;if(Gameboard[i][j-1]==FILLED){Gameboard[i][j]=FILLED;setfillstyle(SOLID_FILL,FORECOLOR);}else /*Gameboard[i][j-1]==EMPTY*/Gameboard[i][j] = EMPTY;setfillstyle(SOLID_FILL,BGCOLOR);}DrawSquare(i,j);}}/*********************************************************** 函数原型:int KillLines(int y) ** 传入参数:纵坐标y ** 返回值:消去的行数 ** 函数功能:消去第y行以及与第y行连续的上面被填满的行 ***********************************************************/int KillLines(int y){int i, j, LinesKilled=0;for(i=0;i<4;i++){while(IsLineFull(y)){KillLine(y);LinesKilled++;i++;}y--;if(y<1)break;}return LinesKilled;}/*********************************************************** 函数原型:int IsGameOver() ** 传入参数:无 ** 返回值:游戏结束返回1,否则返回0 ** 函数功能:判断游戏是否结束***********************************************************/int IsGameOver(){int i;for(i=1;i<=10;i++)if(Gameboard[i][1])return TRUE;return FALSE;}/*********************************************************** 函数原型:int GameOver() ** 传入参数:无** 返回值:退出游戏返回1,否则返回0 ** 函数功能:在界面上输出游戏结束信息,并根据用户按键选择决定是否退出游戏***********************************************************/int GameOver(){int key;settextjustify(CENTER_TEXT,TOP_TEXT);/* 输出游戏结束信息 */setcolor(RED);outtextxy(BSIZE*15,BSIZE*12,"Game Over");setcolor(GREEN);outtextxy(BSIZE*15,BSIZE*14,"Enter : New Game");outtextxy(BSIZE*15,BSIZE*15,"Esc : Exit");for(;;){while(!bioskey(1));key=bioskey(0);if (key==VK_ENTER)return FALSE; /* 按下回车键,重新开始游戏 */if (key==VK_ESC)return TRUE; /* 按下ESC键,退出游戏 */}}。
基于EasyX的俄罗斯方块游戏的设计和分析摘要本文是基于EasyX的图形库,运用C语言在VC++ 6.0的平台上开发出来的一款俄罗斯方块游戏。
关键词EasyX;俄罗斯方块游戏;VC中图分类号TP3 文献标识码 A 文章编号1674-6708(2015)150-0137-01EasyX是针对C++的图形库,可以帮助c语言初学者者快速的上手图形和游戏编程,不需要注册窗口类,建消息循环等,在使用上和Turbo C没有很大的区别,但是它增加了鼠标、批量绘图、读取图片(点阵或矢量)等功能。
1 游戏功能描述编写一个成功的俄罗斯方块游戏,主要考虑实现以下几个功能:游戏方块的预览功能;游戏方块的控制功能;游戏分数、等级更新功能;游戏操作提示功能。
2 游戏设计思路1)程序进入主函数后首先进行初始化,在初始化中通过initgraph()函数进入图形模式,用setorigin()函数设置原点,用rectangle()函数画游戏的游戏区和预览区两个区域,再通过outtextxy()函数输出游戏桌面的有关提示以及成绩和等级。
2)本游戏的游戏区域被划分为20*15个单元方格,定义了一个二维数组g_world[20][15],数组的下标就是每个单元方格左上方的坐标,通过数组存放的信息来标志单元方格的有关信息,用1表示单元方格被方块占用,0表示未被占用。
3)每个游戏方块是通过4*4的矩阵单元方格来定义的,以下为要设计主要的方块。
当单元方格被占用时用1表示,未被占用的则用0表示,以第二个L型方块为例,这个方块可以用0100,0100,0110,0000来表示,用十六进制表示为0x4460。
用循环语句检测这个十六进制的每一位,当为1是就调用setfillcolor()、setlinecolor()、fillrectangle()三个函数来给相应的单元格填充颜色。
4)游戏方块的结构体变量的定义:struct Blockinfo{char num;char x,y;char change;}g_curblock,g_nextblock;//当前和下一个方块struct BLOCK{WORD dir[4];//方块的四个旋转状态COLORREF color;}g_block[7]={ {0x0F00,0x4444,0x0F00,0x4444,RED},// I型......};//定义的7种方块形状3 游戏用到的有关算法1)方块变换。
C语言课程设计报告主标题: C语言课程设计副标题:俄罗斯方块游戏----界面设计姓名:卢文俊指导教师:刘慧院系:信息工程学院专业:计算机科学与技术班级: 11计本(二)班小组成员:卢文俊,齐伟,陈龙提交日期: 2012-6-7俄罗斯方块程序设计报告一、问题描述:要求支持键盘操作和7种不同类型方块的旋转变换,并且界面上显示下一个方块的提示以及当前的玩家的得分,随着游戏的进行,等级越高,游戏难度越大,即方块的下落速度越快,相应的等级,等级越高,消去一行所得到的分数越高,为玩家提供了不同的选择。
二、功能分析:俄罗斯方块游戏需要解决的问题包括:⑴按任意键开始游戏,随机产生方块并自动下移⑵用Esc键退出游戏。
⑶用键变换方块⑷用键和键左右移动方块⑸用键使方块加速下移⑹用空格键使方块直接下移⑺能正确判断满行并消行、计分、定级别⑻能正确计时⑼设定游戏为不同级别,级别越高难度越大重点:*游戏面包的数据结构:二维数组*7种形状方块的数据结构:结构体保存每种形状方块的坐标、颜色三、程序设计:1、程序总体设计结构:首先初始化进入图形模式,进入欢迎界面,玩家按任意进入主菜单界面,按键进入游戏界面,键然后设置新的时钟中断。
开始游戏后,进入该程序最核心的部分——处理和实现进行过程中的各种事件和函数。
在处理中判断游戏是否结束,如果没有结束,则重新开始游戏,否则结束游戏。
详解如下:(1)、游戏方块预览功能。
在游戏过程中,当在游戏底板中出现一个游戏方块时,必须在游戏方块预览区域中出现下一个游戏方块,这样有利于游戏玩家控制游戏的策略。
由于在此游戏中存在19种不同的游戏方块,所以在游戏方块预览区域中需要显示随机生成的游戏方块。
(2)、游戏方块控制功能。
通过各种条件的判断,实现对游戏方块的左移、右移、快速下移、自由下落、旋转功能,以及行满消除行的功能。
否(3)、游戏显示更新功能。
在判断键值时,有左移VK_LEFT、右移VK_RIGHT、下移VK_DOWN、变形旋转VK_UP、退出VK_ESC键值的判断。
当游戏方块左右移动、下落、旋转时,要清除先前的游戏方块,用新坐标重绘游戏方块。
当消除满行时,要重绘游戏底板的当前状态。
(4)、游戏速度分数更新功能。
在游戏玩家进行游戏过程中,需要按照一定的游戏规则给玩家计算游戏分数。
比如,消除一行加10分。
当游戏分数达到一定数量之后,需要给游戏者进行等级的上升,每上升一个等级,游戏方块的下落速度将加快,游戏的难度将增加。
(5)、游戏帮助功能。
玩家进入游戏后,将有对本游戏如何操作的友情提示。
主函数:void main(){InitializeGraph();SetTimer(newtimer); /*设置新的时钟中断*/while(1){StartGame();ProcessInGame();if(GameOver())break;bOver = FALSE;}KillTimer();closegraph();}2、界面设计分为左右两个部分:*左边为游戏面板*右边有三部分:下一个形状提示框、速度框和计分框3、重要数据的数据结构设计1)定义方块形状:定义如下的结构体来表示每一个形状:struct block{int arrXY[8];int nColor;int nNext;}; /*保存某一形状信息的结构体*/Struct SHAPE shapes[MAX_BOX]={口口口口口口口口口口口口口口口口{0x88, 0xc0, CYAN, 1},{0xe8, 0x0, CYAN, 2},{0xc4, 0x40, CYAN, 3},{0x2e, 0x0, CYAN, 0},口口口口口口口口口口口口口口口口{0x44, 0xc0, MAGENTA, 5},{0x8e, 0x0, MAGENTA, 6},{0xc8, 0x80, MAGENTA, 7},{0xe2, 0x0, MAGENTA, 4},口口口口口口口口{0x8c, 0x40, YELLOW, 9},{0x6c, 0x0, YELLOW, 8},口口口口口口口口{0x4c, 0x80, BROWN, 11},{0xc6, 0x0, BROWN, 10},口口口口口口口口口口口口口口口口{0x4e, 0x0, WHITE, 13},{0x8c, 0x80, WHITE, 14},{0xe4, 0x0, WHITE, 15},{0x4c, 0x40, WHITE, 12},口口口口口口口口{0x88, 0x88, RED, 17},{0xf0, 0x0, RED, 16},口口口口{0xcc, 0x0, BLUE, 18),}2)、定义游戏的主界面:宽10、高20的游戏板1、数据结构:全局数组Gameboard[12][22],1表示已有的方块,0表示这个位置空着。
在10*20基础上各自加2行、2列为了便于判断形状在移动时是否到边、到底。
整个屏幕的坐标系原先为640*480。
在此游戏中,将16个像素定义为一个方格的边长,所以坐标系转变成为了40*30(640/16=40,480/10=30)。
2、玩家进行游戏时,需要对游戏界面进行初始化工作。
此代码被main()函数调用。
主要进行的工作如下:(1) 循环调用line()函数绘制当前游戏板。
(2) 调用nScore()函数显示初始的成绩,初始成绩为0。
(3) 调用npeed()函数显示初始的速度(等级),初始速度1。
***************************************************** 注:x,y为左上角坐标* * m,n对应于Vertical_boxs,Horizontal_boxs* * 分别表示纵横方向上方块的个数(以方块为单位)** BOARD_LEFT_X ,BOARD_LEFT_Y*****************************************************4、函数设计1、本程序有主函数和个函数组成:本程序总共由24个函数组成。
2、函数相互作用关系见下图四、函数功能的描述:五、void StartGame() 游戏开始时调用的函数1、绘制界面需要调用函数InitializeGameboard( )2、接下来初始化游戏面板的各个方块和一些全局变量的初值。
void ProcessInGame() 核心函数,主要用于处理在游戏中的各种事件(如按下各种按键)调用HandleUpO、HandleDown()、HandleLeft()、HandleRight()等事件处理函数V oid main() 主流程函数主函数入口,整个游戏的主控部分五、运行效果六、源代码详解#include<stdio.h>#include<stdlib.h>#include<dos.h>#include<graphics.h> /*系统提供的头文件*/#define TIMER 0x1c /*定义时钟中断的中断号*/#define VK_LEFT 0x4b00/*左移键*/#define VK_RIGHT 0x4d00/*右移键*/#define VK_DOWN 0x5000 /*加速键*/#define VK_UP 0x4800 /*变形键*/#define VK_SPACE 0x3920 /*变形键*/#define VK_END 0x4f00 /*暂停键*/#define VK_ESC 0x011b#define VK_ENTER 0x1c0d#define BSIZE 16 /*方块的边长是16个象素*/#define MAX_SHAPE 19 /*总共有19种各形态的方块*/#define BOARD_WIDTH 10 /*游戏面板的宽度,以方块的宽度为单位*/ #define BOARD_HEIGHT 20/*游戏面板的高度,以方块的宽度为单位*/ #define BGCOLOR BLACK /*背景色*/#define FORECOLOR WHITE /*前景色*/#define FALSE 0#define TRUE 1#define EMPTY 0#define FILLED 1#define BOARD_LEFT_X 10 /*游戏面板左上角的横坐标*/#define BOARD_LEFT_Y 5 /*游戏面板左上角的纵坐标*//*定义全局变量*/extern int Gameboard[BOARD_WIDTH+2][BOARD_HEIGHT+2]; extern int nCurrent_block_index ; /*当前下落的方块的索引号*/extern int nNext_block_index ; /*下一个方块的索引号*/extern int nSpeed, nScore; /*速度和得分*/extern int nSpeedUpScore; /*第一次要加速需达到的分数*/extern int bAccel, bOver;extern int nOriginX, nOriginY;/*某一形状的原点的绝对坐标*/extern unsigned int TimerCounter; /* 计时变量,每秒钟增加18 */ struct block{int arrXY[8];int nColor;int nNext;}; /*保存某一形状信息的结构体*/typedef struct block BLOCK;extern BLOCK arrayBlock[19];void interrupt newtimer(void);/*新的时钟中断处理函数*/void SetTimer(void interrupt(*IntProc)(void));/*设置新的时钟中断处理过程*/ void KillTimer();/*恢复原有的时钟中断处理过程*/void InitializeGraph();/*初始化图形模式*/void InitializeGameboard() ;/*初始化游戏面板*/void DrawSquare(int x, int y);/*在坐标(x,y)处画方块*/void DrawBlock(int BlockIndex, int sx, int sy,int color);/*在(sx,sy)处绘制颜色为color的形状*/int IsConflict(int BlockIndex, int x, int y);/*判断形状能否存在于坐标(x,y)处*/ void HandleLeft(int BlockIndex,int *x, int *y);/*左键处理函数*/void HandleRight(int BlockIndex,int *x, int *y);/*右键处理函数*/void HandleUp(int *BlockIndex,int *x, int *y);/*上键处理函数*/int HandleDown(int BlockIndex,int *x, int *y);/*下键处理函数*/int IsLineFull(int y);/*判断y行是否填满*/void KillLine(int y);/*消去y行*/int KillLines(int y);/*消去y行及上面被填满的行*/int IsGameOver();/*结束游戏*/int GameOver();/*用户自己决定是否结束游戏*/void StartGame();/*开始游戏*/void ProcessInGame();/*处理游戏中各种事件*//*********************************************************** 函数原型:void InitializeGraph()** 传入参数:无** 返回值:无** 函数功能:初始化进入图形模式***********************************************************/void InitializeGraph(){int gdriver = VGA, gmode=VGAHI, errorcode;/* 初始化图形模式*/initgraph(&gdriver, &gmode, "c:\\turboc2");/* 读取初始化结果*/errorcode = graphresult();if (errorcode != grOk) /* 错误发生*/{printf("Graphics error: %s\n", grapherrormsg(errorcode));printf("Press any key to halt:");getch();exit(1); /* 返回错误码*/}}/*********************************************************** 函数原型:void InitializeGameboard()** 传入参数:无** 返回值:无** 函数功能:初始化游戏面板以及下一形状提示框、计分框和难度框***********************************************************/void InitializeGameboard(){/* 绘制游戏面板(即游戏区域)*/setfillstyle(SOLID_FILL,BGCOLOR);bar(BSIZE*BOARD_LEFT_X,BSIZE*BOARD_LEFT_Y,BSIZE*(BOARD_LEFT_ X+BOARD_WIDTH),BSIZE*(BOARD_LEFT_Y+BOARD_HEIGHT));setcolor(WHITE);rectangle(BSIZE*BOARD_LEFT_X,BSIZE*BOARD_LEFT_Y,BSIZE*(BOARD_L EFT_X+BOARD_WIDTH),BSIZE*(BOARD_LEFT_Y+BOARD_HEIGHT));/*绘制下一形状提示框*/setcolor(BLUE);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(5+1), "next");setfillstyle(SOLID_FILL, BGCOLOR);bar(BSIZE*(24.5+2), BSIZE*6, BSIZE*(24.5+2+5), BSIZE*(6+5));setcolor(YELLOW);rectangle(BSIZE*(24.5+2), BSIZE*6, BSIZE*(24.5+2+5), BSIZE*(6+5));/*绘制速度框*/setcolor(BLUE);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(12+1), "level");setfillstyle(SOLID_FILL, BGCOLOR);bar(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));setcolor(RED);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(13+1), "0");/*绘制计分框*/setcolor(BLUE);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(19+1), "score");setfillstyle(SOLID_FILL, BGCOLOR);bar(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));setcolor(RED);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(20+1), "0");}int Gameboard[BOARD_WIDTH+2][BOARD_HEIGHT+2];int nCurrent_block_index;/* 当前下落的方块的索引号*/int nNext_block_index ; /*下一个方块的索引号*/int nSpeed, nScore; /*速度和得分*/int nSpeedUpScore = 1000; /*第一次要加速需达到的分数*/int bAccel, bOver;int nOriginX=5, nOriginY=1;/*某一形状的原点的绝对坐标*/BLOCK arrayBlock[19]={/*x1,y1,x2,y2,x3,y3,x4,y4, color, next*/{ 0,-2, 0,-1, 0, 0, 1, 0, CYAN, 1}, /* */{-1, 0, 0, 0, 1,-1, 1, 0, CYAN, 2}, /* # */{ 0,-2, 1,-2, 1,-1, 1, 0, CYAN, 3}, /* # */{-1,-1,-1, 0, 0,-1, 1,-1, CYAN, 0}, /* ## */{ 0,-2, 0,-1, 0, 0, 1,-2,MAGENTA, 5}, /* */{-1,-1,-1, 0, 0, 0, 1, 0,MAGENTA, 6}, /* ## */{ 0, 0, 1,-2, 1,-1, 1, 0,MAGENTA, 7}, /* # */{-1,-1, 0,-1, 1,-1, 1, 0,MAGENTA, 4}, /* # */{-1, 0, 0,-1, 0, 0, 1, 0,YELLOW, 9}, /* */{-1,-1, 0,-2, 0,-1, 0, 0,YELLOW, 10}, /* */{-1,-1, 0,-1, 0, 0, 1,-1,YELLOW, 11}, /* # */{ 0,-2, 0,-1, 0, 0, 1,-1,YELLOW, 8}, /* ### */{-1, 0, 0,-1, 0, 0, 1,-1, BROWN, 13}, /* ## */{ 0,-2, 0,-1, 1,-1, 1, 0, BROWN, 12}, /* ## */{-1,-1, 0,-1, 0, 0, 1, 0, WHITE, 15}, /* ## */{ 0,-1, 0, 0, 1,-2, 1,-1, WHITE, 14}, /* ## */{ 0,-3, 0,-2, 0,-1, 0, 0, RED, 17},/* # */{-1, 0, 0, 0, 1, 0, 2, 0, RED, 16},/* # *//* # *//* # */{ 0,-1, 0, 0, 1,-1, 1, 0, BLUE, 18},/* ## *//*## */};/*********************************************************** 函数原型:void StartGame ()** 传入参数:无** 返回值:无** 函数功能:游戏开始时调用的函数,其中绘制界面需调用函数** InitializeGameboard(), 接下来需初始化游戏面板的** 各个方块和一些全局变量的初值***********************************************************/void StartGame(){int i,j;/*设置游戏面板中每个方块的初始值*/for(j=0;j<=BOARD_HEIGHT;j++)for(i=0;i<BOARD_WIDTH+2;i++){if(i==0 || i==BOARD_WIDTH+1)Gameboard[i][j] = FILLED;elseGameboard[i][j] = EMPTY;}for(i=0;i<BOARD_WIDTH+2;i++)Gameboard[i][BOARD_HEIGHT+1] = FILLED;InitializeGameboard();/*设置游戏变量的初值*/nNext_block_index = -1; /*游戏初始,没有下一个形状的索引号*/nSpeed = 0;nScore = 0;}/*********************************************************** 函数原型:void ProcessInGame()** 传入参数:无** 返回值:无** 函数功能:核心函数,主要用于处理在游戏中的各种事件(如按下各种按键)***********************************************************/void ProcessInGame(){int key;bioskey(0);randomize();while(1){if(nNext_block_index==-1){nCurrent_block_index = rand()%19;nNext_block_index = rand()%19;/*绘制下一个提示形状*/DrawBlock(nNext_block_index,19,6,arrayBlock[nNext_block_index].nColor );}else{nCurrent_block_index = nNext_block_index;DrawBlock(nNext_block_index, 19,6,BGCOLOR ); /* 消除原来的提示形状*/nNext_block_index = rand()%19;DrawBlock(nNext_block_index,19,6,arrayBlock[nNext_block_index].nColor ); /*绘制下一个提示形状*/ }nOriginX=5, nOriginY=1;TimerCounter = 0;DrawBlock(nCurrent_block_index, nOriginX,nOriginY,arrayBlock[nCurrent_block_index].nColor );/*在面板内绘制当前形状*/while(1){if (bioskey(1))key=bioskey(0);else key=0;bAccel = FALSE;switch(key){case VK_LEFT: /* 左移*/HandleLeft(nCurrent_block_index,&nOriginX,&nOriginY );break;case VK_RIGHT: /* 右移*/HandleRight(nCurrent_block_index,&nOriginX,&nOriginY );break;case VK_UP: /* 旋转*/case VK_SPACE:HandleUp(&nCurrent_block_index,&nOriginX,&nOriginY);break;case VK_DOWN: /* 下落加速键*/bAccel=TRUE;break;case VK_END: /* 暂停*/bioskey(0);break;case VK_ESC: /* 退出游戏*/bOver=TRUE;return;}if(bAccel || TimerCounter>(20-nSpeed*2))if(HandleDown(nCurrent_block_index,&nOriginX,&nOriginY))break;if(bOver)return;}}}/*********************************************************** 函数原型:void main()** 传入参数:无** 返回值:无** 函数功能:入口函数,包含俄罗斯方块程序的主流程***********************************************************/void main(){InitializeGraph();SetTimer(newtimer); /*设置新的时钟中断*/while(1){StartGame();ProcessInGame();if(GameOver())break;bOver = FALSE;}KillTimer();closegraph();}unsigned int TimerCounter=0; /* 计时变量,每秒钟增加18 *//*********************************************************** 函数原型:void interrupt (*oldtimer)(void)** 传入参数:无** 返回值:无** 函数功能:指向原来时钟中断处理过程入口的中断处理函数指针(句柄) * **********************************************************/void interrupt (*oldtimer)(void);/*********************************************************** 函数原型:void interrupt newtimer(void) * * 传入参数:无** 返回值:无** 函数功能:新的时钟中断处理函数***********************************************************/void interrupt newtimer(void){(*oldtimer)();TimerCounter++;}/*********************************************************** 函数原型:void SetTimer(void interrupt(*)(void)) ** 传入参数:无** 返回值:无** 函数功能:设置新的时钟中断处理函数***********************************************************/void SetTimer(void interrupt(*IntProc)(void)){oldtimer=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*********************************************************** 函数原型:void KillTimer()** 传入参数:无** 返回值:无** 函数功能:恢复原先的时钟中断处理函数***********************************************************/void KillTimer(){disable();setvect(TIMER,oldtimer);enable();}/*********************************************************** 函数原型:void DrawSquare(int x, int y) * * 传入参数:游戏面板中的横坐标x,纵坐标y ** 返回值:无** 函数功能:在坐标(x, y)处绘制方块***********************************************************/void DrawSquare(int x, int y){if(y<1)return;bar(BSIZE*(x+9)+1,BSIZE*(y+4)+1,BSIZE*(x+10)-1,BSIZE*(y+5)-1);}/*********************************************************** 函数原型:void DrawBlock(int BlockIndex, int sx, int sy,int color) ** 传入参数:形状的索引BlockIndex,绝对横坐标x,绝对纵坐标y,颜色color ** 返回值:无** 函数功能:在坐标(sx, sy)处绘制颜色为color的形状***********************************************************/void DrawBlock(int BlockIndex, int sx, int sy,int color){int i,c;setfillstyle(SOLID_FILL, color);for(i=0;i<7;i+=2)DrawSquare(arrayBlock[BlockIndex].arrXY[i]+sx,arrayBlock[BlockIndex].arrXY[i+1]+sy);}/*********************************************************** 函数原型:int IsConflict(int BlockIndex, int x, int y) ** 传入参数:形状的索引BlockIndex,绝对横坐标x,绝对纵坐标y * * 返回值:无冲突返回0,有冲突返回1 ** 函数功能:判断形状是否能存在于坐标(x, y)处***********************************************************/int IsConflict(int BlockIndex, int x, int y){int i;for (i=0;i<=7;i++,i++){if (arrayBlock[BlockIndex].arrXY[i]+x<1 ||arrayBlock[BlockIndex].arrXY[i]+x>10)return TRUE;if (arrayBlock[BlockIndex].arrXY[i+1]+y<1)continue;if(Gameboard[arrayBlock[BlockIndex].arrXY[i]+x][arrayBlock[BlockIndex].arrXY[i+ 1]+y])return TRUE;}return FALSE;}/*********************************************************** 函数原型:int HandleLeft(int BlockIndex,int *x, int *y)** 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的** 指针*y** 返回值:无** 函数功能:按下左方向键时的处理函数***********************************************************/void HandleLeft(int BlockIndex,int *x, int *y) /*按下左方向键时的处理函数*/ {if(!IsConflict(BlockIndex,*x-1,*y)){DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/(*x)--;DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/}}/*********************************************************** 函数原型:int HandleRight(int BlockIndex,int *x, int *y)** 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的** 指针*y** 返回值:无** 函数功能:按下右方向键时的处理函数***********************************************************/void HandleRight(int BlockIndex,int *x, int *y)/*按下右方向键时的处理函数*/ {if(!IsConflict(BlockIndex,*x+1,*y)){DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/(*x)++;DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/}}/*********************************************************** 函数原型:int HandleUp(int BlockIndex,int *x, int *y)** 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的** 指针*y** 返回值:无** 函数功能:按下上方向键(旋转键)时的处理函数***********************************************************/void HandleUp(int *BlockIndex,int *x, int *y) /*按下旋转键时的处理函数*/{int NextBlockIndex, i;static int arrayOffset[5]={0,-1,1,-2,2};NextBlockIndex = arrayBlock[*BlockIndex].nNext;for(i=0;i<5;i++)if(!IsConflict(NextBlockIndex, *x+arrayOffset[i],*y)){DrawBlock(*BlockIndex, *x, *y, BGCOLOR); /*擦除原先的形状*/*BlockIndex = arrayBlock[*BlockIndex].nNext;(*x) += arrayOffset[i];DrawBlock(*BlockIndex, *x, *y, arrayBlock[*BlockIndex].nColor); /*绘制当前形状*/}}/*********************************************************** 函数原型:int HandleDown(int BlockIndex,int *x, int *y)** 传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的** 指针*y** 返回值:仍在自由下落返回0,无法下落了返回1** 函数功能:按下向下方向键或自由下落时的处理函数***********************************************************/int HandleDown(int BlockIndex,int *x, int *y)/*按下下方向键或自由下落时的处理函数*/{char ScoreBuffer[10]={0},SpeedBuffer[10]={0};int i;int NumLinesKilled=0;/*if(TimerCounter>(20-nSpeed*2))*/{TimerCounter = 0; /*重置时钟中断*/if(!IsConflict(BlockIndex,*x,*y+1)) /*仍在下落*/{DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/(*y)++;DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/return FALSE;/*仍在下落返回FALSE*/}else /*无法再下落了*/{DrawBlock(BlockIndex,*x,*y,FORECOLOR);for (i=0;i<=7;i++,i++){if ((*y)+arrayBlock[BlockIndex].arrXY[i+1]<1)continue;Gameboard[(*x)+arrayBlock[BlockIndex].arrXY[i]][(*y)+arrayBlock[BlockIndex].ar rXY[i+1]]=1;}NumLinesKilled = KillLines(*y);if(NumLinesKilled>0){switch(NumLinesKilled){case 1:nScore+=100;case 2:nScore+=300;case 3:nScore+=500;case 4:nScore+=800;}/*重绘计分框*/setfillstyle(SOLID_FILL,BLACK);bar(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));itoa(nScore,ScoreBuffer, 10);setcolor(RED);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(20+1), ScoreBuffer);if(nScore > nSpeedUpScore){nSpeed++;nSpeedUpScore+= nSpeed*1000;/*重绘速度框*/setfillstyle(SOLID_FILL,BLACK);bar(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));setcolor(YELLOW);rectangle(BSIZE*25,BSIZE*13, BSIZE*(25+8),BSIZE*(13+1));itoa(nSpeed,SpeedBuffer,10);setcolor(YELLOW);settextjustify(CENTER_TEXT, BOTTOM_TEXT);outtextxy(BSIZE*(25+4), BSIZE*(13+1), SpeedBuffer);}}if(IsGameOver())bOver = TRUE;return TRUE; /*下落到底返回TRUE*/}}}/*********************************************************** 函数原型:int IsLineFull(int y)** 传入参数:纵坐标y** 返回值:填满返回1,否则返回0 ** 函数功能:判断第y行是否已被填满***********************************************************/int IsLineFull(int y){int i;for(i=1;i<=10;i++)if(!Gameboard[i][y])return FALSE;return TRUE;}/*********************************************************** void KillLine(int y)** 传入参数:纵坐标y** 返回值:无** 函数功能:消去第y行***********************************************************/void KillLine(int y){int i,j;for(j=y;j>=2;j--)for(i=1;i<=10;i++){if(Gameboard[i][j]==Gameboard[i][j-1])continue;if(Gameboard[i][j-1]==FILLED){Gameboard[i][j]=FILLED;setfillstyle(SOLID_FILL,FORECOLOR);}else /*Gameboard[i][j-1]==EMPTY*/{Gameboard[i][j] = EMPTY;setfillstyle(SOLID_FILL,BGCOLOR);}DrawSquare(i,j);}}/*********************************************************** 函数原型:int KillLines(int y)** 传入参数:纵坐标y** 返回值:消去的行数* * 函数功能:消去第y行以及与第y行连续的上面被填满的行* **********************************************************/int KillLines(int y){int i, j, LinesKilled=0;for(i=0;i<4;i++){while(IsLineFull(y)){KillLine(y);LinesKilled++;i++;}y--;if(y<1)break;}return LinesKilled;}/*********************************************************** 函数原型:int IsGameOver()** 传入参数:无** 返回值:游戏结束返回1,否则返回0 ** 函数功能:判断游戏是否结束***********************************************************/int IsGameOver(){int i;for(i=1;i<=10;i++)if(Gameboard[i][1])return TRUE;return FALSE;}/*********************************************************** 函数原型:int GameOver()** 传入参数:无** 返回值:退出游戏返回1,否则返回0** 函数功能:在界面上输出游戏结束信息,并根据用户按键选择决定是否退出游戏***********************************************************/int GameOver(){int key;settextjustify(CENTER_TEXT,TOP_TEXT);/* 输出游戏结束信息*/setcolor(RED);outtextxy(BSIZE*15,BSIZE*12,"Game Over");setcolor(GREEN);outtextxy(BSIZE*15,BSIZE*14,"Enter : New Game");outtextxy(BSIZE*15,BSIZE*15,"Esc : Exit");for(;;){while(!bioskey(1));key=bioskey(0);if (key==VK_ENTER)return FALSE; /* 按下回车键,重新开始游戏*/if (key==VK_ESC)return TRUE; /* 按下ESC键,退出游戏*/} }。