曲谱网 > 知识库 >

导航导航

解析一个C语言俄罗斯方块游戏,包你看了就会

发布日期:2021-02-09 16:38:09编辑:音乐人

#写代码来显示这个方块

方块数据,这两个数组其实是两种游戏模式的方块信息,我们只需要分析一种就可以了。

int TGM[7][4]={{0x159D,0x89AB,0x159D,0x89AB},{0x126A,0x4856,0x159A,0x4526},{0x926A,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x5926,0x0156,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x156A,0x4152,0x156A,0x4152}};

int SRS[7][4]={{0x159D,0x89AB,0x26AE,0x4567},{0x0159,0x4856,0x159A,0x4526},{0x8159,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x4815,0x459A,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x0459,0x8596,0x156A,0x4152}};

我们分析这段代码

/***********擦除显示*************/

int Display(int x, int y, int CAC, int Mode)

{

for(j=0;j<=3;j++){

P[j]=CAC&0xF, CAC>>=4;

if(Mode==1){Pos((P[j]>>2)+x,(P[j]&0x3)+y); printf( "■");}

elseif(Mode==0){Pos((P[j]>>2)+x,(P[j]&0x3)+y); printf( " ");}

}

return0;

}

P[j]=CAC&0xF 取到的是 4个bit,然后通过判断这 4个bit决定输出方块的位置。

0100 ----> 对应坐标(1,0)

1000 ----> 对应坐标(2,0)

0101 ----> 对应坐标(1,1)

1001 ----> 对应坐标(2,1)

通过这个坐标,我们会输出这样一个方块

再举个例子

0000 ----> 对应坐标(0,0)

0001 ----> 对应坐标(0,1)

0101 ----> 对应坐标(1,1)

0110 ----> 对应坐标(1,2)

显示方块没有问题了

上面的代码中,如果mode等于0的话,也就是把某个方块从显示中擦除掉。

我们用devc++写的程序,需要知道几个细节。

#构建固定行列的窗口

正常情况,我们显示cmd是一个默认值的黑框「如下图」。

实际上,我们可以用代码来固定cmd的框框大小。

默认代码输出

示例代码:

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <Windows.h>

/**********Main主函数***********/

int main

{

system( "color F1&mode con cols=35 lines=25");

getchar;

return0;

}

程序输出:

#延迟函数的设计

跟其他不同的是,这个程序的延迟没有使用 usleep ,我觉得这也是非常值得称赞的地方,不过空跑cpu,哈哈,是有那么一点调皮。

把延迟放到键值获取的函数中。

/**********按键获取**************/

int Getkey(int N,int T)

{

int start=clock;

if(KEY_V==115){ return115;}

do{

if(kbhit){

KEY_V=(int)(getch);

if(KEY_V<97){KEY_V+=32;}

returnKEY_V;

}

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

} while((clock-start)<T);

dy=1;

return-1;

}

就先简单讲解下这些,至于得分机制,碰撞检测,消除的代码,还没有想好怎么讲明白,需要再花时间剖析剖析。

#试玩一下

#源码 #include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <Windows.h>

/**********初始化参数************/

int i,j,N,T,F,J,X,Y,dx,dy, KEY_V, Cache1,Cache2,NU,NI,RU,RI, P_X,P_Y,POS_H_MAX, LEVEL=1,SCORE=0, P[4], POINT_V[12][22], MARK[21], FLAG[5]={0,0,0,1,0};

int TGM[7][4]={{0x159D,0x89AB,0x159D,0x89AB},{0x126A,0x4856,0x159A,0x4526},{0x926A,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x5926,0x0156,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x156A,0x4152,0x156A,0x4152}};

int SRS[7][4]={{0x159D,0x89AB,0x26AE,0x4567},{0x0159,0x4856,0x159A,0x4526},{0x8159,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x4815,0x459A,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x0459,0x8596,0x156A,0x4152}};

/**********光标位置函数**********/

void Pos(int x,int y)

{

COORD pos;

HANDLE hOutput;

pos.X=2*x;

pos.Y=y;

hOutput=GetStdHandle(STD_OUTPUT_HANDLE);

SetConsoleCursorPosition(hOutput,pos);

}

void HideCursor

{

CONSOLE_CURSOR_INFO cursor_info={1,0};

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);

}

/**********初始化界面************/

void CreatUI

{

int i,j,BOUNDARY;

printf( "┏━━━━━━━━━━┓n");

for(j=1;j<=20;j++) {

if(j==3){ printf( "┃ ┃LEVEL:1n");}

elseif(j==5){ printf( "┃ ┃SCORE:0n");}

elseif(j==7){ printf( "┃ ┃NEXT n");}

else{ printf( "┃ ┃n");}

}

printf( "┗━━━━━━━━━━┛n");

printf( " CopyRight@2016~2018 BY HAPPYn");

for(j=1;j<=21;j++){

for(i=0;i<=11;i++){

BOUNDARY=i*(i-11)*(j-21);

if(BOUNDARY==0){

POINT_V[i][j]=1;

} else{

POINT_V[i][j]=0;

}

}

}

}

/**********按键获取**************/

int Getkey(int N,int T)

{

int start=clock;

if(KEY_V==115){ return115;}

do{

if(kbhit){

KEY_V=(int)(getch);

if(KEY_V<97){KEY_V+=32;}

returnKEY_V;

}

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

printf( "%dn",clock-start);

} while((clock-start)<T);

dy=1;

return-1;

}

/***********块体转置*************/

int Rote(int S, int I)

