版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、OpenGL实现俄罗斯方块一、 设计思路本程序采用以C+为基础并利用OpenGl库函数的方式实现俄罗斯方块程序,实现俄罗斯方块中正方形,T形,L形,反L形,直线型,Z字形,反Z字形七种形状的变换操作,七种形状的坐标被存储在一个三维数组中,每次随机选择一个形状生成并下落,在下落过程中监听键盘事件。二、 详细设计说明本程序中主要的函数及其作用说明如下:down:定时下落函数,由glutTimerFunc(1000,down,1);函数设置每隔1000毫秒即调用一次该函数,在函数中将方块的所有纵坐标减一个单位。key: 键盘事件监听函数,当键盘上有按键被触发的时候即调用该函数,函数内部支持w,a,s
2、,d四个键的响应,依次代表方向键上,左,右,下,其中w键是用来控制图形变换的,每次按w键时,图形在现有基础上顺时针变换一次。CheckConflict:冲突检测函数,检测方块下一次将要移动的位置是否会碰到已有的方块或者左右两边的墙壁。CheckDelete:每一次方块落到底部之后,调用该函数检查是否有满行,如果有则调用Delete函数删除该行。myDisplay1:作图函数。Change:变换函数,主要是通过计算变换后的图形与之前图形的坐标关系来实现。三、 源代码#include#include#include#include#includeusing namespace std;#defin
3、e LEFT a#define RIGHT d#define UP w#define DOWN s#define START 0/定义图形的范围#define END 19#define SIZE 25/*初始化七个二维数组,即七个块刚开始产生时出现的位置*这里需要考虑的情况是:刚开始产生时有的方块还只露出来一部分,*如果这个时候按了UP键进行变换应该怎么处理*本程序最初设计并不考虑这个问题,一开始即画出方块的各个部分,以后再考虑完善的事情*另外,记录坐标的顺序为从左至右,从上至下*/GLfloat b53=0.0f,0.9f,0.0f,0.8f,0.0f,0.7f,0.0f,0.6f,/1、
4、记录长条四个坐标-0.1f,0.9f,0.0f,0.9f,-0.1f,0.8f,0.0f,0.8f,/2、记录正方形-0.1f,0.9f,-0.2f,0.8f,-0.1f,0.8f,0.0f,0.8f,/3、T字形-0.1f,0.9f,0.0f,0.9f,0.0f,0.8f,0.1f,0.8f,/4、记录Z字形-0.1f,0.9f,0.0f,0.9f,-0.2f,0.8f,-0.1f,0.8f,/5、记录倒Z字形-0.1f,0.9f,-0.1f,0.8f,-0.1f,0.7f,0.0f,0.7f,/6、记录L字形0.0f,0.9f,0.0f,0.8f,-0.1f,0.7f,0.0f,0.7f,
5、/7、记录倒L字形;GLfloat curLoc53;GLint currentBlock=2;/记录当前正在下落的是第几种方块,顺序如上面所示GLint turn7=0;/应该变换成第几种形态了GLfloat xd=0.0f,yd=0.0f;/*这里定义的over是用来判断方块是否到达了不能再往下降的地方,到了则置其为true,否则就修改为false。其中有这样几种情况需要修改over:1、重新生成了一个方块,修改over=false2、方块到大底部,修改over=true*/bool over=false;/记录游戏是否结束bool end=false;int score=0;/设置一个锁
6、,在下降操作时不允许变换,在变换时不允许下降操作,否则将会产生资源竞争/int lock=1;/*定义一个20*20的矩阵来记录当前整个画面中各个小格子的情况,可用来消除满格行矩阵的存储顺序为从左到右,从下到上,包含下标0BLOCKij中i对应的是纵坐标,j对应的是横坐标(这个有点痛苦),但是在消去满格的时候还是不变,只是在用b数组给其赋值时需要反过来*/GLint BLOCKSIZESIZE;void down(int id);void InitBLOCK();void Change();void CheckDelete();int CheckConflict(int lef_rig=0);
7、void CreateBlocks();void myDisplay1();void key(unsigned char k,int x,int y);void Delete(bool *empty);void show();void show()int i,j;for(i=0;i4;i+)/函数调用的顺序对错误有一定的影响for(j=0;j2;j+)coutcurLocij ;coutendl;/*初始化方块矩阵,方块是一个上端开口的长方形*/void InitBLOCK()int i,j;for(i=0;iSIZE;i+)for(j=0;jSIZE;j+)BLOCKij=0;for(i=0
8、;iSIZE;i+)BLOCK0i=1;for(i=0;i4;i+)for(j=0;j2;j+)curLocij=bcurrentBlockij;void Change()/将图形做变换,采用顺时针旋转的规律(下面的工作即是填入坐标)GLfloat temp00=curLoc00;GLfloat temp01=curLoc01;GLfloat temp10=curLoc10;GLfloat temp11=curLoc11;GLfloat temp20=curLoc20;GLfloat temp21=curLoc21;GLfloat temp30=curLoc30;GLfloat temp31=
9、curLoc31;switch(currentBlock)case 0:/长条switch(turn0)case 0:curLoc00=temp10-0.1f;curLoc01=temp11;curLoc20=temp10+0.1f;curLoc21=temp11;curLoc30=temp10+0.2f;curLoc31=temp11;break;case 1:curLoc00=temp10;curLoc01=temp11+0.1f;curLoc20=temp10;curLoc21=temp11-0.1f;curLoc30=temp10;curLoc31=temp11-0.2f;break;
10、turn0=(turn0+1)%2;break;case 1:/正方形break;case 2:/T字形/coutturn2=turn2endl;switch(turn2)case 0:curLoc10=temp20;curLoc11=temp21;curLoc20=temp30;curLoc21=temp31;curLoc30=temp20;curLoc31=temp21-0.1f;break;case 1:curLoc00=temp10-0.1f;curLoc01=temp11;break;case 2:curLoc00=temp10;curLoc01=temp11+0.1f;curLoc
11、10=temp00;curLoc11=temp01;curLoc20=temp10;curLoc21=temp11;break;case 3:curLoc30=temp20+0.1f;curLoc31=temp21;break;turn2=(turn2+1)%4;break;case 3:/Z字形switch(turn3)case 0:curLoc00=temp10+0.1f;curLoc01=temp11+0.1f;curLoc20=temp10+0.1f;curLoc21=temp11;curLoc30=temp20;curLoc31=temp21;break;case 1:curLoc0
12、0=temp10-0.1f;curLoc01=temp11;curLoc20=temp30;curLoc21=temp31;curLoc30=temp30+0.1f;curLoc31=temp31;break;turn3=(turn3+1)%2;break;case 4:/反Z字形switch(turn4)case 0:curLoc00=temp00-0.1f;curLoc01=temp01+0.1f;curLoc10=temp00-0.1f;curLoc11=temp01;curLoc20=temp00;curLoc21=temp01;curLoc30=temp00;curLoc31=tem
13、p01-0.1f;break;case 1:curLoc00=temp20;curLoc01=temp21;curLoc10=temp20+0.1f;curLoc11=temp21;curLoc20=temp10;curLoc21=temp11-0.1f;break;turn4=(turn4+1)%2;break;case 5:/L字形switch(turn5)case 0:curLoc00=temp10;curLoc01=temp11;curLoc10=temp10+0.1f;curLoc11=temp11;curLoc20=temp10+0.2f;curLoc21=temp11;curLo
14、c30=temp20;curLoc31=temp21;break;case 1:curLoc00=temp00;curLoc01=temp01+0.1f;curLoc10=temp10;curLoc11=temp11+0.1f;curLoc20=temp10;curLoc21=temp11;curLoc30=temp10;curLoc31=temp11-0.1f;break;case 2:curLoc00=temp20+0.1f;curLoc01=temp21;curLoc10=temp20-0.1f;curLoc11=temp21-0.1f;curLoc20=temp20;curLoc21=
15、temp21-0.1f;curLoc30=temp20+0.1f;curLoc31=temp21-0.1f;break;case 3:curLoc00=temp10;curLoc01=temp11+0.2f;curLoc10=temp10;curLoc11=temp11+0.1f;curLoc20=temp10;curLoc21=temp11;curLoc30=temp20;curLoc31=temp21;break;turn5=(turn5+1)%4;break;case 6:/反L字形switch(turn6)case 0:curLoc00=temp20-0.1f;curLoc01=tem
16、p21+0.1f;curLoc10=temp20-0.1f;curLoc11=temp21;break;case 1:curLoc00=temp00+0.1f;curLoc01=temp01+0.1f;curLoc10=temp30;curLoc11=temp31+0.2f;curLoc20=temp00+0.1f;curLoc21=temp01;curLoc30=temp20;curLoc31=temp21;break;case 2:curLoc00=temp00-0.1f;curLoc01=temp01-0.1f;curLoc10=temp20;curLoc11=temp21;curLoc
17、20=temp20+0.1f;curLoc21=temp21;curLoc30=temp30+0.1f;curLoc31=temp31;break;case 3:curLoc00=temp20;curLoc01=temp21+0.1f;curLoc10=temp20;curLoc11=temp21;curLoc20=temp30-0.1f;curLoc21=temp31;curLoc30=temp30;curLoc31=temp31;break;turn6=(turn6+1)%4;break;/如果旋转非法(即旋转时碰到墙壁了),则要恢复原来的状态int ret;ret=CheckConfli
18、ct();if(ret = 1)curLoc00=temp00;curLoc01=temp01;curLoc10=temp10;curLoc11=temp11;curLoc20=temp20;curLoc21=temp21;curLoc30=temp30;curLoc31=temp31;/*消除满格的一行,在每次over被修改为true的时候都要检查一遍算法思想是从第0行开始依次判断,如果empty为true则将下面的向上,并不是判断一次就移动所有的,而是只移动最近的,将空出来的那一行的empty标记为true*/void Delete(int *empty)int i,j;int pos;w
19、hile(1)/将上面非空的行填补到下面的空行中i=1;while(i = 20)break;j=i+1;while(j = 20)break;if(j 20&emptyj != -1)for(pos=0;pos20;pos+)BLOCKipos=BLOCKjpos;emptyi=emptyj;emptyj=-1;for(i=1;i20;i+)if(emptyi != 0)for(j=0;j20;j+)BLOCKij=0;/*1、判断新生成的图形是否和原来的图形有冲突,有则不能更改,这个地方比较不好实现*2、判断是否有满格的行,有则调用Delete函数去掉*3、这里似乎还要加上判断是否到大顶部
20、,如果到达顶部则游戏结束(可采用监视方框最上*面一行之上那行里面有没有方格,如果有的话则游戏结束)*结束之后就可以把当前方块存入BLOCK中*empty表示一行中方块的数目,-1表示为空行,0表示部分为空,1表示满行*/void CheckDelete()/目前这个函数还只是实现了一个方块到达终点之后是否有能够被删除的行int i,j;int emptySIZE;bool is_needed=false;int count;for(i=0;iSIZE;i+)emptyi=-1;for(i=0;i4;i+)double x=(curLoci0+1)*10+0.5;/此处无需注意取值,因为chec
21、kConflict已经解决double y=(curLoci1+1)*10+0.5;BLOCK(int)y(int)x=1;/融合for(i=1;i20;i+)count=0;for(j=0;j 0&count 20)emptyi=0;if(is_needed=true)/如果有满行则去删除,否则免之Delete(empty);int CheckConflict(int lef_rig)int i;for(i=0;i0?(x+0.5):(x-0.5);if(lef_rig = 1)int tmpx=(int)x;if(tmpx 19|tmpx 0)break;if(BLOCK(int)y(in
22、t)x=1) /判断是否发生冲突break;if(i 4)return 1;return 0;/*关键部分在这里,主要是要判断方块下一次的移动是否合法,本程序通过对b数组所存储的下标是否在BLOCK数组中已经为1来判断,这样,只需要在BLOCK的最外层加一圈1,就不用通过原来的方式来判断方块是否越界*/void key(unsigned char k,int x,int y)int i,ret;if(over = false)if(k=UP)/此处需要改成调用变换图形样式的函数Change();else if(k=DOWN)/后续还要修改,移动到底部过了一段时间之后就不能左右移动了for(i=
23、0;i4;i+)/需继续添加以1和-1作为哨兵curLoci1-=0.1f;ret=CheckConflict();if(ret = 1)/发生冲突,则将修改复原for(i=0;i4;i+)curLoci1+=0.1f;over=true;/并且可以生成下一个方块了else if(k=RIGHT)for(i=0;i4;i+)curLoci0+=0.1f;ret=CheckConflict(1);if(ret = 1)/发生冲突,则将修改复原for(i=0;i4;i+)curLoci0-=0.1f;else if(k=LEFT)for(i=0;i4;i+)curLoci0-=0.1f;ret=C
24、heckConflict(1);if(ret = 1)/发生冲突,则将修改复原for(i=0;i4;i+)curLoci0+=0.1f;if(over=true)CheckDelete();glutPostRedisplay();/调用这个函数可以重新绘图,每次相应消息之后,所有全部重绘/*让方块定时下降*/void down(int id)int i,ret;if(over!=true)for(i=0;i4;i+)/需继续添加以1和-1作为哨兵curLoci1-=0.1f;ret=CheckConflict();if(ret = 1)/发生冲突,则将修改复原for(i=0;i= bcurre
25、ntBlock01)coutGame over,your score is:score*100endl;exit(1);over=true;/并且可以生成下一个方块了if(over=true)CheckDelete();glutPostRedisplay();glutTimerFunc(1000,down,1);/作图函数,要修改,利用BLOCK数组绘图void myDisplay1()int i,j;glClear(GL_COLOR_BUFFER_BIT);/不能使用深度测试,否则画出来的图形很乱for(i=0;i20;i+)for(j=0;j20;j+)if(BLOCKij=1)glCol
26、or3f(0.0f,1.0f,0.0f);/用蓝色画图glRectf(j/10.0f-1.0f,i/10.0f-1.0f,j/10.0f-1.0f+0.1f,i/10.0f-1.0f+0.1f);glLineWidth(2.0f);glBegin(GL_LINE_LOOP);glColor3f(0.0f,0.0f,0.0f);glVertex2f(j/10.0f-1.0f,i/10.0f-1.0f);glVertex2f(j/10.0f-1.0f+0.1f,i/10.0f-1.0f);glVertex2f(j/10.0f-1.0f+0.1f,i/10.0f-1.0f+0.1f);glVertex2f(j/10.0f-1.0f,i/10.0f-1.0f+0.1f);glEnd();glFlush();if(over = false)for(i=0;i4;i+)glColor3f(0.0f,1.0f,0.0f);/用蓝色画图glRectf(curLoci0,curLoci1,c
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全教育防微杜渐
- 脑出血急救培训护理
- 创业梦创新梦主题活动
- 黑龙江省 哈尔滨市第四十七中学校2024-2025学年七年级上学期期中考试语文试题
- 甘肃省兰州市兰州树人中学2023-2024学年九年级上学期期中历史试卷 - 副本
- 全球与中国CBRN防护服市场发展需求及投资机遇研究报告2024-2030年
- 广东省广州市白云区华赋学校2024-2025学年上学期七年级英语期中考试卷
- 内蒙古自治区通辽市科尔沁左翼中旗联盟校2024-2025学年九年级上学期期中考试历史试题
- 天津市西青区富力中学2024-2025学年九年级上学期期中检测物理试题
- 【课件】Unit4SectionA1a-1d课件人教版英语七年级上册
- 二 《学习工匠事迹 领略工匠风采》(教学设计)-【中职专用】高二语文精讲课堂(高教版2023·职业模块)
- 水电工考试题及答案
- 分子结构与化学性质的关系
- 2023年房地产估价师考试完整真题及答案解析
- 第14课 推进绿色发展
- 山东省泰安市新泰市2023-2024学年五年级上学期期中语文试卷
- 声乐基础课件
- 2023-2024学年七年级地理上册(人教版)单元精讲·速记·巧练 (含答案解析)第一章 地球和地图【单元测试·达标卷】
- 部编版五年级道德与法治上册第6课《我们神圣的国土》教学课件
- 话剧社管理制度
- 四川省成都市石室联合中学教育集团2023-2024学年八年级上学期期中物理试卷
评论
0/150
提交评论