admin管理员组文章数量:1794759
C语言—俄罗斯方块(新手向)
下面我记录下我用C语言写俄罗斯方块的方法和思路。 方法是参考b站的教学视频并且进行一定的改进。 这个是用控制台实现的,不需要用到graphics.h头文件, 对各种编译器应该都是兼容的。 原视频链接:www.bilibili/video/BV1v441157F7from=search&seid=12333251085306036433 下面是我对原代码的分析和改进。
代码思路数据类型设计: 就是提前设置好起始的X,Y(不是从(0,0) 开始的)长度宽度,定义好上下左右, 后面用到就很方便; 关键是:
乍一看好像挺简单的样子。但是实际操作起来。需要主要注意两个模块。 一. 怎么移动俄罗斯方块 写过贪吃蛇的都知道。或者说没有写过应该也知道: 移动就是把旧的一部分擦掉, 把新的打印出来 怎么打印 / 消除当前方块? 这里我们用一个中心方块(一个结构体类型,储存当前坐标的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语言—俄罗斯方块(新手向) 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686895485a115516.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论