| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1949 人关注过本帖, 1 人收藏
标题:TC2.0+graphics编的俄罗斯方块游戏
只看楼主 加入收藏
yuleol
Rank: 1
等 级:新手上路
帖 子:58
专家分:0
注 册:2005-12-10
收藏(1)
 问题点数:0 回复次数:7 
TC2.0+graphics编的俄罗斯方块游戏

俄罗斯方块V1.0
游戏用四个方向键控制:
左右键分别左移一格,右移一格;
上键变形(顺时针调整方块方向);
下键方块直接落底!
空格键暂停,ESC键退出游戏;

windows2000+tc2.0+graphics.h下编译!

游戏存在一个严重的问题:
键盘中断直接采用TC库函数bioskey(),如果长按或
连续多次按一个键的话会导致其它按键严重滞后~~~这个问题
暂时没找到解决方法~如果有谁知道解决办法联系我!

附件里包含以下四个文件:

Egavga.bgi:TC的图形驱动
FK.jpg:游戏画面截图
fk.c:游戏源代码
fk.exe:编译后的游戏,双击可直接运行!

作者:yuleol E_mail:kuworm@126.com (2006.7.7)

bA4EP39G.rar (51.9 KB) TC2.0+graphics编的俄罗斯方块游戏



#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <bios.h>
#include <dos.h>
#define SPACE 0x3920
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define ESC 0x011b
#define WIDTH 12 /*定义容器宽度*/
#define HIGH 22 /*定义容器高度*/
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 18
#endif
struct container{
int left;
int top;
int right;
int bottom;
int sign; /*记号,0表示空白,1表示墙*/
}lab[HIGH][WIDTH];/*定义大容器存储结构*/

struct nextcontainer{
int left;
int top;
int right;
int bottom;
int sign; /*记号,0表示空白,1表示墙*/
}next[6][6];/*定义下一个方块存储结构*/

int BOX[19][4][4]={
{
{2,2,2,2}, /*方块0*/
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
},{
{2,0,0,0},/*方块1*/
{2,0,0,0},
{2,0,0,0},
{2,0,0,0}
},{
{3,3,3,0}, /*方块2*/
{3,0,0,0},
{0,0,0,0},
{0,0,0,0}
},{
{3,3,0,0},/*方块3*/
{0,3,0,0},
{0,3,0,0},
{0,0,0,0}
},{
{0,0,3,0},/*方块4*/
{3,3,3,0},
{0,0,0,0},
{0,0,0,0}
},{
{3,0,0,0}, /*方块5*/
{3,0,0,0},
{3,3,0,0},
{0,0,0,0}
},{
{4,4,4,0}, /*方块6*/
{0,0,4,0},
{0,0,0,0},
{0,0,0,0}

},{
{0,4,0,0},/*方块7*/
{0,4,0,0},
{4,4,0,0},
{0,0,0,0}

},{
{4,0,0,0}, /*方块8*/
{4,4,4,0},
{0,0,0,0},
{0,0,0,0}

},{
{4,4,0,0}, /*方块9*/
{4,0,0,0},
{4,0,0,0},
{0,0,0,0}

},{
{5,5,5,0}, /*方块10*/
{0,5,0,0},
{0,0,0,0},
{0,0,0,0}
},{
{0,5,0,0}, /*方块11*/
{5,5,0,0},
{0,5,0,0},
{0,0,0,0}
},{
{0,5,0,0}, /*方块12*/
{5,5,5,0},
{0,0,0,0},
{0,0,0,0}
},{
{5,0,0,0}, /*方块13*/
{5,5,0,0},
{5,0,0,0},
{0,0,0,0}
},{
{6,6,0,0}, /*方块14*/
{0,6,6,0},
{0,0,0,0},
{0,0,0,0}
},{
{0,6,0,0}, /*方块15*/
{6,6,0,0},
{6,0,0,0},
{0,0,0,0}
},{
{0,7,7,0},/*方块16*/
{7,7,0,0},
{0,0,0,0},
{0,0,0,0}
},{
{7,0,0,0},/*方块17*/
{7,7,0,0},
{0,7,0,0},
{0,0,0,0}
},{
{8,8,0,0},/*方块18*/
{8,8,0,0},
{0,0,0,0},
{0,0,0,0}
}
};

