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

本文实例为大家分享了C语言实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下

1、设计流程

2、相关程序

#include<stdio.h>

#include<stdlib.h>

#include<graphics.h>

#include<time.h>

#include<dos.h>

#include<bios.h>

#define LEFT 0x4b00 /*键盘码*/

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

#define TIMER 0x1c /* 时钟中断的中断号 */

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();

void interrupt ( *oldhandler)();

void interrupt newhandler( )

{

TimerCounter++;

TimerCounter==36;

oldhandler();

}

void SetTimer(void interrupt (*IntProc)())

{

oldhandler=getvect(TIMER);

disable(); /* 设置新的时钟中断处理过程时,禁止所有中断 */

setvect(TIMER,IntProc);

enable(); /* 开启中断 */

}

void KillTimer()

{

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;i<snownum;i++)

putimage(snow[i].x,snow[i].y,save2,COPY_PUT);

Pr();

if(snownum!=100)

snownum++;

/*delay(300);*/

setfillstyle(SOLID_FILL,15);

for(i=0;i<snownum;i++)

{

snow[i].y+=snow[i].speed;

putimage(snow[i].x,snow[i].y,save1,COPY_PUT);

if(snow[i].y>500)

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);

else

KEY=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语言俄罗斯方块游戏课程设计 的全部内容, 来源链接: utcz.com/p/246288.html

回到顶部