OpenGL实现俄罗斯方块源代码_第1页
OpenGL实现俄罗斯方块源代码_第2页
OpenGL实现俄罗斯方块源代码_第3页
OpenGL实现俄罗斯方块源代码_第4页
OpenGL实现俄罗斯方块源代码_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、OpenGL 实现俄罗斯方块设计思路本程序采用以 C+ 为基础并利用 OpenGl 库函数的方式实现俄罗斯方块程序,实 现俄罗斯方块中正方形, T形,L形,反L形,直线型,Z字形,反Z字形七种形状的 变换操作, 七种形状的坐标被存储在一个三维数组中, 每次随机选择一个形状生成并下 落,在下落过程中监听键盘事件。详细设计说明本程序中主要的函数及其作用说明如下:down :定时下落函数,由 glutTimerFunc(1000,down,1); 函数设置每隔 1000 毫秒即 调用一次该函数,在函数中将方块的所有纵坐标减一个单位。key : 键盘事件监听函数,当键盘上有按键被触发的时候即调用该函数

2、,函数内部支持 w, a, s, d 四个键的响应,依次代表方向键上,左,右,下,其中 w 键是 用来控制图形变换的,每次按 w 键时,图形在现有基础上顺时针变换一次。CheckConflict :冲突检测函数,检测方块下一次将要移动的位置是否会碰到已有的方 块或者左右两边的墙壁。CheckDelete :每一次方块落到底部之后, 调用该函数检查是否有满行, 如果有则调用Delete 函数删除该行。myDisplay1 :作图函数。Change :变换函数,主要是通过计算变换后的图形与之前图形的坐标关系来实现。源代码#include #include#include#include#inclu

3、de using namespace std;#define 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

4、.9f,0.0f,0.8f,0.0f,0.7f,0.0f,0.6f,/1、记录长条四个坐标-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

5、 字形0.0f,0.9f,0.0f,0.8f,-0.1f,0.7f,0.0f,0.7f,/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*/b

6、ool over=false;/ 记录游戏是否结束bool end=false;int score=0;/ 设置一个锁,在下降操作时不允许变换,在变换时不允许下降操作,否则将会产生资 源竞争/int lock=1;/*定义一个 20*20 的矩阵来记录当前整个画面中各个小格子的情况,可用来消除满格行矩阵的存储顺序为从左到右,从下到上,包含下标 0BLOCKi j中i对应的是纵坐标,j对应的是横坐标(这个有点痛苦),但是在消去满格的时候还是不变,只是在用 b 数组给其赋值时需要反过来*/GLint BLOCKSIZESIZE;void down(int id);void InitBLOCK();

7、void Change();void CheckDelete();int CheckConflict(int lef_rig=0);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+)coutendl;/*初始化方块矩阵,方块是一个上端开口的长方形*/void InitBLOCK()int i

8、,j;for(i=0;iSIZE;i+)for(j=0;jSIZE;j+)BLOCKij=0;for(i=0;iSIZE;i+)BLOCK0i=1;for(i=0;i4;i+)for(j=0;j2;j+)curLoci j=bcurrentBlocki j;(下面的工作即是填入坐标 )void Change()/ 将图形做变换,采用顺时针旋转的规律GLfloat temp01=curLoc01;GLfloat temp11=curLoc11;GLfloat temp20=curLoc20;GLfloat temp21=curLoc21;GLfloat temp30=curLoc30;GLflo

9、at temp31=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:curLoc01=temp11+0.1f;curLoc21=temp11-0.1f;curLoc30=temp10;curLoc31=temp11-0.2f;break;turn0=(turn0+1)%2;bre

10、ak;case 1:/ 正方形break;case 2:/T 字形/coutturn2=turn2endl;switch(turn2)case 0:curLoc10=temp20;curLoc11=temp21;curLoc20=temp30;curLoc21=temp31;curLoc30=temp20;break;curLoc01=temp11;break;case 2:curLoc00=temp10;curLoc01=temp11+0.1f;curLoc10=temp00;curLoc11=temp01;curLoc20=temp10;curLoc21=temp11;break;case

11、 3:curLoc30=temp20+0.1f;curLoc31=temp21;break;turn2=(turn2+1)%4;break;case 3:/Z 字形curLoc01=temp11+0.1f;curLoc20=temp10+0.1f;curLoc21=temp11;curLoc30=temp20;curLoc31=temp21;break;case 1:curLoc00=temp10-0.1f;curLoc01=temp11;curLoc20=temp30;curLoc21=temp31;curLoc30=temp30+0.1f;curLoc31=temp31;break;tur

