制作俄罗斯方块游戏的步骤_俄罗斯方块怎么做手工

(54) 2024-08-16 14:01:04

上接Maketetris继续:
在Maketetris里,一共有19个case,第一个case是田字格的形态,田字格有且只有一种形态,我们在Printtetris里面,已经将b数组,也就是方块数组全部赋值为1,而且中心方块一直是4X4大方块里第三行第二个方块,它的xy坐标不用动,所以不需要在写代码的时候再写19次,所以一开始即可对a[80][80] 定位数组赋值了,a数组具体怎么用这里还讲不清楚,后面用到的函数会讲到。每个case 都会有b1,b2,b3数组来赋值,赋值为1

void CleanTetris(struct Tetris*tetris)void CleanTetris(struct Tetris*tetris) { 
    for(i=0;i<4;i++) { 
    b[i]=0; } MakeTetris(tetris); for(i=tetris->x-2;i<=tetris->x+4;i+=2) { 
    for(j=tetris->y-2;j<=tetris->y+1;j++) { 
    if(a[i][j]==0&&j>FrameY) { 
    gotoxy(i,j); printf(" "); } } } } 

与Printtetris类似,不过Clean函数里将b数组全部赋值为0,因为是要清除上一时间点方块的痕迹,不然看起来会很糟糕,同样里面调用了MakeTetris函数,因为具体需要如何清除痕迹,需要由每个链表节点(方块)的flag(方块的形态共19种)来判定,与Printtetris很类似。

int ifMove(struct Tetris*); int ifMove(struct Tetris*tetris) { 
    if(a[tetris->x][tetris->y]!=0) { 
    return 0; } else { 
    if((tetris->flag==1&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x+2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==2&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y]==0&&a[tetris->x+4][tetris->y]==0) ) || (tetris->flag==3&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y-2]==0&&a[tetris->x][tetris->y+1]==0) ) || (tetris->flag==4&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y]==0&&a[tetris->x][tetris->y+1]==0) ) || (tetris->flag==5&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y]==0) ) || (tetris->flag==6&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==7&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==8&&(a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y+1]==0) ) || (tetris->flag==9&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x-2][tetris->y+1]==0) ) || (tetris->flag==10&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==11&&(a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x-2][tetris->y]==0) ) || (tetris->flag==12&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y-1]==0) ) || (tetris->flag==15&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x-2][tetris->y+1]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==14&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x+2][tetris->y+1]==0) ) || (tetris->flag==13&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==16&&(a[tetris->x][tetris->y+1]==0&&a[tetris->x][tetris->y-1]==0&&a[tetris->x+2][tetris->y-1]==0) ) || (tetris->flag==19&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) || (tetris->flag==18&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y+1]==0) ) || (tetris->flag==17&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y+1]==0&&a[tetris->x+2][tetris->y]==0) )) { 
    return 1; } } return 0; } 

ifMove 需要说的一点是,每当调用ifMove之前,方块的xy坐标都会先发生改变,向左向右,或是加速向下,然后用ifMove判断,已经改变的中心坐标,是否在以中心方块坐标为中心方块的4X4方块里面,是否符合相应的flag形态,如果符合 return1,如果不符合return 0,可以看到先判断的是:

if(a[tetris->x][tetris->y]!=0) { 
    return 0; } 

先判断的是中心方块,同理,不需要19个形态一次一次判断,如果连中心方块都不能放入,肯定不可能放入,a数组在这里的作用就是去判断是否在已经改变的中心坐标位置上,是否有方块,a数组就是一个定位作用。(以上代码的xy坐标都是被提前“试着改过”的,如果ifMove返回0,都会进行还原)。

为了方便理解,用flag1 作为例子:

制作俄罗斯方块游戏的步骤_俄罗斯方块怎么做手工 (https://mushiming.com/)  第1张

void Del_Fullline(struct Tetris*tetris); void Del_Fullline(struct Tetris*tetris) { 
    int k,del_rows=0; for(j=FrameY+Frame_height-1;j>=FrameY+1;j--)//定位于下边框至上边框 { 
    k=0; for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2)//定位于左边框至右边框 { 
    if(a[i][j]==1) { 
    k++; if(k==Frame_width-2)//如果满行 { 
    for(k=FrameX+2;k<FrameX+2*Frame_width-2;k+=2)//进行清行操作 { 
    a[k][j]=0; gotoxy(k,j); printf(" "); } for(k=j-1;k>FrameY;k--)//清完一行,被清行上面一行或N行需要集体落下 { 
    for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2) { 
    if(a[i][k]==1) { 
    a[i][k]=0; gotoxy(i,k); printf(" "); a[i][k+1]=1; gotoxy(i,k+1); printf("▇"); } } } j++; del_rows++;//用来计算分数 } } } } score+=100*del_rows;//每清一行,加100分 if(del_rows>0&&(score%1000==0||score/1000>level-1)) { 
    speed-=30;//当每满1000分的时候,延迟速度减少30毫秒 level++;//恭喜你升级1级 } } 

这是判断是否满行的函数,也是每个方块落定以后需要判定的,照着注释很好理解。

void Regulation(); void explantion(); void Replay(); void welcome(); void title(); void flower(); void closer(); int color(); void explantion(); 

