C語(yǔ)言俄羅斯方塊游戲課程設(shè)計(jì)
更新時(shí)間:2021年06月18日 17:23:24 作者:網(wǎng)絡(luò)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言俄羅斯方塊游戲課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊游戲的具體代碼,供大家參考,具體內(nèi)容如下
1、設(shè)計(jì)流程

2、相關(guān)程序
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<time.h>
#include<dos.h>
#include<bios.h>
#define LEFT 0x4b00 /*鍵盤(pán)碼*/
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
#define TIMER 0x1c /* 時(shí)鐘中斷的中斷號(hào) */
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是用作記錄每個(gè)方塊的最左上角的編號(hào)*/
{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(); /* 設(shè)置新的時(shí)鐘中斷處理過(guò)程時(shí),禁止所有中斷 */
setvect(TIMER,IntProc);
enable(); /* 開(kāi)啟中斷 */
}
void KillTimer()
{
disable();
setvect(TIMER,oldhandler);
enable();
}
void main()
{
int gdriver=DETECT,gmode;
SetTimer(newhandler); /* 修改時(shí)鐘中斷 */
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; /*暫時(shí)存放annal中的坐標(biāo)數(shù)據(jù),用來(lái)判斷左移是否成立*/
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; /*將方塊此時(shí)的位置設(shè)置成2以方便后面的判斷*/
for(m=0;m<4;m++)
{
if(form[annal[m][0]+1][annal[m][1]]==1) /*如果等于1說(shuō)明此處已經(jīng)有方塊*/
{
for(m=0;m<4;m++)/*將原本數(shù)值還原*/
form[annal[m][0]][annal[m][1]]=1;
return(0);
}
}
for(m=0;m<4;m++) /*將原本數(shù)值還原*/
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); /*將原圖像位置設(shè)置為黑色框*/
}
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); /*將原圖像位置設(shè)置為黑色框*/
}
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); /*將原圖像位置設(shè)置為黑色框*/
}
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==此方塊下一個(gè)方塊的編號(hào)*/
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;/*等于要轉(zhuǎn)變的方塊編號(hào)*/
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); /*將原圖像位置設(shè)置為黑色框*/
}
for(m=0;m<4;m++) /*將原方塊位置改為0*/
form[annal[m][0]][annal[m][1]]=0;
for(m=0;m<4;m++) /*重新記錄新的形狀坐標(biāo)*/
for(n=0;n<4;n++)
if(shapes[k].box[m][n])
{
annal[i][0]=x+m; /*annal更新新的坐標(biāo)*/
annal[i][1]=y+n;
i++;
}
for(m=0;m<4;m++) /*將新坐標(biāo)設(shè)置為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("開(kāi)辟空間失敗\n");
getch();
exit(1);
}
i=0;
for(m=14;m>=0;m--) /*逐行判斷是否有滿行情況*/
{
for(n=1;n<=10;n++)
{
if(!form[m][n]) /*如果有一個(gè)為0那么退出本行的循環(huán)*/
break;
else if(n==10) /*1-10全為1*/
{
i++; /*用來(lái)記錄所消行數(shù)*/
for(p=m;p>=1;p--)
for(q=1;q<=10;q++) /*所有行數(shù)信息下降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) /*如果已經(jīng)消掉4行則不用再進(jìn)行判斷*/
break;
}
if(i==1) /*一次所消行數(shù)進(jìn)行不同分?jǐn)?shù)獎(jiǎng)勵(lì)*/
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) /*產(chǎn)生新方塊*/
{
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]) /*將新方塊在俄羅斯方塊界面的坐標(biāo)記錄在annal中*/
{
annal[i][0]=0+m; /*記錄坐標(biāo)*/
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);/*將對(duì)應(yīng)的位畫(huà)上顏色*/
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)) /*讀取鍵盤(pán)*/
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();
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言中的函數(shù)指針學(xué)習(xí)筆記
這篇文章主要介紹了C語(yǔ)言中的函數(shù)指針的一些學(xué)習(xí)知識(shí)點(diǎn)記錄,文中作者整理了一些比較interesting的函數(shù)指針用法,需要的朋友可以參考下2016-04-04
C語(yǔ)言 簡(jiǎn)單粗暴的笨方法找水仙花數(shù)
這篇文章介紹了C語(yǔ)言找水仙花數(shù)最原始的笨方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02
用c語(yǔ)言實(shí)現(xiàn)一個(gè)電話薄(附完整代碼)
大家好,本篇文章主要講的是用c語(yǔ)言實(shí)現(xiàn)一個(gè)電話薄(附完整代碼),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01
VS Code遠(yuǎn)程連接Linux服務(wù)器調(diào)試C程序的操作方法
這篇文章主要介紹了VS Code遠(yuǎn)程連接Linux服務(wù)器調(diào)試C程序的操作方法,打開(kāi)遠(yuǎn)程 Linux 服務(wù)器上的文件夾本文以 /root/ 為例,給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12
C++實(shí)現(xiàn)和電腦對(duì)戰(zhàn)三子棋實(shí)例
大家好,本篇文章主要講的是C++實(shí)現(xiàn)和電腦對(duì)戰(zhàn)三子棋實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01