12、n3=(turn3+1)%2;break;case 4:/ 反 Z 字形curLoc00=temp00-0.1f;curLoc01=temp01+0.1f;curLoc10=temp00-0.1f;curLoc11=temp01;curLoc20=temp00;curLoc21=temp01;curLoc30=temp00;curLoc31=temp01-0.1f;break;case 1:curLoc00=temp20;curLoc01=temp21;curLoc10=temp20+0.1f;curLoc11=temp21;curLoc20=temp10;curLoc21=temp11-0.

13、1f;break;break;case 5:/L 字形switch(turn5)case 0:curLoc00=temp10;curLoc01=temp11;curLoc10=temp10+0.1f;curLoc11=temp11;curLoc20=temp10+0.2f;curLoc21=temp11;curLoc30=temp20;curLoc31=temp21;break;case 1:curLoc00=temp00;curLoc01=temp01+0.1f;curLoc10=temp10;curLoc11=temp11+0.1f;curLoc20=temp10;curLoc21=tem

14、p11;curLoc30=temp10;break;curLoc00=temp20+0.1f; curLoc01=temp21;curLoc10=temp20-0.1f;curLoc11=temp21-0.1f; curLoc20=temp20;curLoc21=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=te

15、mp11;curLoc30=temp20;curLoc31=temp21;break;turn5=(turn5+1)%4;break;case 6:/ 反 L 字形switch(turn6)case 0:curLoc00=temp20-0.1f;curLoc01=temp21+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;curLoc

16、21=temp01;curLoc30=temp20;curLoc31=temp21;break;case 2:curLoc01=temp01-0.1f;curLoc10=temp20;curLoc11=temp21;curLoc20=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

17、;curLoc30=temp30;curLoc31=temp31;break;break;/ 如果旋转非法 (即旋转时碰到墙壁了 ),则要恢复原来的状态 int ret;ret=CheckConflict();if(ret = 1)curLoc00=temp00;curLoc01=temp01;curLoc10=temp10;curLoc11=temp11;curLoc20=temp20;curLoc21=temp21;curLoc30=temp30;curLoc31=temp31;/*消除满格的一行,在每次over 被修改为 true 的时候都要检查一遍算法思想是从第 0 行开始依次判断,如

18、果empty 为 true 则将下面的向上,并不是判断一次就移动所有的,而是只移动最近的,将空出来的那一行的 empty 标记为 true */ void Delete(int *empty)int i,j;int pos;while(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;empty j=-1;for(i=1;i20;i+)if(empt

19、yi != 0)for(j=0;j20;j+)BLOCKij=0;/*1 、判断新生成的图形是否和原来的图形有冲突, 有则不能更改, 这个地方比较不好实 现*2 、判断是否有满格的行,有则调用 Delete 函数去掉*3 、这里似乎还要加上判断是否到大顶部, 如果到达顶部则游戏结束 (可采用监视方框 最上*面一行之上那行里面有没有方格,如果有的话则游戏结束)* 结束之后就可以把当前方块存入 BLOCK 中*empty 表示一行中方块的数目, -1 表示为空行, 0 表示部分为空, 1 表示满行*/void CheckDelete()/ 目前这个函数还只是实现了一个方块到达终点之后是否有能够 被

20、删除的行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;checkConflict 已经解决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)/ 如果有满行则

21、去删除,否则免之Delete(empty);int CheckConflict(int lef_rig)int i;for(i=0;i0?(x+0.5):(x-0.5);int tmpx=(int)x;if(tmpx 19|tmpx 0)break;if(BLOCK(int)y(int)x=1) / 判断是否发生冲突break;if(i 4)return 1;return 0;/*关键部分在这里,主要是要判断方块下一次的移动是否合法,本程序通过对 b 数组所存储的下标是否在 BLOCK 数组中已经为 1 来判断,这样,只需要在 BLOCK 的最外层加一圈 1,就不用通过 原来的方式来判断方块是

22、否越界*/void key(unsigned char k,int x,int y)int i,ret;if(k=UP)/ 此处需要改成调用变换图形样式的函数Change();右移动了else if(k=DOWN)/ 后续还要修改, 移动到底部过了一段时间之后就不能左for(i=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(

23、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=CheckConflict(1);if(ret = 1)/ 发生冲突,则将修改复原for(i=0;i4;i+)curLoci0+=0.1f;if(over=true) CheckDelete();glutPostRedisplay();/ 调用这个函数可以重新绘图 ,每次相应消息之后,所有全部重绘/*让

24、方块定时下降*/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= bcurrentBlock01)coutGame over,your score is:score*100endl;exit(1);over=true;/ 并且可以生成下一个方块了if(over=true) CheckDelete();glutPostRedisplay();glutTimerF

25、unc(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(BLOCKi j=1)glColor3f(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_L

26、OOP);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,curLoc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论