int score,grade; /*定义分数和等级*/

/*初始化图形显示*/
int initialize(void)
{
int gdriver, gmode,errorcode;
gdriver=VGA;
gmode=VGAHI;
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
return 0;
}

void my_delay(unsigned long ms)
{ /*延时函数*/
double start_time = (double)clock() / CLOCKS_PER_SEC * 1000;
while ( (double)clock() / CLOCKS_PER_SEC * 1000 - start_time < ms ) ;
}

void showcontainer(int i,int j,int flag)
{/*显示容器函数*/
int sign;
if(flag==0)
sign=lab[i][j].sign;
else
sign=next[i][j].sign;
switch(sign)
{
case 0: setfillstyle(SOLID_FILL,LIGHTBLUE);break;
case 1: setfillstyle(SOLID_FILL,RED); break;
case 2: setfillstyle(SOLID_FILL,LIGHTCYAN);break;
case 3: setfillstyle(SOLID_FILL,BLUE);break;
case 4: setfillstyle(SOLID_FILL,GREEN);break;
case 5: setfillstyle(SOLID_FILL,DARKGRAY);break;
case 6: setfillstyle(SOLID_FILL,YELLOW);break;
case 7: setfillstyle(SOLID_FILL,MAGENTA);break;
case 8: setfillstyle(SOLID_FILL,LIGHTGREEN);break;
}
if(flag==0)
bar(lab[i][j].left,lab[i][j].top,lab[i][j].right,lab[i][j].bottom);
else
bar(next[i][j].left,next[i][j].top,next[i][j].right,next[i][j].bottom);
}


void initialcontainer()
{ /*生成容器函数*/
int i,j,leftx=10,topy=10,rightx=30,bottomy=30;
for(i=0;i<HIGH;i++)
for(j=0;j<WIDTH;j++)
{
lab[i][j].left=leftx+j*20;
lab[i][j].top=topy+i*20;
lab[i][j].right=rightx+j*20;
lab[i][j].bottom=bottomy+i*20;
lab[i][j].sign=0;
}
for(i=0;i<HIGH;i++)
{
lab[i][0].sign=1;
lab[i][WIDTH-1].sign=1;
}
for(j=0;j<WIDTH;j++)
{
lab[0][j].sign=1;
lab[HIGH-1][j].sign=1;
}
for(i=0;i<HIGH;i++)
for(j=0;j<WIDTH;j++)
showcontainer(i,j,0);
}
void initialnext()
{ /*初始化下一个方块的显示*/
int i,j,leftx=280,topy=30,rightx=300,bottomy=50;
for(i=0;i<6;i++)
for(j=0;j<6;j++)
{
next[i][j].left=leftx+j*20;
next[i][j].top=topy+i*20;
next[i][j].right=rightx+j*20;
next[i][j].bottom=bottomy+i*20;
next[i][j].sign=0;
}
for(i=0;i<6;i++)
{
next[i][0].sign=1;
next[i][6-1].sign=1;
}
for(j=0;j<6;j++)
{
next[0][j].sign=1;
next[6-1][j].sign=1;
}
for(i=0;i<6;i++)
for(j=0;j<6;j++)
showcontainer(i,j,1);
}

void showscore()
{/*显示分数和等及*/
char b[10],*p=b;
p=itoa(score,p,10);
setfillstyle(SOLID_FILL,BLUE);
bar(280,160, 400, 200);
moveto(290,170);
outtext("score:");
outtext(p);
p=itoa(grade,p,10);
moveto(290,185);
outtext("grade:");
outtext(p);
}

void shownext(int n)
{ /*显示下一个方块*/
int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(BOX[n][i][j]!=0)
{
next[i+1][j+1].sign=BOX[n][i][j];
showcontainer(i+1,j+1,1);
}
else
{
next[i+1][j+1].sign=0;
showcontainer(i+1,j+1,1);
}
}

int checkbox(int n,int x,int y)
{ /*检查方块是否可以放置*/
int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(BOX[n][i][j]!=0 && lab[i+x][j+y].sign!=0)
return 0;
return 1;
}

void showbox(int n,int x,int y)
{/*显示方块*/
int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(BOX[n][i][j]!=0 && lab[i+x][j+y].sign==0)
{
lab[i+x][j+y].sign=BOX[n][i][j];
showcontainer(i+x,j+y,0);
}
}

