九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。 -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。 -毛泽东
/*以下程序在Tc2.0下编译运行*/ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> /*定义键盘扫描码*/ #define k_down 20480 #define k_left 19200 #define k_right 19712 #define k_space 14624 #define k_esc 283 #define k_p 6512 /*以下定义常用的常数*/ #define M_Max 20 /*游戏框大小为20*10*/ #define N_Max 10 #define Pc_Delay 10 /*延时的基准数*/ #define Down_Sp 18000 /*方块的下落速度默认分频数(对delay(Pc_Delay)函数分频)*/
typedef enum {D_Zero,D_Russ}Ar_Type; /*将矩阵内数据枚举*/ Ar_Type Gm_Array[M_Max][N_Max]; /*游戏矩阵*/ struct { int x; int y; /*当前处理方块的位置*/ int score; int speed; /*玩家分数和速度分频数(每升一级:减15层,speed减少2000)*/ int type; int dict; /*type:当前方块的形状类型(用于查表),dict:当前控制的方向*/ int nextt; /*下一个方块的形状类型*/ }S_Status; /*游戏状态*/ enum {M_Conti,M_Pause,M_Exit,M_Gover}Mess; /*定义消息:M_Conti:游戏进行中,M_Pause:暂停,M_Exit:退出游戏,M_Gover:游戏结束*/ int Ru_Sp[7][4][4]={{{4,5,6,9},{0,4,5,8},{5,8,9,10},{1,4,5,9}},{{4,5,6,8},{0,4,8,9},{6,8,9,10},{0,1,5,9}}, {{4,5,6,10},{0,1,4,8},{4,8,9,10},{1,5,8,9}},{{5,6,8,9},{0,4,5,9},{0,0,0,0},{0,0,0,0}}, {{4,5,9,10},{1,4,5,8},{0,0,0,0},{0,0,0,0}},{{1,5,9,13},{4,5,6,7},{0,0,0,0},{0,0,0,0}}, {{0,1,4,5},{0,0,0,0},{0,0,0,0},{0,0,0,0}}};/*定义静态表,表中存储方块形状数据*/ char format_GO[10]; /*用于在屏幕上格式化输出数字*/
void opengraph(void); /*打开图形模式并注册图形驱动*/ void Draw_Node(int,int,Ar_Type); /*在屏幕上画一个小方块,游戏中的方块由四个这样的小方块组成*/ void Init_Gm(void); /*初始化游戏数据*/ void Draw_Shape(int,int,int,int,Ar_Type); /*查表画出游戏中不同种类和形状的方块*/ int Rand_New(void); /*当一个方块下落完成后,随机产生新的方块*/ int Check_Move_Ok(int,int,int); /*当用左,下,右键控制游戏方块的时候检查是否可以控制*/ void Russ_Move(int); /*用于控制方块左,下,右的移动,该函数有键盘扫描调用*/ void Russ_Rot(void); /*对方块旋转*/ void Dec_Level(void); /*减层函数*/ void Gm_Over(void); /*方块到顶的时候游戏结束,这个函数处理游戏结束事件*/
void main() { int keyid,d_sp=Down_Sp; randomize(); /*初始化随机数发生器*/ opengraph(); /*打开图形模式并注册图形驱动*/ setcolor(WHITE); /*以下画游戏图形框架*/ rectangle(180,70,380,470); setcolor(YELLOW); settextstyle(0,0,1); outtextxy(50,40,"Esc:Quit ||| Left,Down,Right:Move ||| p:Pause ||| Space:Rotate"); settextstyle(0,0,2); outtextxy(130,10,"Russia FK (By STN_LCD!)"); outtextxy(400,200,"Score:"); outtextxy(400,250,"Speed:"); Init_Gm(); /*初始化游戏数据*/ Rand_New(); /*产生第一个方块*/ while(Mess!=M_Exit) { /*以下进行键盘扫描和消息的循环*/ if(bioskey(1)) { keyid=bioskey(0); switch(keyid) { case k_left: if(Mess==M_Conti) Russ_Move(-1); /*-1表示向左移动方块*/ break; case k_down: if(Mess==M_Conti) Russ_Move(0); /*0表示向下移动方块*/ break; case k_right: if(Mess==M_Conti) Russ_Move(1); /*1表示向右移动方块*/ break; case k_p: if(Mess==M_Conti) /*暂停!(再按一下p游戏将继续)*/ Mess=M_Pause,setfillstyle(0,BLACK),bar(400,300,600,450),outtextxy(410,320,"Pause!"), settextstyle(0,0,1),outtextxy(410,350,"Press 'p' to continue..."),settextstyle(0,0,2); else Mess=M_Conti,setfillstyle(0,BLACK),bar(400,300,600,450); break; case k_space: /*旋转方块*/ if(Mess==M_Conti) Russ_Rot(); break; case k_esc: /*退出游戏*/ if(Mess==M_Conti) Mess=M_Exit,outtextxy(100,150,"Press anykey to quit!"),getch(); break; } } delay(Pc_Delay); /*方块延时基时间*/ if(Mess==M_Conti&&!--d_sp) Russ_Move(0), d_sp=S_Status.speed;/*d_sp用于分频控制*/ if(Mess==M_Gover) Gm_Over(); /*如果为“游戏结束”消息,转去执行游戏结束函数*/ } closegraph(); }
void opengraph(void) {/*打开图形模式,并注册图形驱动*/ int gdriver=VGA,gmode=VGAHI; registerbgidriver(EGAVGA_driver); initgraph(&gdriver,&gmode,""); }
void Draw_Node(int x,int y,Ar_Type type) { /*在屏幕上画一个小方块*/ int x_x=x*20+70; int y_y=y*20+180; if(type==D_Zero) setfillstyle(SOLID_FILL,BLACK); else if(type==D_Russ) setfillstyle(SOLID_FILL,YELLOW); bar(y_y+2,x_x+2,y_y+18,x_x+18); }
void Draw_Shape(int x,int y,int type,int d,Ar_Type hd) {/*查表画出游戏中不同种类和形状的方块*/ int i,xt,yt,temp; for(i=0;i<4;i++) { temp=Ru_Sp[type][d][i]; xt=x+temp/4; yt=y+temp%4; Draw_Node(xt,yt,hd); } }
int Rand_New(void) { int i,temp; for(i=0;i<4;i++) { temp=Ru_Sp[S_Status.nextt][0][i]; if(Gm_Array[temp/4][4+temp%4]) return 0;/*gameover*/ } setfillstyle(SOLID_FILL,BLACK); bar(385,70,480,170); S_Status.type=S_Status.nextt; S_Status.nextt=rand()%7; S_Status.x=0; S_Status.y=4; S_Status.dict=0; Draw_Shape(0,4,S_Status.type,0,D_Russ); Draw_Shape(0,11,S_Status.nextt,0,D_Russ); return 1; }
void Init_Gm(void) { int i,j; S_Status.nextt=rand()%7; setfillstyle(0,BLACK); bar(500,190,630,270); S_Status.score=0; S_Status.speed=Down_Sp; outtextxy(500,200,itoa(S_Status.score,format_GO,10)); outtextxy(500,250,itoa((int)((Down_Sp-S_Status.speed)/100),format_GO,10)); for(i=0;i<M_Max;i++) for(j=0;j<N_Max;j++) Gm_Array[i][j]=D_Zero; }
int Check_Move_Ok(int x,int y,int dict) {/*dict = -1(left),0(down),1(right)*/ int i,temp,xt,yt,flag=0; if(!dict) ++x; else y=y+dict; for(i=0;i<4;i++) { temp=Ru_Sp[S_Status.type][S_Status.dict][i]; xt=x+temp/4; yt=y+temp%4; if(xt<0||xt>=M_Max||yt<0||yt>=N_Max||Gm_Array[xt][yt]==D_Russ) { if(dict) { ++xt; yt=yt-dict; if(xt<0||xt>=M_Max||yt<0||yt>=N_Max||Gm_Array[xt][yt]==D_Russ) return 2; } flag=1; } } return flag; /*return 2:在左右的时候都不行,return 1:在左右的时候向下可以,return 0:OK*/ }
void Russ_Move(int dict) { int i,temp,ok; ok=Check_Move_Ok(S_Status.x,S_Status.y,dict); if(!ok) { Draw_Shape(S_Status.x,S_Status.y,S_Status.type,S_Status.dict,D_Zero); if(!dict) ++S_Status.x; else S_Status.y=S_Status.y+dict; Draw_Shape(S_Status.x,S_Status.y,S_Status.type,S_Status.dict,D_Russ); } else if((dict&&ok==2)||(!dict&&ok==1)) { for(i=0;i<4;i++) { temp=Ru_Sp[S_Status.type][S_Status.dict][i]; Gm_Array[S_Status.x+temp/4][S_Status.y+temp%4]=D_Russ; } Dec_Level(); if(!Rand_New()) Mess=M_Gover; } }
void Russ_Rot(void) { int i,flag=1,temp,xt,yt,tmp1; if(S_Status.type<=2) tmp1=(S_Status.dict+1)%4; else if(S_Status.type<=5) tmp1=(S_Status.dict+1)%2; else tmp1=S_Status.dict; for(i=0;i<4&&flag;i++) { temp=Ru_Sp[S_Status.type][tmp1][i]; xt=S_Status.x+temp/4; yt=S_Status.y+temp%4; if(xt<0||xt>=M_Max||yt<0||yt>=N_Max||Gm_Array[xt][yt]==D_Russ) flag=0; } if(flag) { Draw_Shape(S_Status.x,S_Status.y,S_Status.type,S_Status.dict,D_Zero); S_Status.dict=tmp1; Draw_Shape(S_Status.x,S_Status.y,S_Status.type,S_Status.dict,D_Russ); } }
void Dec_Level(void) { int i,j,k,num,up,down; up=S_Status.x; if(S_Status.type<=4) down=up+2; else if(S_Status.type<=5) down=up+3; else down=up+1; for(i=up;i<=down;i++) { num=0; for(j=0;j<N_Max;j++) {num+=Gm_Array[i][j];} if(num==N_Max) { for(j=0;j<N_Max;++j) { for(k=i-1;k>=0;--k) { Draw_Node(k+1,j,Gm_Array[k][j]); Gm_Array[k+1][j]=Gm_Array[k][j]; } Gm_Array[0][j]=D_Zero; Draw_Node(0,j,D_Zero); } setfillstyle(0,BLACK); bar(500,190,630,220); ++S_Status.score; outtextxy(500,200,itoa(S_Status.score,format_GO,10)); if(S_Status.speed>4000&&(S_Status.score%15==0)) { bar(500,240,630,270); S_Status.speed-=2000; outtextxy(500,250,itoa((int)((Down_Sp-S_Status.speed)/2000),format_GO,10)); } } } }
void Gm_Over(void) { char ch; int i,j; outtextxy(410,320,"Game Over!"); settextstyle(0,0,1); outtextxy(410,350,"Press Y/y to restart!"); outtextxy(470,360,"N/n to Quit!"); settextstyle(0,0,2); do {ch=getch(); }while(ch!='y'&&ch!='Y'&&ch!='n'&&ch!='N'); if(ch=='n'||ch=='N') { Mess=M_Exit; outtextxy(100,150,"Press anykey to quit!"); getch(); } else { Mess=M_Conti; setfillstyle(0,BLACK); bar(181,71,379,469); bar(400,300,600,450); Init_Gm(); Rand_New(); } }