{

return(F==0)?TGM[S][(I+4)%4]:SRS[S][(I+4)%4];

}

/***********擦除显示*************/

int Display(int x, int y, int CAC, int Mode)

{

for(j=0;j<=3;j++){

P[j]=CAC&0xF, CAC>>=4;

if(Mode==1){Pos((P[j]>>2)+x,(P[j]&0x3)+y); printf( "■");}

elseif(Mode==0){Pos((P[j]>>2)+x,(P[j]&0x3)+y); printf( " ");}

}

return0;

}

/***********固化块体*************/

int DoBlocks

{

//~~~游戏结束

if(Y<2){

Pos(1,22); printf( "GAME OVER!");

exit(0);

}

//~~~固化块体

POS_H_MAX=0, FLAG[3]=1;

for(j=0;j<=3;j++){

P_X=(P[j]>>2)+X,P_Y=(P[j]&0x3)+Y;

if(POS_H_MAX<P_Y){POS_H_MAX=P_Y;}

POINT_V[P_X][P_Y]=1;

}

//~~~关卡得分

for(j=Y;j<=POS_H_MAX;j++){

FLAG[2]=1;

for(i=1;i<=10;i++){

if(POINT_V[i][j]==0){FLAG[2]=0;}

}

if(FLAG[2]){

SCORE+=10,MARK[j]=1;

if(SCORE==400){

SCORE=0,LEVEL+=1,T-=100;

FLAG[4]=1;

}

}

}

//~~~极品消行

for(j=20;j>=5;j--){

if(FLAG[4]){

for(i=1;i<=10;i++){

POINT_V[i][j]=0;

Pos(i,j); printf( " ");

}

}

elseif(MARK[j])

{

MARK[j]=0,J=j-1;

for(N=1;N<=3;N++){

if(MARK[J]){J--;}

}

MARK[J]=1;

for(i=1;i<=10;i++){

Pos(i,j);

if(POINT_V[i][j]=POINT_V[i][J]){

printf( "■");

} else{

printf( " ");

}

}

}

}

FLAG[4]=0;

return0;

}

/***********碰撞检测*************/

int CheckCollision

{

for(j=0;j<=3;j++){

P_X=(P[j]>>2)+X+dx,P_Y=(P[j]&0x3)+Y+dy;

if(POINT_V[P_X][P_Y]){

if(dx!=0){ return1;}

if(dy){

DoBlocks;

Pos(12,3); printf( "LEVEL:%-3d",LEVEL);

Pos(12,5); printf( "SCORE:%-3d",SCORE);

return2;

}

if(KEY_V==119){FLAG[0]=1;}

}

}

return0;

}

unsigned

/***********循环核心*************/

int GameCycle(int N, int T, int F)

{

srand((unsigned)time(NULL));RU=rand%7,RI=(rand%4);

while(1){

if(FLAG[3]){

Display(12,8,Rote(RU,RI),0);

X=4,Y=1, NU=RU,NI=RI, RU=rand%7,RI=(rand%4), FLAG[3]=0,KEY_V=0;

Display(12,8,Rote(RU,RI),1);

Display(X, Y,Rote(NU,NI),1);

}

dx=0,dy=0;

KEY_V=Getkey(N,T);

if(KEY_V==119){

NI++;

Display(X,Y,Rote(NU,NI),2);

}//旋W

elseif(KEY_V==115){dy= 1;}//下S

elseif(KEY_V==97 ){dx=-1;}//左A

elseif(KEY_V==100){dx= 1;}//右D

elseif(KEY_V==112){getch; }//暂停P

elseif(KEY_V==113){ return0;}//退出Q

if(dx!=0 || dy!=0 || KEY_V==119){

if(!CheckCollision){

if(FLAG[0]){

NI--,FLAG[0]=0;

Display(X,Y,Rote(NU,NI),0);

}

elseif(KEY_V==119){

Display(X,Y,Rote(NU,NI-1),0);

} else{

Display(X,Y,Rote(NU,NI),0);

}

Display(X+dx,Y+dy,Rote(NU,NI),1);

X+=dx,Y+=dy;

}

}

}

return0;

}

/**********Main主函数***********/

int main

{

system( "color F0&mode con cols=35 lines=25");

HideCursor;

CreatUI;

GameCycle(10,800,1);

return0;

}

#后记

大家都在看

最新资讯

推荐专题

儿童歌曲大全 儿童故事大全 卡农钢琴曲谱 天空之城钢琴曲谱 梦中的婚礼钢琴曲谱 梁祝》钢琴曲谱 童年的回忆钢琴曲谱 彩云追月钢琴曲谱 康定情歌钢琴曲谱 水边的阿狄丽娜钢琴曲谱 渔舟唱晚古筝曲谱 云水禅心古筝曲谱 高山流水古筝曲谱 浏阳河古筝曲谱 南泥湾古筝曲谱 梅花三弄古筝曲谱 笑傲江湖古筝曲谱 青花瓷古筝曲谱 月光下的凤尾竹葫芦丝曲谱 婚誓葫芦丝曲谱 荷塘月色葫芦丝曲谱 映山红葫芦丝简谱 军港之夜葫芦丝简谱 青花瓷葫芦丝简谱 蝴蝶泉边葫芦丝曲谱 美丽的神话葫芦丝曲谱 致爱丽丝电子琴谱 小苹果 电子琴谱 天空之城 电子琴谱 婚礼进行曲 电子琴谱 茉莉花 电子琴谱 红河谷曲谱