以上几个函数,几乎没有用到任何参数,基本上都是定位和打印,以下是图片和源代码:

制作俄罗斯方块游戏的步骤_俄罗斯方块怎么做手工 (https://mushiming.com/)  第2张制作俄罗斯方块游戏的步骤_俄罗斯方块怎么做手工 (https://mushiming.com/)  第3张
制作俄罗斯方块游戏的步骤_俄罗斯方块怎么做手工 (https://mushiming.com/)  第4张
制作俄罗斯方块游戏的步骤_俄罗斯方块怎么做手工 (https://mushiming.com/)  第5张

void Regulation() { 
    int i,j=1; system("cls"); color(13); gotoxy(34,3); printf("Regulation"); color(2); for(i=6;i<=18;i++) { 
    for(j=12;j<=70;j++) { 
    gotoxy(j,i); if(i==6||i==18) printf("="); else if(j==12||j==69) printf("="); } } color(12); gotoxy(16,7); printf("tip1:不同形状的小方块从屏幕上方落下,玩家通过调整"); gotoxy(22,9); printf("方块的位置和方向,使他们在屏幕拼出完整的"); gotoxy(22,11); printf("一条或者几条"); color(14); gotoxy(16,13); printf("tip2:每消除一行,积分涨100"); color(11); gotoxy(16,15); printf("tip3:每累计1000分,会提升一个等级"); color(10); gotoxy(16,17); printf("tip4:提升等级会使方块下落速度加快,游戏难度加大"); getch(); system("cls"); welcome(); } 
void explantion() { 
    int i,j=1; system("cls"); color(13); gotoxy(32,3); printf("explanation"); color(2); for(i=6;i<=16;i++) { 
    for(j=15;j<=60;j++) { 
    gotoxy(j,i); if(i==6||i==16) printf("="); else if(j==15||j==59) printf("||"); } } color(3); gotoxy(18,7); printf("tip1:玩家可以通过方向键来移动方块"); color(10); gotoxy(18,9); printf("tip2:通过向上键旋转方块"); color(14); gotoxy(18,11); printf("tip3:通过向下键加速方块下落"); color(11); gotoxy(18,13); printf("tip4:按空格键暂停游戏"); color(4); gotoxy(18,15); printf("tip5:按ESC键退出游戏"); getch(); system("cls"); main(); } 
void Replay() { 
    system("cls"); memset(a,0,6400*sizeof(int)); DrawGameframe(); Gameplay(); } 
void welcome() { 
    int n; int i,j=1; color(14); for(i=9;i<=20;i++) { 
    for(j=15;j<=60;j++) { 
    gotoxy(j,i); if(i==9||i==20) printf("="); else if(j==15||j==59) printf("||"); } } color(12); gotoxy(25,12); printf("1.开始游戏"); gotoxy(40,12); printf("2.按键说明"); gotoxy(25,17); printf("3.游戏规则"); gotoxy(40,17); printf("4.退出"); gotoxy(21,22); color(3); printf("请选择【1 2 3 4】:[ ]\b\b"); color(14); scanf("%d",&n); switch(n) { 
    case 1: system("cls"); DrawGameframe(); Gameplay(); break; case 2: explantion(); break; case 3: Regulation(); break; case 4: closer(); break; } } 
void title() { 
    color(15); gotoxy(28,3); printf("俄 罗 斯 方 块\n"); color(11); gotoxy(18,5); printf("▇"); gotoxy(18,6); printf("▇▇"); gotoxy(18,7); printf("▇"); color(14); gotoxy(26,6); printf("▇▇"); gotoxy(28,7); printf("▇▇"); color(10); gotoxy(36,6); printf("▇▇"); gotoxy(36,7); printf("▇▇"); color(13); gotoxy(45,5); printf("▇"); gotoxy(45,6); printf("▇"); gotoxy(45,7); printf("▇"); gotoxy(45,8); printf("▇"); color(12); gotoxy(56,6); printf("▇"); gotoxy(52,7); printf("▇▇▇"); } 
void flower() { 
    gotoxy(66,11); color(12); printf("(_)"); gotoxy(64,12); printf("(_)"); gotoxy(68,12); printf("(_)"); gotoxy(66,13); printf("(_)"); gotoxy(67,12); color(6); printf("@"); gotoxy(72,10); color(13); printf("(_)"); gotoxy(76,10); printf("(_)"); gotoxy(74,9); printf("(_)"); gotoxy(74,11); printf("(_)"); gotoxy(75,10); color(6); printf("@"); gotoxy(71,12); printf("|"); gotoxy(72,11); printf("/"); gotoxy(70,13); printf("\\|"); gotoxy(70,14); printf("^|/"); gotoxy(70,15); printf("\\|"); gotoxy(71,16); printf("|/"); gotoxy(71,17); printf("|"); gotoxy(67,17); color(10); printf("\\\\\\\\"); gotoxy(73,17); printf("//"); gotoxy(67,18); color(2); printf("^^^^^^^^"); } 
void closer() { 
    exit(0); } 
int color(int c) { 
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c); return 0; } 

第三部分是最关键的 CreateFlag和Gameplay函数

THE END

发表回复