先学习了一个简单的图形库,然后花了几天试着写一个俄罗斯方块,菜鸟写的超级水,刚开始没搞懂状况,直接想写一个函数把所有情况给包含在内,
结果没写完,自己都搞不懂自己写的是什么了,下边是开始的时候边学习边写的,典型的反面教材,不过毕竟也是自己搞的第一个试验品,没写完
先总结一下了
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 0000
for (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多次,现在只是有一个雏形。
争取这两天完善好