1. C语言设计俄罗斯方块
1、将游戏区域划分为18行*10列的棋盘,设立一个布尔型的二维数组变量,以表示棋盘上各个地方是否有方块。
2、用4个顶点代表各种不同形状的方块,一旦方块在游戏区域中,就把对应的布尔型二维数组变量置为真,表示该方格已经有方块了。
3、如上做方便方块移动是否会碰撞的判断。
4、代码已经修正了一个小BUG。
5、压缩包中的文件是未经修改的源代码,此处的代码为最新。
6、方向键上为改变形状,下为直接落到底部。p键为暂停(或者Pause键)。
2. 求C语言俄罗斯方块代码
俄罗斯方块C源代码
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#defineZL4 //坐标增量,不使游戏窗口靠边
#defineWID36 //游戏窗口的宽度
#defineHEI20 //游戏窗口的高度
inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用于记住和转换方块变量的值
inta[60][60]={0}; //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框
intb[4]; //标记4个"口"方块:1有,0无,类似开关
intx,y,level,score,speed; //方块中心位置的x,y坐标,游戏等级、得分和游戏速度
intflag,next; //当前要操作的方块类型序号,下一个方块类型序号
voidgtxy(intm,intn); //以下声明要用到的自编函数
voidgflag(); //获得下一方块序号
voidcsh(); //初始化界面
voidstart(); //开始部分
voidprfk(); //打印方块
voidclfk(); //清除方块
voidmkfk(); //制作方块
voidkeyD(); //按键操作
intifmov(); //判断方块能否移动或变体
void clHA(); //清除满行的方块
voidclNEXT(); //清除边框外的NEXT方块
intmain()
{csh();
while(1)
{start();//开始部分
while(1)
{prfk();
Sleep(speed); //延时
clfk();
Tb=x;Tc=flag;//临存当前x坐标和序号,以备撤销操作
keyD();
y++;//方块向下移动
if(ifmov()==0){y--;prfk();dlHA();break;}//不可动放下,删行,跨出循环
}
for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方块触到框顶
if(j==0){system("cls");gtxy(10,10);printf("游戏结束!");getch();break;}
clNEXT(); //清除框外的NEXT方块
}
return0;
}
voidgtxy(intm,intn)//控制光标移动
{COORDpos;//定义变量
pos.X=m;//横坐标
pos.Y=n;//纵坐标
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
voidcsh()//初始化界面
{gtxy(ZL+WID/2-5,ZL-2);printf("俄罗斯方块");//打印游戏名称
gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//打印菜单信息
gtxy(ZL+WID+3,ZL+13);printf("**********");
gtxy(ZL+WID+3,ZL+15);printf("Esc:退出游戏");
gtxy(ZL+WID+3,ZL+17);printf("↑键:变体");
gtxy(ZL+WID+3,ZL+19);printf("空格:暂停游戏");
gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//打印框角
gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");
a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//记住有图案
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//打印上横框
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框
for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左竖框记住有图案
for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框
CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隐藏光标的设置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
level=1;score=0;speed=400;
gflag();flag=next;//获得一个当前方块序号
}
voidgflag() //获得下一个方块的序号
{srand((unsigned)time(NULL));next=rand()%19+1; }
voidstart()//开始部分
{gflag();Ta=flag;flag=next;//保存当前方块序号,将下一方块序号临时操作
x=ZL+WID+6;y=ZL+10;prfk();//给x,y赋值,在框外打印出下一方块
flag=Ta;x=ZL+WID/2;y=ZL-1;//取回当前方块序号,并给x,y赋值
}
voidprfk()//打印俄罗斯方块
{for(i=0;i<4;i++){b[i]=1;}//数组b[4]每个元素的值都为1
mkfk();//制作俄罗斯方块
for(i=x-2;i<=x+4;i+=2)//打印方块
{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}
gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下打印菜单信息
gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);
gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);
}
voidclfk()//清除俄罗斯方块
{for(i=0;i<4;i++){b[i]=0;}//数组b[4]每个元素的值都为0
mkfk();//制作俄罗斯方块
for(i=x-2;i<=x+4;i+=2)//清除方块
{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}
}
voidmkfk()//制作俄罗斯方块
{a[x][y]=b[0];//方块中心位置状态:1-有,0-无
switch(flag)//共6大类,19种小类型
{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方块
case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直线方块:----
case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直线方块:|
case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方块
case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字顺时针转90度
case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字顺转180度
case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字顺转270度
case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方块
case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字顺转90度
case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字顺转180度
case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字顺转270度
case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方块
case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字顺转90度
case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字顺转180度
case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字顺转270度
case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方块
case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字顺转90度
case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字顺转180度
case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字顺转270度
}
}
voidkeyD()//按键操作
{if(kbhit())
{intkey;
key=getch();
if(key==224)
{key=getch();
if(key==75){x-=2;}//按下左方向键,中心横坐标减2
if(key==77){x+=2;}//按下右方向键,中心横坐标加2
if(key==72)//按下向上方向键,方块变体
{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}
if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}
if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}
if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}
if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}
}
if(key==32)//按空格键,暂停
{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格键,继续游戏
if(ifmov()==0){x=Tb;flag=Tc;} //如果不可动,撤销上面操作
else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可动,执行操作
}
}
intifmov()//判断能否移动
{if(a[x][y]!=0){return0;}//方块中心处有图案返回0,不可移动
else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||
(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||
(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||
(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||
(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||
(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||
(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||
(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||
(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||
(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||
( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||
( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||
(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||
( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||
(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0
&&a[x+2][y]==0))){return1;}
}
return0; //其它情况返回0
}
voidclNEXT() //清除框外的NEXT方块
{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}
void clHA() //清除满行的方块
{intk,Hang=0; //k是某行方块个数,Hang是删除的方块行数
for(j=ZL+HEI-1;j>=ZL+1;j--)//当某行有WID/2-2个方块时,则为满行
{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)
{if(a[i][j]==1)//竖坐标从下往上,横坐标由左至右依次判断是否满行
{k++; //下面将操作删除行
if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)
{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}
for(k=j-1;k>ZL;k--)
{for(i=ZL+2;i<ZL+WID-2;i+=2)//已删行数上面有方块,先清除再全部下移一行
{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;
gtxy(i,k+1);printf("□");}}
}
j++;//方块下移后,重新判断删除行是否满行
Hang++;//记录删除方块的行数
}
}
}
}
score+=100*Hang; //每删除一行,得100分
if(Hang>0&&(score%500==0||score/500>level-1)) //得分满500速度加快升一级
{speed-=20;level++;if(speed<200)speed+=20; }
}
3. 一个简单的c语言写的俄罗斯方块程序
1、考虑怎么存储俄罗斯方块
俄罗斯方块的形状一共有19种类型,如果拿数组来表示的话,可能会比较会浪费空间(网上有很多实现代码)
考虑到每种方块形状的范围是4 *4的小方块,用 字模点阵的方式来存储,即设置一个4行4列的数组,元素置1即代表这个位置有小
方块,元素置0即代表这个位置无小方块,这个整个的4*4的数组组成俄罗斯方块的形状。
1000
1000
1100
0000
上述4*4来表示L形状的方块。
4*4 =16 bit 正好为short类型,所以每一个方块可以用一个short类型的数据来表示。
我们把俄罗斯方块点阵的数位存在rockArray中,我们可以事先把这19种方块的字模点阵自己转化成十六进制,然后在rockArray数组的初始化时赋值进去。
但是这种方式扩展性不好,每当有一种新方块时需要改动,
所以可以写一个配置文件来表示19种方块。(RockShape.ini)
@###@###@@######1234
从配置文件中读取方块的类型的代码在(Init.h的ReadRock函数中)在下面3中解释下代码如何实现
2如何画出方块
可以使用EasyX库来画出简单的图形,
EasyX库是在VC下实现TC的简单绘图功能的一个库,这个库很容易学会(直接 网络EasyX库,里面有详细的教程)
那么如何画出方块,方块已经存储到一个short类型中了
从short中读取出,可以用一个掩码mask = 1来与short的每个bit位相与,结果为1,则画出一个小方块;
函数声明:
void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed)1
参数1:表示在数组中的下标,取出short类型的方块表示数据
参数2:表示当前坐标,即画出方块的左上角的坐标x,y
参数3:true表示画出该方块,false 表示擦除该方块。
//方块在图形窗口中的位置(即定位4*4大块的左上角坐标) typedef struct LOCATE
{ int left; int top;
} RockLocation_t;123456
3如何实现同一种类型方块的翻转,
在按‘↑’时应该翻转同一种类型的方块,
比如下面的横杆和竖杆
@###@###@###@###@@@@############****1234567891011
可以假想成静态循环链表来实现这种方式
使同一种类型的方块循环起来,
用一个struct结构来表示一种方块
typedef struct ROCK
{ //用来表示方块的形状(每一个字节是8位,用每4位表示方块中的一行)
unsigned short rockShapeBits; int nextRockIndex; //下一个方块,在数组中的下标 } RockType;123456
定义一个RockType类型的数组来存储19种方块
RockType RockArray[19] = { (0, 0) };
当我们按“↑”时,把传入画方块函数DrawRock中的rockIndex变为当前方块结构体中的nextRockIndex即可。
简单解释下ReadRock函数的实现:当读取到空行的时候表示 一种方块已经读取完毕,当读取到****行时 表示同一种类型的方块读取完毕,具体看代码实现,代码中具体的注释
4、主要游戏实现的逻辑
贴一个预览图吧
注:上述预览图的游戏控制区和游戏显示区在Draw.h的DrawGameWindow()函数实现的
(1)在初始位置画出方块,在预览区画出下一次的方块
(2)方块有两种行为:响应键盘命令UserHitKeyBoard(),自由下落
如果敲击键盘了(w ,a ,s ,d, )空格表示暂停,如果在规定时间内没有敲击键盘的话,方块自由下落一个单位
if (kbhit()) //如果敲击键盘了 就处理按键
{
userHit = getch();
UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);
} //没有 就自动下移一个单位 :不能用else,因为可能按键不是上下左右
DWORD newtime = GetTickCount(); if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE)
{
oldtime = newtime;
DisplayRock(curRockIndex, &curRockLocation, false);
curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格
}1234567891011121314
(3)当方块落地(即不能下移了)时,判断是否满行,如果满行则消除,然后再判断游戏是否结束,游戏结束的话,直接退出游戏
判断满行:FullLine()函数,从最底下的一行开始判断,直到遇到一行空行,
while (count != xROCK_SQUARE_NUM ) //遇到空行 14
{
linefull = true; count = 0; for (int i = 1; i <= xROCK_SQUARE_NUM; ++i)
{ if (game_board[idx][i] == 0)
{
linefull = false; count++;
}
} if (linefull) //满行,消除当前行,更新分数
{
DelCurLine(idx);//消除满行
game_socres += 3;
UpdateSocres(game_socres);
idx++;//因为下面要减1
}
idx--;
}
(4)消除满行
将要删除的满行擦除:即将方块化成与背景色相同的,该代码为黑色
然后将上面的一行向下移,移一行删除一行,直到遇到空行
具体看代码的具体实现 game.h
void DelCurLine(int rowIdx)
(4)判断方块是否能移动
在game.h中实现
bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction)1
**比较当前位置的坐标(左上角)开始,能否放下rockIndex的方块。
注:f_direction为”↑”的话,则传入的rockIndex为下一个方块**
如果不能移动的话,给游戏game_board设置标记表示该位置被占有
//全局变量-游戏板的状态描述(即表示当前界面哪些位置有方块) //0表示没有,1表示有(多加了两行和两列,形成一个围墙,便于判断方块是否能够移动) int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };123
实现过程遇到的一些问题
(1)在快速下落的时候,可能方块会掉出围墙的范围内,
快速下落是使方块每次下落2个单位距离。
在判断不能下落时,使当前坐标的top即y减去一个单位的距离
(2)遇到多行满行时消除不了,
在判断满行时,循环找出满行,找出一个满行,就消除一行,然后继续判断是否满行,直到遇到空行
4. 怎么用c语言做俄罗斯方块游戏 要详解
/*俄罗斯方块*/
#include "Conio.h"
#include "graphics.h"
#include<stdio.h>
#include<stdlib.h>
#define closegr closegraph
#define WALL 9
#define BACK 6
#define PTC 4
#define DELC 15
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
void init();
void draw(int,int,int);
void drawpart(int);
void drawdp(int);
void newpart();
void start();
void sport();
void changedp();
int check(int);
int delmap();
int map[12][20],pat,gameover,i,j,k,w=1,speed=1,lingp=0;
long int score=0;
char scorec[20],speedc[10],lingpc[10];
struct node{
int x[4];
int y[4];
};
struct node part,dp;
void initgr(void) /* BGI初始化 */
{
int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */
registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */
initgraph(&gd, &gm, "");
}
int main(void)
{
char ch;
init();
start();
while((ch=getch())!='Q'&&ch!='q')
{} /* 暂停一下,看看前面绘图代码的运行结果 */
closegr(); /* 恢复TEXT屏幕模式 */
return 0;
}
void init()
{
initgr(); /* BGI初始化 */
randomize();
setbkcolor(BACK);
setcolor(4);
setviewport(130,40,510,440,1);/*设置可活动区域*/
pat=0;
gameover=0;
sprintf(scorec,"SCORE:%ld",score);
outtextxy(250,300,scorec);
sprintf(speedc,"SPEED:%d",speed);
outtextxy(250,200,speedc);
sprintf(lingpc,"LINE:%d",lingp);
outtextxy(250,250,lingpc);
for(i=0;i<=380;i+=20)
{
draw(0,i,WALL);
draw(220,i,WALL);
draw(360,i,WALL);
}
for(i=20;i<=360;i+=20)
{
draw(i,0,WALL);
draw(i,380,WALL);
}
for(i=0;i<12;i++)
for(j=0;j<20;j++)
if(i==0||i==11||j==0||j==19)
map[i][j]=1;
else
map[i][j]=0;
newpart();
drawpart(PTC);
}
void draw(int x,int y,int p)/*画小元件*/
{
setcolor(p);
rectangle(x+1,y+1,x+18,y+18);
rectangle(x+3,y+3,x+16,y+16);
}
void newpart()
{
int ran;
ran=rand()%7;
switch(ran)
{
case 0:
{
for(i=0;i<4;i++)
{
part.x[i]=i;
part.y[i]=0;
}
break;
}
case 1:
{
for(i=0;i<3;i++)
{
part.x[i]=i;
part.y[i]=1;
}
part.x[3]=2;
part.y[3]=0;
break;
}
case 2:
{
for(i=0;i<3;i++)
{
part.x[i]=i;
part.y[i]=0;
}
part.x[3]=2;
part.y[3]=1;
break;
}
case 3:
{
for(i=0;i<3;i++)
{
part.x[i]=i;
part.y[i]=0;
}
part.x[3]=1;
part.y[3]=1;
break;
}
case 4:
{
for(i=0;i<2;i++)
{
part.x[i]=i;
part.y[i]=0;
}
for(i=2;i<4;i++)
{
part.x[i]=i-1;
part.y[i]=1;
}
break;
}
case 5:
{
for(i=0;i<2;i++)
{
part.x[i]=i;
part.y[i]=1;
}
for(i=2;i<4;i++)
{
part.x[i]=i-1;
part.y[i]=0;
}
break;
}
case 6:
{
for(i=0;i<2;i++)
{
part.x[i]=i;
part.y[i]=0;
part.x[i+2]=i;
part.y[i+2]=1;
}
break;
}
}
}
void drawpart(int color)
{
for(i=0;i<4;i++)
draw(260+(part.x[i])*20,40+(part.y[i])*20,color);
}
void drawdp(int color)
{
for(i=0;i<4;i++)
draw((dp.x[i])*20,(dp.y[i])*20,color);
}
void start()
{
while(gameover==0)
{
sport();
if(delmap()==1)
{
setcolor(BACK);
outtextxy(250,300,scorec);
outtextxy(250,200,speedc);
sprintf(scorec,"SCORE:%ld",score);
sprintf(speedc,"SPEED:%d",speed);
setcolor(PTC);
outtextxy(250,300,scorec);
outtextxy(250,200,speedc);
}
setcolor(BACK);
outtextxy(250,250,lingpc);
sprintf(lingpc,"LINE:%d",lingp);
setcolor(PTC);
outtextxy(250,250,lingpc);
}
setcolor(15);
settextstyle(0,0,4);
outtextxy(50,180,"GAME OVER");
settextstyle(0,0,1);
outtextxy(70,220,"PRESS Q TO QUIT GAME.");
}
void sport()
{
int delayn=0,key,delayt;
drawpart(BACK);
pat=0;
for(i=0;i<4;i++)
{
dp.x[i]=part.x[i]+4;
dp.y[i]=part.y[i]+2;
}
if(check(1)==1){gameover=1;pat=1;}
newpart();
drawpart(PTC);
drawdp(PTC);
while(pat==0)
{
while(!kbhit())
{
if(speed<=9)
delayt=3300-speed*300;
else
delayt=600;
delay(delayt*w);
delayn++;
if(delayn%100)
continue;
delayn=0;
if(check(1)==1)
{
for(i=0;i<4;i++)
map[dp.x[i]][dp.y[i]]=1;
pat=1;
break;
}
drawdp(BACK);
changedp(1);
drawdp(PTC);
}
w=1;
if(pat==1)break;
key=bioskey(0);
if(key==ESC)
{
exit(0);
}
else if(key==DOWN)
{
w=0;
}
else if(key==LEFT)
{
if(check(2)==0){drawdp(BACK);changedp(2);drawdp(PTC); }
}
else if(key==RIGHT)
{
if(check(0)==0){drawdp(BACK);changedp(0);drawdp(PTC); }
}
else if(key==UP)
{
if(check(3)==0){drawdp(BACK);changedp(3);drawdp(PTC);}
}
}
}
void changedp(int p)
{
int ex,rx,ry;
switch(p)
{
case 1:
{
for(i=0;i<4;i++)
dp.y[i]++;
break;
}
case 2:
{
for(i=0;i<4;i++)
dp.x[i]--;
break;
}
case 0:
{
for(i=0;i<4;i++)
dp.x[i]++;
break;
}
case 3:
{
for(i=0;i<4;i++)
if(i!=1)
{
ex=dp.x[i];
dp.x[i]=dp.x[1]+dp.y[1]-dp.y[i];
dp.y[i]=dp.y[1]-dp.x[1]+ex;
}
break;
}
}
}
int check(int p)
{
struct node chp;
switch(p)
{
case 1:
{
for(i=0;i<4;i++)
if(map[dp.x[i]][dp.y[i]+1]==1)
return 1;
break;
}
case 2:
{
for(i=0;i<4;i++)
if(map[dp.x[i]-1][dp.y[i]]==1)
return 1;
break;
}
case 0:
{
for(i=0;i<4;i++)
if(map[dp.x[i]+1][dp.y[i]]==1)
return 1;
break;
}
case 3:
{
for(i=0;i<4;i++)
{
chp.x[i]=dp.x[i];
chp.y[i]=dp.y[i];
}
changedp(3);
for(j=0;j<4;j++)
if(map[dp.x[j]][dp.y[j]]==1)
{
for(i=0;i<4;i++)
{
dp.x[i]=chp.x[i];
dp.y[i]=chp.y[i];
}
return 1;
}
for(i=0;i<4;i++)
{
dp.x[i]=chp.x[i];
dp.y[i]=chp.y[i];
}
break;
}
}
return 0;
}
int delmap()
{
int sum,m=0;
for(i=18;i>1;i--)
{
sum=0;
for(j=1;j<=10;j++)
sum+=map[j][i];
if(sum==10)
{
m++;
for(k=1;k<=10;k++)
{
delay(6000);
draw(k*20,i*20,DELC);
}
for(k=i;k>1;k--)
for(j=1;j<=10;j++)
{
map[j][k]=map[j][k-1];
if(map[j][k]==1)draw(j*20,k*20,PTC);
else draw(j*20,k*20,BACK);
}
i++;
}
}
switch(m)
{
case 0:break;
case 1:
{score+=100;break;}
case 2:
{score+=300;break;}
case 3:
{score+=1000;break;}
case 4:
{score+=1600;break;}
}
speed=(int)score/10000+1;
lingp+=m;
if(m==0)return 0;
else return 1;
}
5. 如何用C语言编一个俄罗斯方块
游戏界面预览:
菜单预览:
自定义每个小方块颜色功能界面:
游戏主要有四部分组成:Square类,Block类,gameField类,游戏引擎
Square类:
这个类描述的对象是组成大方块中的每个小正方形实体。
类设计:
class Square
{
public Point location; //小方块的坐标
public Size size; //小方块大小
public Color foreColor; //小方块前景色
public Color backColor; //小方块背景色
public Square(Size initSize,Color initForeColor,Color initBackColor) //构造函数
{ ……}
public void Draw(System.IntPtr winHandle) //在指定设备上画方块
{ …… }
public void Erase(System.IntPtr winHandle)//擦除方块
{ …… }
}
Block类:
这个类描述的对象是某一个大方块的实体。每个大方块由四个小正方形组成,一共有7种组合方式。这个类需要实现一个大方块实体所有的属性和动作。包括:方块的形状,位置,方块左移,右移,下移,旋转等。
类设计:
class Block
{
public Square square1; //组成block的四个小方块
public Square square2;
public Square square3;
public Square square4; private const int squareSize = GameField.SquareSize; //小方块的边长
public enum BlockTypes
{
undefined = 0,
square = 1,
line = 2,
J = 3,
L = 4,
T = 5,
Z = 6,
S = 7
};//一共有7种形状
public BlockTypes blockType; //方块的形状
//七个小方块的颜色数组
private Color foreColor;
private Color backColor;
//方块的方向
public enum RotateDirections
{
North = 1,
East = 2,
South = 3,
West = 4
};
public RotateDirections myRotation = RotateDirections.North;
public Block(Point thisLocation,BlockTypes bType)
{ ……}
//含有自定义颜色的重载
public Block(Point thisLocation, BlockTypes bType,Color fc,Color bc)
{ ……} /*画方块*/
public void Draw(System.IntPtr winHandle)
{…… }
/*擦方块*/
public void Erase(System.IntPtr winHandle)
{…… } /*移动*/
public bool down()
{……}
public bool left()
{……}
public bool right()
{……}
/*旋转block*/
public void Rotate()
{……}
/*检测是否到顶*/
public int Top()
{……}
}
GameField类:
这个类描述的对象是游戏场景实体,包括场景的背景色,大小,方块是否还可以移动,以及场景中填满一行的检测等。
类设计:
class GameField
{
public const int width = 20; //场景的宽,以方块个数为单位
public const int height = 30;
public const int SquareSize = 15; //每个四分之一小方块的边长
public static Color BackColor; //场景的背景色
public static System.IntPtr winHandle; //场景的handle
public static Color[] BlockForeColor ={ Color.Blue, Color.Beige, Color.DarkKhaki, Color.DarkMagenta, Color.DarkOliveGreen, Color.DarkOrange, Color.DarkRed };
public static Color[] BlockBackColor ={ Color.LightCyan, Color.DarkSeaGreen, Color.Beige, Color.Beige, Color.Beige, Color.Beige, Color.Beige };
public static bool isChanged=false; //设置是否被更改的标志位
public static SoundPlayer sound = new SoundPlayer(); //播放声音 public static Square[,] arriveBlock = new Square[width, height]; //保存已经不能再下落了的方块
public static int[] arrBitBlock=new int[height]; //位数组:当某个位置有方块时,该行的该位为1
private const int bitEmpty = 0x0; //0000 0000 0000 0000 0000
private const int bitFull = 0xFFFFF; //1111 1111 1111 1111 1111 /*检测某个位置是否为空*/
public static bool isEmpty(int x, int y)
{……}
/*将方块停住*/
public static void stopSquare(Square sq, int x, int y)
{……}
/*检测行是否满
* 返回:成功消除的行数和 (方便统计分数)
*/
public static int CheckLines()
{ ……}
/*播放声音*/
public static void PlaySound(string soundstr)
{……}
/*重画*/
public static void Redraw()
{ …… }
//结束
}
游戏引擎:
游戏引擎正如其名,就像一个发动机一样让游戏不间断运行。本游戏中就是让方块以一定的速度下落。并响应键盘事件,实行左右移动,和向下加速功能。(代码见源码)
声音播放:
音效是游戏不可缺少的一部分。在.Net2.0中已经提供了一个类来播放声音。在using System.Media;命名空间。
本游戏中播放声音的代码如下:(在 GameField类中)
using System.Media;
public static SoundPlayer sound = new SoundPlayer();
/*播放声音*/
public static void PlaySound(string soundstr)
{
switch (soundstr)
{
case "FinishOneLine": //消除一行的声音
if (!File.Exists("FinishOneLine.wav")) return;
sound.SoundLocation = "FinishOneLine.wav";
break;
case "CanNotDo": //当无法操作时
if (!File.Exists("CanNotDo.wav")) return;
sound.SoundLocation = "CanNotDo.wav";
break;
}
sound.Play();
}
要播放的时候调用PlaySound()方法即可。
其实步骤很简单,先引用System.Media空间,然后创建一个SoundPlayer 对象,用SoundLocation 属性设置声音文件的地址,然后调用Play()方法即可播放。不过注意,这个类可以播放的声音格式只有Wav文件。
保存游戏设置:
在游戏中经常要保存用户自定义的设置。本游戏通过写进ini文件来保存。
主要代码如:
/*加载窗体时从配置文件Setting.ini中读取游戏设置*/
private void getSettings()
{
if (!File.Exists("Setting.ini"))
return;
FileStream fs = new FileStream("Setting.ini", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamReader sr = new StreamReader(fs);
string line1=sr.ReadLine();
string line2=sr.ReadLine();
string line3=sr.ReadLine();
if (line1 != null && line1.Split('=').Length > 1)
{
GameField.BackColor = Color.FromArgb(int.Parse(line1.Split('=')[1]));
picBackGround.BackColor = GameField.BackColor;
}
if (line2 != null && line2.Split('=').Length > 1)
GameField.BlockForeColor = strToColor(line2.Split('=')[1]);
if (line3 != null && line3.Split('=').Length > 1)
GameField.BlockBackColor = strToColor(line3.Split('=')[1]);
sr.Close();
fs.Close();
}
/*如果游戏设置被更改,将新的设置保存到Setting.ini*/
private void saveSettings()
{
FileStream fs = new FileStream("Setting.ini", FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("GameFieldColor="+GameField.BackColor.ToArgb());
sw.WriteLine("BlockFroeColor=" + colorToStr(GameField.BlockForeColor));
sw.WriteLine("BlockBackColor=" + colorToStr(GameField.BlockBackColor));
sw.Flush();
sw.Close();
fs.Close();
}
要源码+QQ348199903
6. C语言中俄罗斯方块怎么做
当时做得时候工具用turboC
2.0开发的,课程设计.
具体的代码网上可以搜到很多,我就不细说了.
当时编码的时候,通常把俄罗斯方块的编码工作分成几个小块完成,我描述一下:
1.
当前下落块的控制逻辑.
2.
用户输入的控制逻辑,这个是用中断控制,比如bioskey()函数去获取当前的输入值,具体的我记不清了.
3.
判断一行是否能够消去逻辑(公共环境是用20*12的数组来存放.)
4.
难度以及其他配置模块管理,模块划分清楚之后,编码较为容易.
希望可以有帮助:
)
7. 用C语言俄罗斯方块制作
下面的源码可以直接在tc下运行
现在打算在vc下用mfc试着编一下
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>
#define VK_LEFT 0x4b00
#define VK_RIGHT 0x4d00
#define VK_DOWN 0x5000
#define VK_UP 0x4800
#define VK_ESC 0x011b
#define TIMER 0x1c
#define MAX_BOX 19
#define BSIZE 20
#define Sys_x 160
#define Sys_y 25
#define Horizontal_boxs 10
#define Vertical_boxs 15
#define Begin_boxs_x Horizontal_boxs/2
#define FgColor 3
#define BgColor 0
#define LeftWin_x Sys_x+Horizontal_boxs*BSIZE+46
#define false 0
#define true 1
#define MoveLeft 1
#define MoveRight 2
#define MoveDown 3
#define MoveRoll 4
int current_box_numb;
int Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;
int flag_newbox=false;
int speed=1;
int score=0;
int speed_step=30;
void interrupt(*oldtimer)(void);
struct BOARD
{
int var;
int color;
}Table_board[Vertical_boxs][Horizontal_boxs];
struct SHAPE
{
char box[2];
int color;
int next;
};
struct SHAPE shapes[MAX_BOX]=
{
{0x88,0xc0,CYAN,1},
{0xe8,0x0,CYAN,2},
{0xc4,0x40,CYAN,3},
{0x2e,0x0,CYAN,0},
{0x44,0xc0,MAGENTA,5},
{0x8e,0x0,MAGENTA,6},
{0xc8,0x80,MAGENTA,7},
{0xe2,0x0,MAGENTA,4},
{0x8c,0x40,YELLOW,9},
{0x6c,0x0,YELLOW,8},
{0x4c,0x80,BROWN,11},
{0xc6,0x0,BROWN,10},
{0x4e,0x0,WHITE,13},
{0x8c,0x80,WHITE,14},
{0xe4,0x0,WHITE,15},
{0x4c,0x40,WHITE,12},
{0x88,0x88,RED,17},
{0xf0,0x0,RED,16},
{0xcc,0x0,BLUE,18},
};
unsigned int TimerCounter=0;
void initialize(int,int,int,int);
void interrupt newtimer(void);
void SetTimer(void interrupt(*IntProc)(void));
void KillTimer(void);
void ShowScore(int);
void ShowSpeed(int);
void show_help(int,int);
void setFullRow(int);
int DelFullRow(int);
void show_box(int,int,int,int);
void EraseBox(int,int,int);
void ErasePreBox(int,int,int);
int MkNextBox(int);
int MoveAble(int,int,int,int);
void main()
{
int GameOver=0;
int key,nextbox;
int Currentaction=0;
int gd=VGA,gm=VGAHI,errorcode;
initgraph(&gd,&gm,"");
errorcode=graphresult();
if(errorcode!=grOk)
{
printf("\nNotice:Graphics error: %s\n",grapherrormsg(errorcode));
printf("Press any key to quit!");
getch();
exit(1);
}
setbkcolor(BgColor);
setcolor(FgColor);
randomize();
SetTimer(newtimer);
initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);
nextbox=MkNextBox(-1);
show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color);
show_box(LeftWin_x,Curbox_y+320,nextbox,shapes[nextbox].color);
show_help(Sys_x,Curbox_y+320);
getch();
while (1)
{
Currentaction=0;
flag_newbox=false;
if(bioskey(1))
{
key=bioskey(0);
}
else
{
key=0;
}
switch(key)
{
case VK_LEFT:
if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft))
{
EraseBox(Curbox_x,Curbox_y,current_box_numb);
Curbox_x-=BSIZE;
Currentaction=MoveLeft;
}
break;
case VK_RIGHT:
if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight))
{
EraseBox(Curbox_x,Curbox_y,current_box_numb);
Curbox_x+=BSIZE;
Currentaction=MoveRight;
}
break;
case VK_DOWN:
if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown))
{
EraseBox(Curbox_x,Curbox_y,current_box_numb);
Curbox_y+=BSIZE;
Currentaction=MoveDown;
}
else
flag_newbox=true;
break;
case VK_UP:
if(MoveAble(Curbox_x,Curbox_y,shapes[current_box_numb].next,MoveRoll))
{
EraseBox(Curbox_x,Curbox_y,current_box_numb);
current_box_numb=shapes[current_box_numb].next;
Currentaction=MoveLeft;
}
break;
case VK_ESC:
GameOver=1;
break;
default:
break;
}
8. 怎样用c语言编写俄罗斯方块程序
俄罗斯方块C源代码
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#defineZL4 //坐标增量,不使游戏窗口靠边
#defineWID36 //游戏窗口的宽度
#defineHEI20 //游戏窗口的高度
inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用于记住和转换方块变量的值
inta[60][60]={0}; //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框
intb[4]; //标记4个"口"方块:1有,0无,类似开关
intx,y,level,score,speed; //方块中心位置的x,y坐标,游戏等级、得分和游戏速度
intflag,next; //当前要操作的方块类型序号,下一个方块类型序号
voidgtxy(intm,intn); //以下声明要用到的自编函数
voidgflag(); //获得下一方块序号
voidcsh(); //初始化界面
voidstart(); //开始部分
voidprfk(); //打印方块
voidclfk(); //清除方块
voidmkfk(); //制作方块
voidkeyD(); //按键操作
intifmov(); //判断方块能否移动或变体
void clHA(); //清除满行的方块
voidclNEXT(); //清除边框外的NEXT方块
intmain()
{csh();
while(1)
{start();//开始部分
while(1)
{prfk();
Sleep(speed); //延时
clfk();
Tb=x;Tc=flag;//临存当前x坐标和序号,以备撤销操作
keyD();
y++;//方块向下移动
if(ifmov()==0){y--;prfk();dlHA();break;}//不可动放下,删行,跨出循环
}
for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方块触到框顶
if(j==0){system("cls");gtxy(10,10);printf("游戏结束!");getch();break;}
clNEXT(); //清除框外的NEXT方块
}
return0;
}
voidgtxy(intm,intn)//控制光标移动
{COORDpos;//定义变量
pos.X=m;//横坐标
pos.Y=n;//纵坐标
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
voidcsh()//初始化界面
{gtxy(ZL+WID/2-5,ZL-2);printf("俄罗斯方块");//打印游戏名称
gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//打印菜单信息
gtxy(ZL+WID+3,ZL+13);printf("**********");
gtxy(ZL+WID+3,ZL+15);printf("Esc:退出游戏");
gtxy(ZL+WID+3,ZL+17);printf("↑键:变体");
gtxy(ZL+WID+3,ZL+19);printf("空格:暂停游戏");
gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//打印框角
gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");
a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//记住有图案
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//打印上横框
for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框
for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左竖框记住有图案
for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框
CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隐藏光标的设置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
level=1;score=0;speed=400;
gflag();flag=next;//获得一个当前方块序号
}
voidgflag() //获得下一个方块的序号
{srand((unsigned)time(NULL));next=rand()%19+1; }
voidstart()//开始部分
{gflag();Ta=flag;flag=next;//保存当前方块序号,将下一方块序号临时操作
x=ZL+WID+6;y=ZL+10;prfk();//给x,y赋值,在框外打印出下一方块
flag=Ta;x=ZL+WID/2;y=ZL-1;//取回当前方块序号,并给x,y赋值
}
voidprfk()//打印俄罗斯方块
{for(i=0;i<4;i++){b[i]=1;}//数组b[4]每个元素的值都为1
mkfk();//制作俄罗斯方块
for(i=x-2;i<=x+4;i+=2)//打印方块
{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}
gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下打印菜单信息
gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);
gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);
}
voidclfk()//清除俄罗斯方块
{for(i=0;i<4;i++){b[i]=0;}//数组b[4]每个元素的值都为0
mkfk();//制作俄罗斯方块
for(i=x-2;i<=x+4;i+=2)//清除方块
{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}
}
voidmkfk()//制作俄罗斯方块
{a[x][y]=b[0];//方块中心位置状态:1-有,0-无
switch(flag)//共6大类,19种小类型
{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方块
case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直线方块:----
case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直线方块:|
case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方块
case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字顺时针转90度
case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字顺转180度
case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字顺转270度
case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方块
case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字顺转90度
case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字顺转180度
case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字顺转270度
case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方块
case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字顺转90度
case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字顺转180度
case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字顺转270度
case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方块
case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字顺转90度
case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字顺转180度
case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字顺转270度
}
}
voidkeyD()//按键操作
{if(kbhit())
{intkey;
key=getch();
if(key==224)
{key=getch();
if(key==75){x-=2;}//按下左方向键,中心横坐标减2
if(key==77){x+=2;}//按下右方向键,中心横坐标加2
if(key==72)//按下向上方向键,方块变体
{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}
if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}
if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}
if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}
if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}
}
if(key==32)//按空格键,暂停
{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格键,继续游戏
if(ifmov()==0){x=Tb;flag=Tc;} //如果不可动,撤销上面操作
else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可动,执行操作
}
}
intifmov()//判断能否移动
{if(a[x][y]!=0){return0;}//方块中心处有图案返回0,不可移动
else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||
(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||
(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||
(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||
(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||
(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||
(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||
(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||
(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||
(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||
(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||
( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||
( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||
(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||
( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||
(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||
(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0
&&a[x+2][y]==0))){return1;}
}
return0; //其它情况返回0
}
voidclNEXT() //清除框外的NEXT方块
{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}
void clHA() //清除满行的方块
{intk,Hang=0; //k是某行方块个数,Hang是删除的方块行数
for(j=ZL+HEI-1;j>=ZL+1;j--)//当某行有WID/2-2个方块时,则为满行
{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)
{if(a[i][j]==1)//竖坐标从下往上,横坐标由左至右依次判断是否满行
{k++; //下面将操作删除行
if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)
{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}
for(k=j-1;k>ZL;k--)
{for(i=ZL+2;i<ZL+WID-2;i+=2)//已删行数上面有方块,先清除再全部下移一行
{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;
gtxy(i,k+1);printf("□");}}
}
j++;//方块下移后,重新判断删除行是否满行
Hang++;//记录删除方块的行数
}
}
}
}
score+=100*Hang; //每删除一行,得100分
if(Hang>0&&(score%500==0||score/500>level-1)) //得分满500速度加快升一级
{speed-=20;level++;if(speed<200)speed+=20; }
}
9. 用c语言编写俄罗斯方块的程序
这里把游戏的关键设计放在三个盒子和一个坐标上:
大盒子:一个两维数组,记录着方块点阵的开与关(把游戏的舞台想象
成一个点阵),在下面也把这个东西称为地图
两个5*5小盒子:两维数组,一个盛放着正在下落的方块,一个盛放在
下一个下落的方块(即next),当然这两个也必须想象成一个点阵:如长条
的点阵为:
00000
00100
00100
00100
00100
现在你只要有这么一个概念:一个不断定时下落的小盒子从大盒子顶
部下降到底部,之后再将next盒子放在下落盒子,再进行下一轮的下落...
中间的控制等尚不要太着急.
现在面临着一个问题:
下落的盒子和地图之间要怎么联系起来?
一个好的方法是再定义一个坐标:x,y,保存着小盒子左上角在地图上对应
的下标(位置),即当x
=
0,
y
=
0时,小盒子处于地图的左上部.如此,当
小盒子需要移动时,即只须要改变x,y的值.
现在说说旋转.
小盒子保存着当前下落形状的点阵,那么旋转就只须要将这个点阵旋
转90度:例如:
00000
00000
00100
00000
00100
->
01111
00100
00000
00100
00000
这一点实现起来还是不太难的.
判断碰撞
通常这种情况只须要在有移动小盒或旋转盒子时发生:也即点阵非空
是互斥的,当小盒要向下移(x++)时,如果小盒里的点阵与地图上的点阵(非
空的地方)重叠,则不能下移,(卡住了),旋转则转换后的形状与地图有冲
突则要放弃旋转.
到了这里,你应该有一个大概的了解了,至于怎样在屏幕上画出来,这
个是比较简单的,下面的代码会慢慢与你解释.
*/
/*接下一贴*/
10. 利用C语言制作俄罗斯方块,需要学什么
首先要学习C语言,这个是基础。 然后如果必须用C的话,还要学习C语言的图形界面编程。 网上资料做多,而且容易得到的就是Turbo C的,因为Turbo C可以写图形的程序。 如果你不想限制在Turbo C,想用其他编译器也可以编译的程序的话,你可以学习SDL。SDL的教程里,也可以找到俄罗斯方块。当然,你也可以学习OpenGL的俄罗斯方块。你网络 SDL 俄罗斯方块或者 OpenGL 俄罗斯方块都很容易找到例程。 总之, 第一,你必须先学好C语言; 然后,你要学习一种C语言的图形库; 最后,你要学习俄罗斯方块的程序设计方法。 这样,你就可以编写一个自己的,有声有色的俄罗斯方块了。