C语言俄罗斯方块游戏课程设计

本文实例为大家分享了C语言实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下
1、设计流程
C语言俄罗斯方块游戏课程设计
文章图片

2、相关程序

#include#include#include#include#include#include#define LEFT 0x4b00/*键盘码*/#define RIGHT 0x4d00#define DOWN 0x5000#define UP 0x4800#define ESC 0x011b#defineTIMER0x1c/*时钟中断的中断号*/struct Snow{int x; int y; int speed; }snow[100]; typedef struct{int box[4][4]; int color; int next; }SHAPE; int x=0,y=4,form[16][12]={/*x,y是用作记录每个方块的最左上角的编号*/{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1,1},}; /*俄罗斯方块初始化界面*/SHAPE shapes[19]={{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,CYAN,1},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,CYAN,2},{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,CYAN,3},{0,0,0,0,0,0,1,0,1,1,1,0,0,0,0,0,CYAN,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,MAGENTA,5},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,MAGENTA,6},{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,MAGENTA,7},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,MAGENTA,4},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,YELLOW,9},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,YELLOW,8},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,BROWN,11},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,BROWN,10},{0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,WHITE,13},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,WHITE,14},{1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,WHITE,15},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,WHITE,12},{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,RED,17},{1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,RED,16},{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,BLUE,18}}; int TimerCounter=0; int snownum=0; int size; int change1=10; int annal[4][2],score=0,level=0,color,Boxnumber; void plot(); void operation(); void *save1,*save2; void Copy(); void DrawSnow(); void Pr(); voidinterrupt(*oldhandler)(); voidinterruptnewhandler( ){TimerCounter++; TimerCounter==36; oldhandler(); }voidSetTimer(voidinterrupt(*IntProc)()){oldhandler=getvect(TIMER); disable(); /*设置新的时钟中断处理过程时,禁止所有中断*/setvect(TIMER,IntProc); enable(); /*开启中断*/}voidKillTimer(){disable(); setvect(TIMER,oldhandler); enable(); }void main(){int gdriver=DETECT,gmode; SetTimer(newhandler); /*修改时钟中断*/registerbgidriver(EGAVGA_driver); initgraph(&gdriver,&gmode,"c:\\turboc2"); Copy(); DrawSnow(); closegraph(); initgraph(&gdriver,&gmode,"E:\\TC20H\\INCLUDE\\GRAPHICS.H"); /*初始化图形*/plot(); operation(); getch(); }void Copy(){setcolor(0); setfillstyle(SOLID_FILL,15); fillellipse(200,200,4,4); size=imagesize(196,196,204,204); save1=malloc(size); save2=malloc(size); getimage(196,196,204,204,save1); getimage(96,96,104,104,save2); }void Pr(){int fr[]={392,392,440,294,262,262,220,294,392,392,440,532,440,392,262,262,220,294,392,294,262,247,220,196,392,294,330,294,262,262,220,294,330,294,262,294,22,247,220,196}; setcolor(change1/10); settextstyle(0,0,3); outtextxy(100,200,"Welcome to our Game!!!”); sound(fr[change1/10]); }void DrawSnow(){int i; int sx[62]; randomize(); for(i=0; i<62; i++)sx[i]=(i+2)*10; cleardevice(); while(!kbhit()){Pr(); if (snownum!=100){snow[snownum].speed=2+random(5); i=random(62); snow[snownum].x=sx[i]; snow[snownum].y=10-random(100); }for(i=0; i500)snow[i].y=10-random(200); }change1++; if(change1==140)change1=10; }nosound(); }void plot(){int i,j; char ch1[]={24,'-','R','o','l','l','\0'},ch2[]={25,'-','D','o','w','n','w','a','r','d','s','\0'},ch3[]={26,'-','T','u','r','n',' ','L','e','f','t','\0'},ch4[]={27,'-','T','u','r','n',' ','R','i','g','h','t','\0'}; setcolor(LIGHTGRAY); rectangle(200,30,350,255); i=0; while((i++)<10)line(200+i*15,30,200+i*15,255); i=0; while((i++)<15)line(200,30+i*15,350,30+i*15); setcolor(WHITE); rectangle(170,270,390,330); outtextxy(190,280,ch1); outtextxy(270,280,ch2); outtextxy(190,300,ch3); outtextxy(290,300,ch4); outtextxy(190,320,"Esc-Exit"); settextjustify(1,1); outtextxy(390,50,"score"); outtextxy(390,100,"lexel"); outtextxy(390,150,"Next box"); outtextxy(390,65,"0"); outtextxy(390,115,"0"); }void nextboxfun(SHAPE shapes[],int i) {int m,n; for(m=0; m<4; m++)for(n=0; n<4; n++)if(shapes[i].box[m][n]){setfillstyle(1,shapes[i].color); bar(370+n*15+1,180+m*15+1,370+n*15+15-1,180+m*15+15-1); setcolor(LIGHTGRAY); rectangle(370+n*15,180+m*15,370+n*15+15,180+m*15+15); }}int Leftmobile(){int m,k=-1; /*暂时存放annal中的坐标数据,用来判断左移是否成立*/for(m=0; m<4; m++){if(annal[m][0]!=k){if(form[annal[m][0]][annal[m][1]-1])return(0); k=annal[m][0]; }}return(1); }int Rightmobile(){int m,k=-1; for(m=3; m>=0; m--){if(annal[m][0]!=k){if(form[annal[m][0]][annal[m][1]+1])return(0); k=annal[m][0]; }}return(1); }int Downmobile(){int m; for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=2; /*将方块此时的位置设置成2以方便后面的判断*/for(m=0; m<4; m++){if(form[annal[m][0]+1][annal[m][1]]==1)/*如果等于1说明此处已经有方块*/{for(m=0; m<4; m++)/*将原本数值还原*/form[annal[m][0]][annal[m][1]]=1; return(0); }}for(m=0; m<4; m++)/*将原本数值还原*/form[annal[m][0]][annal[m][1]]=1; return(1); }void LeftRedraw(){int m; y--; for(m=0; m<4; m++){setfillstyle(1,BLACK); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*将原图像位置设置为黑色框*/}for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=0; for(m=0; m<4; m++){annal[m][1]--; form[annal[m][0]][annal[m][1]]=1; setfillstyle(1,color); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*在新的位置重绘图像*/}}void RightRedraw(){int m; y++; for(m=0; m<4; m++){setfillstyle(1,BLACK); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*将原图像位置设置为黑色框*/}for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=0; for(m=0; m<4; m++){ annal[m][1]++; form[annal[m][0]][annal[m][1]]=1; setfillstyle(1,color); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); }/*在新的位置重绘图像*/}void DownRedraw(){int m,n; x++; for(m=0; m<4; m++){setfillstyle(1,BLACK); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*将原图像位置设置为黑色框*/}for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=0; for(m=0; m<4; m++){annal[m][0]++; form[annal[m][0]][annal[m][1]]=1; setfillstyle(1,color); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*在新的位置重绘图像*/}}int UPmobile(){int m,n,k; k=shapes[Boxnumber].next; /*k==此方块下一个方块的编号*/for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=2; for(m=0; m<4; m++)for(n=0; n<4; n++){if(form[x+m][y+n]==1&&shapes[k].box[m][n]){for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=1; /*将2还原为1*/return(0); }} for(m=0; m<4; m++)form[annal[m][0]][annal[m][1]]=1; return(1); }void change(){int m,n,k,i=0; k=Boxnumber=shapes[Boxnumber].next; /*等于要转变的方块编号*/for(m=0; m<4; m++){setfillstyle(1,BLACK); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*将原图像位置设置为黑色框*/}for(m=0; m<4; m++)/*将原方块位置改为0*/form[annal[m][0]][annal[m][1]]=0; for(m=0; m<4; m++)/*重新记录新的形状坐标*/for(n=0; n<4; n++)if(shapes[k].box[m][n]){annal[i][0]=x+m; /*annal更新新的坐标*/annal[i][1]=y+n; i++; }for(m=0; m<4; m++)/*将新坐标设置为1并绘图*/{form[annal[m][0]][annal[m][1]]=1; setfillstyle(1,color); bar(200+(annal[m][1]-1)*15+1,30+annal[m][0]*15+1,200+(annal[m][1]-1)*15+15-1,30+annal[m][0]*15+15-1); /*在新的位置重绘图像*/}}void FulllineJudge(){void *p1; int m,n,i,k,p,q; char *ch; if(!(p1=malloc(imagesize(200,30,350,255)))){printf("开辟空间失败\n"); getch(); exit(1); }i=0; for(m=14; m>=0; m--)/*逐行判断是否有满行情况*/{for(n=1; n<=10; n++){if(!form[m][n])/*如果有一个为0那么退出本行的循环*/break; else if(n==10)/*1-10全为1*/{i++; /*用来记录所消行数*/for(p=m; p>=1; p--)for(q=1; q<=10; q++)/*所有行数信息下降1行*/form[p][q]=form[p-1][q]; for(p=1; p<=10; p++)/*最顶行清零*/form[0][p]=0; getimage(200,30,350,30+m*15,p1); putimage(200,45,p1,0); m++; }}if(i==4)/*如果已经消掉4行则不用再进行判断*/break; }if(i==1)/*一次所消行数进行不同分数奖励*/score+=10; if(i==2)score+=30; if(i==3)score+=60; if(i==4)score+=100; setcolor(WHITE); /*绘图部分*/sprintf(ch,"%d",score); setfillstyle(1,BLACK); bar(380,60,400,80); outtextxy(390,65,ch); level=score/500; setfillstyle(1,BLACK); bar(380,110,400,130); sprintf(ch,"%d",level); outtextxy(390,115,ch); free(p1); }void operation(){int newbox,nextbox,m,n,k=1,i,KEY,l,o; o=1; srand((unsigned)time(NULL)); nextbox=rand()%19; while(o){if(k)/*产生新方块*/{x=0,y=4; /*还原x,y*/Boxnumber=newbox=nextbox; nextbox=rand()%19; setfillstyle(1,BLACK); bar(360,160,430,250); nextboxfun(shapes,nextbox); i=0; color=shapes[newbox].color; for(m=0; m<4; m++)for(n=0; n<4; n++)if(shapes[newbox].box[m][n])/*将新方块在俄罗斯方块界面的坐标记录在annal中*/{annal[i][0]=0+m; /*记录坐标*/annal[i][1]=4+n; if(form[0+m][4+n]){setfillstyle(1,BLACK); bar(240,130,310,150); setcolor(RED); outtextxy(275,140,"GAME OVER"); getch(); o=0; }form[0+m][4+n]=1; setfillstyle(1,shapes[newbox].color); bar(200+n*15+1+45,30+m*15+1,200+n*15+15-1+45,30+m*15+15-1); /*将对应的位画上颜色*/setcolor(LIGHTGRAY); rectangle(200+n*15+45,30+m*15,200+n*15+15+45,30+m*15+15); i++; }k=0; }if(bioskey(1))/*读取键盘*/KEY=bioskey(0); elseKEY=0; switch(KEY){case LEFT:/*左*/if(Leftmobile())LeftRedraw(); break; case RIGHT:/*右*/if(Rightmobile())RightRedraw(); break; case DOWN:/*下*/if(Downmobile())DownRedraw(); else{FulllineJudge(); k=1; }break; case UP:/*变形*/if(UPmobile())change(); break; case ESC:o=0; break; }if(TimerCounter>(36-level*2))/*TimerCounter每秒钟增加18*/{TimerCounter=0; if(Downmobile())/*作下降处理*/DownRedraw(); else{FulllineJudge(); k=1; }}}KillTimer(); }

【C语言俄罗斯方块游戏课程设计】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读