编程高手之路—代码集萃—C语言编写的俄罗斯方块Tc2.0中怎么样设置图形显示?Tc2.0中有两种显示模式,一种是我们所熟知的字符模式,另一种是图形模式。在字符模式下只能显式字符,如ASCII字符。一般是显示25行,每行80个字符。程序缺省的是字符模式。在字符模式下不能显式图形和进行绘图操作。要想进行图形显示和绘图操作,必须切换到图形模式下。Tc2.0中用initgraph()函数可以切换到图形模式,用closegraph()可以从图形模式切换回字符模式。initgraph()和closegraph()都是图形函数,使用图形函数必须包括头文件graphics.h。voidfarinitgraph(intfar*graphdriver,intfar*graphmode,charfar*pathtodriver);graphdriver是上涨指向图形驱动序号变量的指针;graphmode是在graphdriver选定后,指向图形显示模式序号变量的指针。pathtodriver表示存放图形驱动文件的路径。Tc2.0中有多种图形驱动,每种图形驱动下又有几种图形显示模式。在我的程序中图形驱动序号为VGA,图形显示模式序号为VGAHI。这是一种分辨率为640*480(从左到右坐标依次为0-639,从上到下坐标依次为0-479),能够显示16种颜色的图形模式。别的图形驱动序号和图形显示模式序号,可以从手册或联机帮助中找到。pathtodriver指示存放图形驱动文件的路径。图形驱动序号不同,图形驱动文件也不同。序号为VGA图形驱动对应egavga.bgi这个图形驱动文件。egavga.bgi一般在Tc目录下。voidfarclosegraph(void);没有参数,从图形模式直接返回字符模式。initgraph()和closegraph()的常用用法如下:intgdriver=VGA,gmode=VGAHI,errorcode;/*initializegraphicsmode*/initgraph(&gdriver,&gmode,e:tc2);/*readresultofinitialization*/errorcode=graphresult();if(errorcode!=grOk)/*anerroroccurred*/{printf(Graphicserror:%sn,grapherrormsg(errorcode));printf(Pressanykeytohalt:);getch();exit(1);/*returnwitherrorcode*/}/*returntotextmode*/closegraph();Tc2.0中常用图形函数的用法?在这里讲几个游戏中用到的绘图用的图形函数:setcolor();line();rectangle();settextjustify();outtextxy();setfillstyle();bar();voidfarsetcolor(intcolor);设置画线、画框和在图形模式下显示文字的当前颜色。这个函数将影响line()、rectangle()和outtextxy()函数绘图的颜色。color可以取常的颜色常量:BLACK?0BLUE?1GREEN?2CYAN?3RED?4MAGENTA?5BROWN?6LIGHTGRAY?7DARKGRAY?8LIGHTBLUE?9LIGHTGREEN?10LIGHTCYAN?11LIGHTRED?12LIGHTMAGENTA?13YELLOW?14WHITE?15voidfarline(intx1,inty1,intx2,inty2);用当前颜色从(x1,y1)画一条到(x2,y2)的线段。voidfarrectangle(intleft,inttop,intright,intbottom);用当前颜色画一个左上角为(left,top)、右下角为(right,bottom)的矩形框。voidfarsettextjustify(inthorz,intvert);设置图形模式下文字输出的对齐方式。主要影响outtextxy()函数。horiz和vert可取如下枚举常量:horiz?LEFT_TEXT?0?Left-justifytext?CENTER_TEXT?1?Centertext?RIGHT_TEXT?2?Right-justifytextvert?BOTTOM_TEXT?0?Justifyfrombottom?CENTER_TEXT?1?Centertext?TOP_TEXT?2?Justifyfromtopvoidfarouttextxy(intx,inty,char*textstring);在(x,y)处用当前字体(缺省的字体是DEFAULT_FONT)显示字符串textstring,字符串的对齐方式由settextjustify()指定。voidfarsetfillstyle(intpattern,intcolor);设置图形的填充模式和填充颜色,主要影响bar()等函数。pattern一般取枚举常量值SOLID_FILL,color的取值与setcolor(intcolor)中color的取值范围相同。介绍完了前面两个问题,现在来写一个程序。这个程序演示前了面所介绍的几个图形函数。程序prog1.c怎样获取鍵盘输入?在Tc2.0中有一个处理键盘输入的函数bioskey();intbioskey(intcmd);当cmd为1时,bioskey()检测是否有键按下。没有键按下时返回0;有键按下时返回按键码(任何按键码都不为0),但此时并不将检测到的按键码从键盘缓冲队列中清除。当cmd为0时,bioskey()返回键盘缓冲队列中的按键码,并将此按键码从键盘缓冲队列中清除。如果键盘缓冲队列为空,则一直等到有键按下,才将得到的按键码返回。Escape键的按键码为0x11b,下面的小程序可以获取按键的按键码。for(;;){key=bioskey(0);/*waitforakeystroke*/printf(0x%xn,key);if(key==0x11b)break;/*Escape*/}常用按键的按键码如下:#defineVK_LEFT0x4b00#defineVK_RIGHT0x4d00#defineVK_DOWN0x5000#defineVK_UP0x4800#defineVK_HOME0x4700#defineVK_END0x4f00#defineVK_SPACE0x3920#defineVK_ESC0x011b#defineVK_ENTER0x1c0d完整的程序请参见prog2.c、prog3.c。prog2.c获取按键的按键码,按Escape键退出程序。prog3.c根据不同的按键进行不同的操作,按Escape键退出程序。怎样控制方块的移动?方块移动的实现很简单,将方块原来的位置用背景色画一个同样大小的方块,将原来的方块涂去。然后在新的位置上重新绘制方块就可以了。这样就实现了方块的移动。完整的程序请参见prog4.c。这个用方向键控制一个黄色的小方块在屏幕上上、下、左、右移动。这个程序用到了前面几个问题讲的内容,如果你有点忘了,还要回头看看哦。:)怎样控制时间间隔(用于游戏中控制形状的下落)?解决这个问题要用到时钟中断。时钟中断大约每秒钟发生18.2次。截获正常的时钟中断后,在处理完正常的时钟中断后,将一个计时变量加1。这样,每秒钟计时变量约增加18。需要控控制时间的时候,只需要看这个计时变量就行了。截获时钟中断要用到函数getvect()和setvect()。两个函数的声明如下:?voidinterrupt(*getvect(intinterruptno))();?voidsetvect(intinterruptno,voidinterrupt(*isr)());保留字interrupt指示函数是一个中断处理函数。在调用中断处理函数的时候,所有的寄存器将会被保存。中断处理函数的返回时的指令是iret,而不是一般函数用到的ret指令。getvect()根据中断号interruptno获取中断号为interruptno的中断处理函数的入口地址。setvect()将中断号为interruptno的中断处理函数的入口地址改为isr()函数的入口地址。即中断发生时,将调用isr()函数。在程序开始的时候截获时钟中断,并设置新的中断处理。在程序结束的时候,一定要记着恢复时钟中断哦,不然系统的计时功能会出问题的。具体演示程序请参见prog5.c。由于中断处理大家可能用的不多,所以我把prog5.c这个程序完整地贴在下面,并加上详细的解释。/*prog5.c*/Thisisaninterruptserviceroutine.YoucanNOTcompilethisprogramwithTestStackOverflowturnedonandgetanexecutablefilewhichwilloperatecorrectly.*//*这个程序每隔1秒钟输出一个整数,10秒钟后结束程序。按escape键提前退出程序。*/#include#include#include/*Escapekey*/#defineVK_ESC0x11b#defineTIMER0x1c/*时钟中断的中断号*//*中断处理函数在C和C++中的表示略有不同。如果定义了_cplusplus则表示在C++环境下,否则是在C环境下。*/#ifdef__cplusplus#define__CPPARGS...#else#define__CPPARGS#endifintTimerCounter=0;/*计时变量,每秒钟增加18。*//*指向原来时钟中断处理过程入口的中断处理函数指针(句柄)*/voidinterrupt(*oldhandler)(__CPPARGS);/*新的时钟中断处理函数*/voidinterruptnewhandler(__CPPARGS){/*increasetheglobalcounter*/TimerCounter++;/*calltheoldroutine*/oldhandler();}/*设置新的时钟中断处理过程*/voidSetTimer(voidinterrupt(*IntProc)(__CPPARGS)){oldhandler=getvect(TIMER);disable();/*设置新的时钟中断处理过程时,禁止所有中断*/setvect(TIMER,IntProc);enable();/*开启中断*/}/*恢复原有的时钟中断处理过程*/voidKillTimer(){disable();setvect(TIMER,oldhandler);enable();}voidmain(void){intkey,time=0;SetTimer(newhandler);/*修改时钟中断*/for(;;){if(bioskey(1)){key=bioskey(0);if(key==VK_ESC)/*按escape键提前退出程序*/{printf(Usercancel!n);break;}}if(TimerCounter18)/*1秒钟处理一次*/{/*恢复计时变量*/TimerCounter=0;time++;printf(%dn,time);if(time==10)/*10秒钟后结束程序*/{printf(Programterminatednormally!n);break;}}}KillTimer();/*恢复时钟中断*/}游戏中的各种形状及整个游戏空间怎么用数据表示?以后我提到的形状都是指下面七种形之一及它们旋转后的变形体。□□□□□□□□□□□□□□□□□■□□□■■□□□□□□□□□□■□□□■□□□■□□□■■□□■■□□■□□■■■□■■□□□□□□□■□□□□□□□□□□□■□□□□□□■■□□□■□□□■■□□■■□□■□□□■