学曲谱,请上曲谱自学网!

解析一个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)

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

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

再举个例子

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

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

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

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

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

显示方块没有问题了

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

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

#构建固定行列的窗口

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

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

默认代码输出

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

示例代码:

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

}

程序输出:

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

#延迟函数的设计

跟其他不同的是,这个程序的延迟没有使用 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;

}

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

#试玩一下

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

#源码 #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;

}

#后记

跑跑卡丁车手游x长安欧尚X5怎么玩 过大年开新车联动活动攻略

人格解体新手怎么通关 人格解体新手通关技巧总汇

热门曲谱

Copyright © 2014-2019 曲谱大全(www.qpzxw.com)曲谱自学网版权所有 备案号:皖ICP备2021004734号-1

版权声明:曲谱网所有曲谱及资料均为作者提供或网友推荐收集整理而来,仅供爱好者学习和研究使用,版权归原作者所有。

联系邮箱:qupudaquanhezuo@gmail.com