俄罗斯方块

来源:互联网 发布:mysql数据库查询工具 编辑:程序博客网 时间:2024/06/03 10:58

先学习了一个简单的图形库,然后花了几天试着写一个俄罗斯方块,菜鸟写的超级水,刚开始没搞懂状况,直接想写一个函数把所有情况给包含在内,
结果没写完,自己都搞不懂自己写的是什么了,下边是开始的时候边学习边写的,典型的反面教材,不过毕竟也是自己搞的第一个试验品,没写完
先总结一下了

void show(int x, int y, int numb, int color){static int Table[row][column] = {0};int lastx = 0, lasty = 0;lastx = x + column / 2 * element;//设置下落位置为主界面中间位置x = lastx;//记忆得到中间坐标后,再把x的值赋为中间坐标lasty = y;int p = 0, q = 0;int gridR = (lasty - Sys_y)/element;//画方块的位置-行格子数int gridC = (lastx - Sys_x)/element;//画方块的位置-列格子数int s = 0, t = 0;//在4*4的区域内行/列数,判断边界位置int a[4][4] = {0}, b[4] = {0};//记忆4*4内方块的边界int lowy = 0;//每次画完方块后的最低点,通过它与边界的倒数第一层比较判断是否到达底界int r = 0, c = 0;//方块在主界面里的方格行/列数if (numb >= shapeMax || numb < 0)numb = shapeMax / 2;setlinecolor(BLACK);for(int i = 0; i < 2; i++){int mask = 128;//1000 0000for (int j = 0; j < 8; j++){if (j != 0 && j % 4 == 0){//4个位置比较之后换行x = lastx;//横坐标复原y += element;//纵坐标下移一个格子}if (shape[numb].bite[i] & mask){setfillcolor(color);r = (y - Sys_y) / element;//被占用格子的行数c = (x - Sys_x) / element;//被占用的格子的列数s = (y - lasty) / element;t = (x - lastx) / element;if (color != fgcolor){Table[r][c] = 1;//标记这个格子被占用a[s][t] = 1;}else{Table[r][c] = 0;//标记这个格子被释放}fillrectangle(x, y, x + element, y + element);//在这个格子内填充lowy = y;//记忆被占用的最靠近底部的位置}x += element;mask /= 2;}x = lastx;y += element;}//每次画完格子之后,r为画的最后一行,将c初始化为降落的位置for (int i = 0; i < 4; i++){for (int j = 3; j >= 0; j--){if (a[j][i] > b[i])b[i] = j;}p = gridR + b[i];q = gridC + i;if (Table[p][q] == 1 && Table[p+1][q] == 1){END = true;}}//for (c = (lastx - Sys_x) / element; c < column; c++){//if(Table[r][c] == 1 && Table[r + 1][c] == 1){//比较占用位置和下一行//END = true;//如果占用位置的下一行已经占用,则结束//break;//}//}if (lowy == Sys_y + row * element - element)//判断最低的被占用的位置是否已经到达了底部的界限END = true;}

今天下午又花时间梳理了一下

分析方块的结构
所有的方块都位于4*4的区域
方块的形状使用二进制表示,0表示空白,1表示打印单元,C语言中的字符量是用0x+两个十六进制数表示的,所以使用两个字符表示方块的形状
方块的个数为19个,声明一个长度为19的方块结构数组
方块的类别为7类,方块的颜色由方块的类别决定
方块旋转一次后变为哪一个方块,是由的类别决定的,每个类中的方块通过有限次旋转后可以得到它自己,那么就需要一个后继next,表示旋转后下一个的编号,类似于链表中的nextPtr

分析方块的显示
通过两个4循环的for循环,方块的字符量与mask进行位运算,判定是否打印单元,mask= 128,每次mask减半,当mask=0时候,重置mask为128(之所以使用128是因为C语言中每个字符为8个字节,假如方块的形状是使用一个整数表示的话,则可以使用mask=32768与整数进行位运算,判定它的16位中哪些为1)每4次循环x坐标复回原位,y坐标下移(其实就是先一行4位判断,判断够4位后即判断了一行,那么重新回到列首,行数下移一位)

分析方块的移动move
上下左右
先给出一个函数判定是否可以移动,不能返回false,能返回true,然后在根据判定调用下一步使用的函数
LEFT左-移动后要显示的格子碰到左边界或者格子已经被占用
x = x - element;然后4*4判定
RIGHT右-移动后要显示的格子碰到右边界或者格子已经被占用
x = x + element;然后4*4判定
DOWN下-移动后要显示的格子碰到右边界或者格子已经被占用
y = y + element;然后4*4判定
UP上-旋转后要显示的格子碰到左、右、下边界或者格子已经被占用
num 变为它的next;

分析游戏界面中的方块
先显示一个方块
然后判断是否按键
    是的话,按Esc的话直接退出游戏,先擦去该方块,查看属于上下左右哪个键,调用相应move函数判定是否可行:然后在移动后下一个位置显示该方块。否,则自由下落,执行(A) 
    否的话,先擦去该方块,自由下落,(A)调用move(DOWN)判定下落是否可行:
是,然后在移动后下一个位置显示该方块
否,再显示该方块,另外产生新方块
注意是先擦去该方块,再调用move函数判定是否可行。顺序必须这样,先腾空要消失的方块的空间,再判定。

产生新方块
需要一个标记NEW判断是否产生新方块,
产生新方块的话,x,y坐标都要复原,编号也要随机生成一个
如果NEW=TRUE但是调用move(DOWN)函数返回false则说明游戏结束

当然具体的细节还要修正,再加上消除行,某一行全部被占用,就被消除,可以写出游戏主界面基本的内容了。
巨多细节没有考虑到,结果做的时候调试N多次,现在只是有一个雏形。
争取这两天完善好


0 0
原创粉丝点击