void clearbox(int n,int x,int y)
{/*擦除方块显示*/
int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(BOX[n][i][j]!=0)
{
lab[i+x][j+y].sign=0;
showcontainer(i+x,j+y,0);
}
}

void clearrow(int x)
{ /*删除一行*/
int i,j;
for(i=x;i>1;i--)
for(j=1;j<11;j++)
{
lab[i][j].sign=lab[i-1][j].sign;
showcontainer(i,j,0);
}
for(j=1;j<11;j++)
{
lab[1][j].sign=0;
showcontainer(i,j,0);
}
}

void checkrow(int x)
{/*检查是否一行已满*/
int i,n=0;
for(i=x;i<HIGH-1;i++)
if(lab[i][0].sign!=0 && lab[i][1].sign!=0 && lab[i][2].sign!=0 && lab[i][3].sign!=0 && lab[i][4].sign!=0
&& lab[i][5].sign!=0 && lab[i][6].sign!=0 && lab[i][7].sign!=0 && lab[i][8].sign!=0 && lab[i][9].sign!=0)
{
clearrow(i);
n++;
}
if(n!=0)
{
switch(n)
{
case 1:score+=100;break;
case 2:score+=200;break;
case 3:score+=400;break;
case 4:score+=800;break;
}
if(score%5000==0) grade++;
showscore();
}
}

void pause()
{/*暂停*/
setfillstyle(SOLID_FILL,BLUE);
bar(280,220, 400, 400);
moveto(280,230);
outtext("Press any key");
moveto(280,250);
outtext("to start...");
while(!bioskey(1));
bar(280,220, 400, 400);
moveto(280,230);
outtext("SPACE to pause");
moveto(280,250);
outtext("ESC to exit...");
}

int conversion(int n,int x,int y)
{ /*方块变形函数*/
int m;
switch(n)
{
case 0: m=1;break;
case 1: m=0;break;
case 2: m=3;break;
case 3: m=4;break;
case 4: m=5;break;
case 5: m=2;break;
case 6: m=7;break;
case 7: m=8;break;
case 8: m=9;break;
case 9: m=6;break;
case 10: m=11;break;
case 11: m=12;break;
case 12: m=13;break;
case 13: m=10;break;
case 14: m=15;break;
case 15: m=14;break;
case 16: m=17;break;
case 17: m=16;break;
case 18: m=18;break;
}
if(checkbox(m,x,y)==1)
return m;
else
return n;
}

int main(void)
{
int x,y,flag=1,n,next,key,keytemp;
initialize();/*初始化图形显示*/
score=0;
grade=1;
setbkcolor(LIGHTBLUE);
setcolor(RED);
initialcontainer();
initialnext();
moveto(290,15);
outtext("NEXT:");
showscore();
srand((int)time(0));
pause();
next=rand()%19;
while(flag==1)
{
x=1;
y=4;
n=next;
next=rand()%19;/*随机生成下一个方块*/
shownext(next);/*显示下个方块*/
flag=checkbox(n,x,y);
showbox(n,x,y);
while(flag==1)
{
if(bioskey(1))
keytemp=bioskey(0);
if(keytemp==ESC)
{
flag=0;
break;
}
if(keytemp==SPACE)
{
pause();
keytemp=0;
}
if(keytemp==UP || keytemp==DOWN || keytemp==RIGHT || keytemp==LEFT)
key=keytemp;
clearbox(n,x,y);
switch(key)
{
case UP: n=conversion(n,x,y);break; /*方块变形*/
case DOWN: while(checkbox(n,x+1,y)==1) x++; break; /*方块落到底部*/
case RIGHT: if(checkbox(n,x,y+1)==1) y=y+1;break; /*右移一格*/
case LEFT: if(checkbox(n,x,y-1)==1) y=y-1;break;/*左移一格*/
}
key=0;
keytemp=0;
if(checkbox(n,x+1,y)==1)
x=x+1;
else
{
showbox(n,x,y);
break;
}
showbox(n,x,y);
my_delay((11-grade)*30);
}
checkrow(x); /*检查是否一行已满*/
}
setfillstyle(SOLID_FILL,BLUE);
bar(280,220, 400, 400);
moveto(280,230);
outtext(" GAME OVER!");
moveto(280,250);
outtext("Press any key");
moveto(280,270);
outtext("to exit...");
sleep(2);
fflush(stdin);
getch();
closegraph();/*关闭图形显示*/
return 0;
}



