下面我记录下我用C语言写俄罗斯方块的方法和思路。
方法是参考b站的教学视频并且进行一定的改进。
这个是用控制台实现的,不需要用到graphics.h头文件, 对各种编译器应该都是兼容的。
原视频链接:https://www.bilibili/video/BV1v441157F7from=search&seid=12333251085306036433
下面是我对原代码的分析和改进。
代码思路
数据类型设计:
就是提前设置好起始的X,Y(不是从(0,0) 开始的)长度宽度,定义好上下左右, 后面用到就很方便;
关键是:
- 用一个结构体表示俄罗斯方块的中心块(不是全部),包含它的坐标x y,类型(1到19),对应的颜色,下一个方块类型 ,
- 用一个坐标数组储存每个坐标的状态(0. 空白, 1. 已下落的方块,2.墙壁 ,3. 还在下落的方块 )
游戏整体框架:
乍一看好像挺简单的样子。但是实际操作起来。需要主要注意两个模块。
一. 怎么移动俄罗斯方块
写过贪吃蛇的都知道。或者说没有写过应该也知道:
移动就是把旧的一部分擦掉, 把新的打印出来
怎么打印 / 消除当前方块?
这里我们用一个中心方块(一个结构体类型,储存当前坐标的x,y值,当前方块的类型编号)来代表当前的俄罗斯方块。因为每个俄罗斯方块都是由4个小方块组成的,因此我们可以通过他们和中心方块的相对位置来表示。
我用的(其实是视频中的方法)办法:写一个传递函数, 传入中心块结构体地址,把俄罗斯方块全部的19种类型的排列方式都写好对应的坐标赋值为3,就可以按照各种编号打印出方块的整体了。
这里对19种类型说明一下:
举个栗子,比如:
我们要打印一个田字形:
中心块坐标已经赋值好了是x= tetris->x, y= tetris->y, 那么根据相对位置:
1号是 x=tetris->x+1; y=tetris->y;
2号的 x=tetris->x; y=tetris->y+1;(向下是y+1)
3号的 x=tetris->x+1; y=tetris->y+1;
我们把它们赋值为sign(是1,或者是0,或者是3)
19种慢慢写就好了;
然后我们对标记为3的进行打印, 对标记为0的进行消除;
打印就是对这4×4的矩阵遍历一遍, 如果遇到3,那么打印一个小方块’■’;
如图:
消除同理遍历一遍, 如果遇到0,那么打印一个空格‘ ’。
另外再写这2个函数即可。
二. 怎么判断能否移动
不能移动就代表着:**如果移动了,那么会碰到(或者说重叠)墙壁或者其他方块。**这样子我们可以写一个ifmove函数来判断。
这个函数很长, 我用的是笨办法, 对传入的中心块类型进行对应的判断,
如果有一个值不是0,那么说明不能移动,结构与上面差不多,这里就不赘述了;
虽说还有其他的函数, 但是理解了这两个其他的就很容易上手了。
上代码:*(一些关键的函数说明放在后面)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#include<conio.h>
#define FrameX 13
#define FrameY 3
#define Frame_width 18
#define Frame_hight 20
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define ESC 27
#define SPACE 32
int a[80][80]={0}/*存储每个坐标的状态*/,gr=1/*游戏结束标注*/,co[80][80]={0}/*储存对应的颜色*/; //0 空白, 1 块 2 墙
int speed=200 /*速度*/, score = 0 /*得分*/, highest=0 /*最高得分*/, m=0 /*是否第一个生成的方块*/;
struct Tetris{
int x;
int y;
int flag; //类型序号
int color;
int next; //下一个的类型
};
///
void gotoxy(int x,int y);
void DrawGameframe();
void creat_tetris();
///移动光标
void gotoxy(int x,int y)
{
COORD coord;
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );
}
///改变打印颜色
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色
return 0;
}
///隐藏光标(调用一次就行了)
void hidden_cursor()//隐藏光标
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible=0;//赋1为显示,赋0为隐藏
SetConsoleCursorInfo(hOut,&cci);
}
///标题
void title(){
color(11);
gotoxy(30,2);
printf("趣 味 俄 罗 斯");
color(14);
gotoxy(18,4);
printf("■");
gotoxy(18,5);
printf("■■");
gotoxy(18,6);
printf("■");
color(13);
gotoxy(26,4);
printf("■■");
gotoxy(28,5);
printf("■■");
color(12);
gotoxy(36,4);
printf("■■");
gotoxy(36,5);
printf("■■");
color(11);
gotoxy(44,4);
printf("■");
gotoxy(44,5);
printf("■");
gotoxy(44,6);
printf("■");
gotoxy(44,7);
printf("■");
color(3);
gotoxy(54,4);
printf("■");
gotoxy(50,5);
printf("■■■");
}
void welcome(){ //欢迎界面
int i,j=1;
color(10);
for(i=15;i<60;i++){
for(j=8;j<18;j++){
gotoxy(i,j);
if(j==8||j==17)printf("=");
else if(i==15||i==59)printf("||");}}
gotoxy(26,11);
color(11);
printf("1. 开始游戏");
gotoxy(26,15);
printf("3. 最高记录");
gotoxy(41,11);
printf("2. 游戏说明");
gotoxy(41,15);
printf("4. 退出游戏");
gotoxy(30,19);
color(13);
printf("请选择: [ ]\b\b");
}
void initial_frame(){ //初始化框架
system("cls");
int i,j;
for(i=FrameX;i<=FrameX + Frame_width*2 -2;i+=2)
for(j=FrameY;j<=FrameY + Frame_hight;j++){
gotoxy(i,j);
if(i==FrameX||i==FrameX + Frame_width*2 -2){
a[i][j]=2;
printf("■");
}
else if(j==FrameY + Frame_hight){
a[i][j]=2;
printf("■");
}
else if(j==FrameY){
printf("■"); //上界不需要赋值2
}
}
color(7);
gotoxy(FrameX+Frame_width*2+3,FrameY + 1);
printf("左 A / ←右 D / →");
gotoxy(FrameX+Frame_width*2+3,FrameY + 3);
printf("旋转 ↑ ");
gotoxy(FrameX+Frame_width*2+3,FrameY + 5);
printf("加速 S / ↓");
gotoxy(FrameX+Frame_width*2+3,FrameY + 7);
printf("暂停 SPACE ");
gotoxy(FrameX+Frame_width*2+3,FrameY + 9);
printf("退出 ESC ");
color(9);
gotoxy(FrameX + Frame_width*2 + 3,FrameY+10); //分数
printf("最高记录 : %d",highest);
gotoxy(FrameX + Frame_width*2 + 4,FrameY+11); //分数
printf("SOCRE : %d",score);
gotoxy(FrameX + Frame_width*2 + 3,FrameY+12); //分数
printf("当前速度: %d",500-speed);
gotoxy(FrameX+Frame_width*2+3,FrameY + 13);
color(4);
printf("下一个:");
color(10);
gotoxy(FrameX+Frame_width*2+3,FrameY + 14); //next
printf("***************");
gotoxy(FrameX+Frame_width*2+3,FrameY + 20);
printf("***************");
}
void mark_tetris(struct Tetris *tetris,int sign){ //19种情况
a[tetris->x][tetris->y]=sign;
switch(tetris->flag){
case 1: /* ■ ■
■ ■ */
a[tetris->x][tetris->y + 1] = sign;
a[tetris->x+2][tetris->y + 1] = sign;
a[tetris->x+2][tetris->y] = sign;
break;
case 2: /* ■
■ ■ ■ */
a[tetris->x-2][tetris->y] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x+2][tetris->y-1] = sign;break;
case 3:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x+2][tetris->y+1] = sign;break;
case 4:
a[tetris->x-2][tetris->y] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x-2][tetris->y+1] = sign;break;
case 5:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x-2][tetris->y-1] = sign;break;
case 6: /* ■
■ ■ ■ */
a[tetris->x-2][tetris->y] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x-2][tetris->y-1] = sign;break;
case 7:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x+2][tetris->y-1] = sign;break;
case 8:
a[tetris->x-2][tetris->y] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x+2][tetris->y+1] = sign;break;
case 9:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x-2][tetris->y+1] = sign;break;
case 10: /*■ ■ ■ ■ */
a[tetris->x-2][tetris->y] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x+4][tetris->y] = sign;break;
case 11:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x][tetris->y+2] = sign;break;
case 12: /* ■ ■
■ ■ */
a[tetris->x+2][tetris->y-1] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x][tetris->y+1] = sign;break;
case 13:
a[tetris->x-2][tetris->y] = sign;
a[tetris->x+2][tetris->y+1] = sign;
a[tetris->x][tetris->y+1] = sign;break;
case 14: /* ■ ■
■ ■ */
a[tetris->x+2][tetris->y] = sign;
a[tetris->x+2][tetris->y+1] = sign;
a[tetris->x][tetris->y-1] = sign;break;
case 15:
a[tetris->x+2][tetris->y] = sign;
a[tetris->x-2][tetris->y+1] = sign;
a[tetris->x][tetris->y+1] = sign;break;
case 16: /* ■
■ ■ ■ */
a[tetris->x][tetris->y-1] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x-2][tetris->y] = sign;break;
case 17:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x+2][tetris->y] = sign;break;
case 18:
a[tetris->x][tetris->y+1] = sign;
a[tetris->x+2][tetris->y] = sign;
a[tetris->x-2][tetris->y] = sign;break;
case 19:
a[tetris->x][tetris->y-1] = sign;
a[tetris->x][tetris->y+1] = sign;
a[tetris->x-2][tetris->y] = sign;break;
}
}
void print_tetris(struct Tetris *tetris){
int i,j;
color(tetris->color);
for(i=tetris->x-2;i<=tetris->x+4;i+=2)
for(j=tetris->y-1;j<=tetris->y+2;j++){
if(a[i][j]==3&&j>=FrameY+1){
gotoxy(i,j);
co[i][j]=tetris->color; //颜色数组
printf("■");
}
}
gotoxy(0,FrameY+Frame_hight+1);
}
int ifmove(struct Tetris *tetris){ //按照视频的思路
if(tetris->y>=FrameY+Frame_hight||tetris->x<=FrameX||tetris->x>=FrameX+Frame_width*2-2||a[tetris->x][tetris->y]!=0)
return 0;
switch(tetris->flag){
case 1: /* ■ ■
■ ■ */
if(a[tetris->x][tetris->y + 1] == 0&&
a[tetris->x+2][tetris->y + 1] ==0&&
a[tetris->x+2][tetris->y] ==0)return 1;break;
case 2: /* ■
■ ■ ■ */
if(a[tetris->x-2][tetris->y] ==0&&
a[tetris->x+2][tetris->y] ==0&&
a[tetris->x+2][tetris->y-1] ==0)return 1;break;
case 3:
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x+2][tetris->y+1]==0)return 1;break;
case 4:
if(a[tetris->x-2][tetris->y]==0&&
a[tetris->x+2][tetris->y]==0&&
a[tetris->x-2][tetris->y+1]==0)return 1;break;
case 5:
if(a[tetris->x][tetris->y-1] ==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x-2][tetris->y-1] ==0)return 1;break;
case 6: /* ■
■ ■ ■ */
if(a[tetris->x-2][tetris->y]==0&&
a[tetris->x+2][tetris->y] ==0&&
a[tetris->x-2][tetris->y-1]==0)return 1;break;
case 7:
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x+2][tetris->y-1]==0)return 1;break;
case 8:
if(a[tetris->x-2][tetris->y] ==0&&
a[tetris->x+2][tetris->y]==0&&
a[tetris->x+2][tetris->y+1]==0)return 1;break;
case 9:
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x-2][tetris->y+1]==0)return 1;break;
case 10: /*■ ■ ■ ■ */
if(a[tetris->x-2][tetris->y]==0&&
a[tetris->x+2][tetris->y]==0&&
a[tetris->x+4][tetris->y]==0)return 1;break;
case 11:
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x][tetris->y+2]==0)return 1;break;
case 12: /* ■ ■
■ ■ */
if(a[tetris->x+2][tetris->y-1]==0&&
a[tetris->x+2][tetris->y]==0&&
a[tetris->x][tetris->y+1]==0)return 1;break;
case 13:
if(a[tetris->x-2][tetris->y]==0&&
a[tetris->x+2][tetris->y+1]==0&&
a[tetris->x][tetris->y+1]==0)return 1;break;
case 14: /* ■ ■
■ ■ */
if(a[tetris->x+2][tetris->y]==0&&
a[tetris->x+2][tetris->y+1]==0&&
a[tetris->x][tetris->y-1]==0)return 1;break;
case 15:
if(a[tetris->x+2][tetris->y]==0&&
a[tetris->x-2][tetris->y+1]==0&&
a[tetris->x][tetris->y+1]==0)return 1;break;
case 16: /* ■
■ ■ ■ */
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x+2][tetris->y]==0&&
a[tetris->x-2][tetris->y]==0)return 1;break;
case 17:
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x+2][tetris->y]==0)return 1;break;
case 18:
if(a[tetris->x][tetris->y+1]==0&&
a[tetris->x+2][tetris->y]==0&&
a[tetris->x-2][tetris->y]==0)return 1;break;
case 19:
if(a[tetris->x][tetris->y-1]==0&&
a[tetris->x][tetris->y+1]==0&&
a[tetris->x-2][tetris->y]==0)return 1;break;
}return 0;
}
void creat_tetris(struct Tetris *tetris){ //产生新的方块
int i,j;
if(m++==0)tetris->flag =rand()%19+1; //19种
else tetris->flag=tetris->next;
tetris->next =rand()%19+1; //下一个
tetris->color=rand()%15+1;
tetris->x=FrameX + Frame_width;
tetris->y=FrameY + 1;
if(!ifmove(tetris))gr=0; //游戏结束
else mark_tetris(tetris,3) ; //这些方块已经标记了 3
}
void clean_tetris(struct Tetris *tetris){ //消除原位置方块
int i,j;
for(i=tetris->x-2;i<=tetris->x+4;i+=2)
for(j=tetris->y-1;j<=tetris->y+2;j++){
if(a[i][j]==0&&j>=FrameY+1){
gotoxy(i,j);
co[i][j]=0; //颜色改变
printf(" "); //看情况1个空格或两个
}
}
}
void change_flag(struct Tetris *tetris){ //旋转
mark_tetris(tetris,0);
int X=tetris->x,Y=tetris->y,Flag=tetris->flag;
clean_tetris(tetris);
switch(tetris->flag){
case 5:case 9:case 19:tetris->flag-=3;break;
case 11:case 13:case 15:tetris->flag--;break;
case 1:break;
default:tetris->flag++;break;
}
if(ifmove(tetris)){}
else{
tetris->x=X;
tetris->y=Y;
tetris->flag=Flag; //类型要换回来
}
mark_tetris(tetris,3);
print_tetris(tetris);
}
void print_next(struct Tetris *tetris,int sign){ //打印下一个
Tetris r,*q=&r;
q->flag=tetris->next;
q->x=FrameX + Frame_width*2+7;
q->y=FrameY + 16;
if(sign!=0){
mark_tetris(q,3);
print_tetris(q);
}
else{
mark_tetris(q,0);
clean_tetris(q);
}
}
void fullline(){ //消除满行, 假装没有bug
int i,j,k,l,sign=0;
for(j= FrameY + Frame_hight -1; j >= FrameY+1 ;j--){
sign=0;
for(i=FrameX+2;i<=Frame_width*2+FrameX-4;i+=2){ //x坐标
if(a[i][j]==0) sign=1; //不能消行
}
if(sign==0){
for(k=FrameX+2;k<=Frame_width*2+FrameX-4;k+=2){
gotoxy(k,j);
a[k][j]=0;
co[k][j]=0;
printf(" ");
}
for(l=j-1;l>=FrameY + 1;l--)
for(k=FrameX+2;k<=Frame_width*2+FrameX-4;k+=2){
if(a[k][l]==1&&l+1!=FrameY+Frame_hight){ //可以下移
gotoxy(k,l);
a[k][l]=0;
printf(" "); //因为方块占有两个字符(看情况)
color(co[k][l]);
gotoxy(k,l+1);
co[k][l]=co[k][l-1];
printf("■");
a[k][l+1]=1;
}
}
j++;
gotoxy(FrameX + Frame_width*2 + 12,FrameY+11);
color(12);
printf("%d",score+=100);
if(score%100==3)speed-=100;
gotoxy(FrameX + Frame_width*2 + 13,FrameY+12); //分数
printf("%d",500-speed);
}
}
}
int preservation(){ //保存记录
FILE *fp;
if((fp=fopen("D:\\els_record.txt","rb"))!=NULL){ //用wb+会删掉原数据??
fscanf(fp,"%d",&highest); //读出原记录
fclose(fp);}
if(score <= highest)return 0;
else {
fp=fopen("D:\\els_record.txt","wb+");
fprintf(fp,"%d",score); //写入新纪录
highest = score;
fclose(fp);
}
return 1;
}
void startgame(){ //开始游戏
gr=1;score=0;speed=200,m=0;
int i,j;
for(i=0;i<80;i++)
for(j=0;j<80;j++){ //重新初始化 ,第一次不用
a[i][j]=0;co[i][j]=1;
}
struct Tetris t,*tetris=&t;
int X,Y,A,B;
char ch;
initial_frame();
creat_tetris(tetris);
print_tetris(tetris);
print_next(tetris,0); //清除原来的next
print_next(tetris,1);
while(1)
{
if(kbhit()){
mark_tetris(tetris,0); //一定要先置为0
A=tetris->x;B=tetris->y;X=tetris->x;
ch=getch();
switch(ch){
case UP :case 'w': change_flag(tetris);Y=tetris->y; break;
case DOWN :case 's': Y=(tetris->y+4 < FrameY+Frame_hight?tetris->y = FrameY+Frame_hight-3:tetris->y++);break;
case LEFT :case 'a': X=tetris->x-=2;Y=tetris->y; break; //不知道开始为什么用不了上下左右啊
case RIGHT:case 'd': X=tetris->x+=2;Y=tetris->y; break;
case ESC :gr=0;break;
case SPACE:fflush(stdin);
gotoxy(FrameX+Frame_width-3,FrameY-1);
printf("已经暂停");getchar();
gotoxy(FrameX+Frame_width-3,FrameY-1);
printf(" ");break; //懒得再写函数了
default :Y=tetris->y; break;
}
if(ifmove(tetris)){ //如果可以的话就移动
tetris->x=A;tetris->y=B; //不忘初位
mark_tetris(tetris,0); //保证旋转后也要置为0
clean_tetris(tetris);
tetris->x=X;tetris->y=Y;
mark_tetris(tetris,3);
print_tetris(tetris);
}
else{ //不可以的话就回去
tetris->x=A;
tetris->y=B;
}
}
else //只能下落
{
mark_tetris(tetris,0);
if(tetris->y++,ifmove(tetris)){ //要置为0才能用ifmove()
tetris->y--;
clean_tetris(tetris);
tetris->y++;
mark_tetris(tetris,3);
print_tetris(tetris);
}
else{ //不能下落呢
tetris->y--;
mark_tetris(tetris,1); //已经到头了, 标记为 1
fullline();
print_next(tetris,0); //清除原来的next
creat_tetris(tetris);
print_next(tetris,1); //打印现在的
}
}Sleep(speed);
if(gr==0)break;
}
fflush(stdin);
gotoxy(FrameX+Frame_width-3,FrameY+10);
printf("GAMEOVER!");
preservation();
getch();
gotoxy(0,FrameY+Frame_hight);
}
void game_explain(){
system("cls");
title();
int i,j;
color(13);
for(i=15;i<60;i++){
for(j=8;j<18;j++){
gotoxy(i,j);
if(j==8||j==17)printf("=");
else if(i==15||i==59)printf("||");}}
color(9);
gotoxy(FrameX+Frame_width-8,FrameY + 6);
printf("1. 左 右 上 或 A D S 移动/旋转方块");
gotoxy(FrameX+Frame_width-8,FrameY + 8);
printf("2. [空格键]暂停, [ESC]键退出");
gotoxy(FrameX+Frame_width-8,FrameY + 10);
printf("3. 消除越多, 得分越高噢");
gotoxy(FrameX+Frame_width-8,FrameY + 12);
printf("4. 每行填满方块即可消除");
gotoxy(30,19);
color(13);
fflush(stdin);
printf("[任意键继续]");
getch();
}
void game_record(){
gotoxy(FrameX+Frame_width,FrameY+9);
printf("最高记录: %d",highest);
gotoxy(FrameX+Frame_width,FrameY+11);
printf("[按任意键继续]");
fflush(stdin);
getch();
}
main(){
int k;
srand((unsigned)time(NULL));
hidden_cursor();
label:{
title();
welcome();
preservation();
scanf("%d",&k);
while(k!=4){
switch(k){
case 1: startgame();break;
case 2: game_explain();break;
case 3: game_record();break;
default: break;
}
system("cls");
title();
welcome();
fflush(stdin);
scanf("%d",&k);
}}
printf(" 确认离开[N/Y]:[ ]\b\b");
fflush(stdin);
char ch=getchar();
if(ch=='n'||'N')goto label;
}
几个关键函数(我觉得):
主菜单和游戏边界的话,视频上讲的挺清楚了, 大不了就若干个printf进行调试,需要注意的是每个方块占用2个宽度;
1. 光标移动函数gotoxy():
传递xy坐标就可以把光标移动到那里了;
横向是x,纵向是y,都从0开始,逐行递增;
2. 颜色改变函数color();
输入一个数(1到16)改变字符颜色;
3. 隐藏光标hidden_cursor();
没什么好说的,调用一次就行了;
4. 标记函数 mark_print();
这个函数要传递指针和一个整型sign(可取0,1,3)
函数的作用就是把当前的方块坐标全部赋值为sign;
5. 打印/消除函数
双重循环判断是不是3 / 0;
如果是的话就打印 方块/ 消除(打印空格);
6. 旋转函数change_flag();
先用X,Y储存好原来的坐标(避免失败无法恢复)
然后根据19种情况,加啊,减啊;
然后判断能否旋转,可以的话消除原来的, 打印现在的;
如果不能,就赋值回X,Y,假装没事发生,结束函数;
7. 消除满行函数 fullline();
这个不用传递结构体指针;
用两层循环, 从下到上, 从左到右判断是否有坐标为0(注意x坐标每次加2)
如果没有为0的, 就可以消行了;
消行的操作就是:
先把当前行全部打印空白并且全部赋值0;
再用两层循环, 一个从当前行+1向上循环,一个从左往右:
如果坐标为1,那它下面的坐标赋值1,当前的赋值0,消除, 打印;如此反复;
颜色也要另外改变, 可以保证消除没问题再改;
对了, 消除完一行一定要回到当前行(j++或者j–), 不然如果要消除两行就会忽略一行;
**可能遇到的问题:
1. 颜色同化
每次打印赋值3, 不要都赋值1, 这样原来是1的也会再打印一遍
2.怎么显示下一个方块:
提前生成下一个方块的类型(甚至是颜色),下次生成就读取上次的就好了
3. 穿透bug:
要么是19种排列方式没写对,就是忘记赋值1或者3/0;
更多推荐
C语言—俄罗斯方块(新手向)
发布评论