cMvffeQZ.jpg (24.98 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册
搜索更多相关主题的帖子: 俄罗斯方块 graphics 游戏 
2006-07-07 23:57
jig
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 

不错,LZ以方块为对象。做的不错。

我前不久也做了一个俄罗斯方块(是为了移植到单片机),不过我是以被框(也就是方块显示区域)做为编程对象,我个人认为那些样做比较好理解和容易实现。少时我也放出来给大家看看

还有,LZ在按键处理上我个人觉得不是很科学,我在试完你这个觉得按键不灵敏切延时时间太长,最致命的弱点是,在停顿的过程中,按键是失效的,可等停顿结束,先前按的键又起作用,给人程序不受控制的感觉。我个人给的建议是LZ可以用“分割停顿”的方法,把键盘响应添加到“分割”中以实现键盘实时响应.

我看LZ在其中用的是sleep()我不建议你这样,还是用delay()的好,这个函数的单位是毫秒,LZ可以这样,比如你要停顿800毫秒,你可以在while()主循环中这样

for (i = 0; i < 800; i++) /*停顿800毫秒*/
{
delay(1); /*实现停顿分割*/

if(bioskey(1)) /*按键响应*/
{
switch(bioskey(0)) /*按键处理 */
{
......
}
}

}

看这样写的话即使在停顿中你也是可以控制方块的(毕竟,在方块停顿的过程中你可能要旋转方快,不可能总要等到方块开始下落运动时候才响应你的旋转吧)。这样做也就避免了你自己再去创建个中断来实现实时响应按键,那样浪费啦。

[此贴子已经被作者于2006-7-8 10:43:58编辑过]


个人网站 -  http://.h001.
2006-07-08 10:32
yuleol
Rank: 1
等 级:新手上路
帖 子:58
专家分:0
注 册:2005-12-10
收藏
得分:0 
jig提的意见不会,我昨天还在想可不可以在下落一格的时间内两次或多次响应键盘操作呢!~~

兴趣是我的源动力!
2006-07-08 14:39
jig
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
帖 子:530
专家分:242
注 册:2005-12-27
收藏
得分:0 

呵呵,只要你这样“分割停顿”,那理论上你延时N豪秒你就可以在方块下落时响应N次啊,在PC机上基本可以实现键盘实时响应。把他用到俄罗斯方块上最大一点好处就是,他可以完成很多“特技动作”。比如一个小凹陷是独立悬空的,你可以在方块停顿期间把一个方块给平移进去......这样效果就好多了


至于LZ所说的按键滞后问题,我想TC下没有清空按键缓存的函数,唯一的就是自己写,这也证实要做游戏库函数是永远不可靠。你唯一能解决要不自己写个按键模块,要不在其后稍加延时,不过不是解决之本

[此贴子已经被作者于2006-7-8 14:58:57编辑过]


个人网站 -  http://.h001.
2006-07-08 14:49
一笔苍穹
Rank: 1
等 级:新手上路
帖 子:640
专家分:0
注 册:2006-5-25
收藏
得分:0 
DOS的键盘缓冲首尾指针分别在0040:001A和0040:001C中,只要将0040:001A和值变为0040:001C的值就可以实现清除缓冲区了。
给个实现函数:
void clear_keybuf()
{
int var;
var = peek(0x40, 0x1a);
pokeb(0x40, 0x1c, var);
}

[此贴子已经被作者于2006-7-9 17:42:01编辑过]

2006-07-08 21:25
小CKAKA
Rank: 1
来 自:山东
等 级:新手上路
帖 子:1
专家分:0
注 册:2010-12-8
收藏
得分:0 
2010-12-12 17:49
xufan123
Rank: 5Rank: 5
等 级:职业侠客
帖 子:226
专家分:318
注 册:2010-11-15
收藏
得分:0 
TC下可以不用全屏吗?
2010-12-17 19:04
快速回复:TC2.0+graphics编的俄罗斯方块游戏
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027735 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved