献给初学编程的礼物⑵C语言
2000-4-6
我们来看下主程序是怎么写的,如何去控制键盘,并且响应(省去了部分无关代码)
main()
{int gd=DETECT,gm;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"");
setbkcolor(0);
system("hscplay zfxl.hsc");
clearviewport();
xs(60,50,"zfxl.dat");
for(i=0;i<10;i++)
{ ztu(80+i*42,60+40,15,t1[i]);
ztu(100+i*42,60*2+40,15,t2[i]);
ztu(120+i*42,60*3+40,15,t3[i]);
}
bit=malloc(imagesize(150,120,150+267,120+120));
getimage(150,120,267+150,240,bit);
xs(150,120,"zfxl.txt");
for(;;)
{if(keykey()==ESC) break;}
putimage(150,120,bit,COPY_PUT);
randomize();
for(;;)
{ s=random(30);
zou(80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,1,t4[s]);
putout(s);
end:tt=keykey();
if((tt)==t5[s])
{ztu(80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,15,t4[s]);
sc++;
}
else if((tt)==ESC)
{
xs(150,120,"zfxl.sys");
gotoxy(30,11);
printf("%d",sc);
gotoxy(30,13);
printf("%d",time4);
gotoxy(30,15);
if (time4==0) time4=1;
printf("%d",sc*60/time4);
getch();
closegraph();
exit(0);}
else {printf("\007");
goto end;}}}
上两篇的文章已提到过部分函数的用法了,我们依次看下来
int gd=DETECT,gm;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"");.
这是初始化图形界面的用法
system("hscplay zfxl.hsc");
这句话本是无关的,为什么要提出来呢?
system可以说是一个shell,帮你执行外部的可执行文件的,这里的用法是插放zfxl.hsc这段音
乐.
clearviewport();
xs(60,50,"zfxl.dat");
......
getimage(150,120,267+150,240,bit);
xs(150,120,"zfxl.txt");
这就是显示背景及按钮的的调用程序
for(;;)
{if(keykey()==ESC) break;}
这个用法要记住
思想是这样的,不停地等待,直到查测到按键才跳出循环.
这个方法如同window的消息循一样,是查测用操作的一个最有效的方法
一定要记住!
randomize();
for(;;)
{ s=random(30);
zou(80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,1,t4[s]);
putout(s);
end:tt=keykey();
if((tt)==t5[s])
{ztu(80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,15,t4[s]);
sc++;
}
......
到结束
randomize()是初始化随机数.random(30)是0-29之间的整数,其实应该是int(random(30))的
,但s是一个整数型变量,自动就转成了整数所以没加int.
在C在语言考试中指针和数字类型是最重要的考点,从这点就可以看出C语言的灵活性了吧.
再下来调用zou,ztu这两个自编的函数,
80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,1,t4[s]
这几个参数为什么这样写,请读者自己捉摸,
s/10是取整数部分,s%10是取余数部分,这个参数的调用有点技巧,我可是想了一天的,不然要
花十行代码才能完成的.请对照源程序慢慢看.
tt=keykey()
keykey是什么?
看下面这个自编函数
int keykey()
{int key;
while(bioskey(1)==0);
key=bioskey(0);
key=key&0xff ? key&0xff:key>>8;
return(key);
}
这个是检测键盘按键值的,是让计算机知道你按的是哪个键比如是A还是B,并返回键值.对初学
者不必太了解,记住这段程序,并且学会调用等你学到一定程度了,就知道为什么这样写了
key=key&0xff ? key&0xff:key>>8;这是一个比目运算,
如果key=key&0xff则key=key, 否则key=8,
最用这个程序是怎么计分的呢?
因为用了中断调用,我下次在讲鼠标控制时会讲到的.
下面附全部源程序
hz16.h 西文写汉的程序
showbmp1.c 显示位图的程序
zfxl.c 主程序
zfxl.dat\zfxl.txt\zfxl.sys 事实上是三个bmp文件
hzk16 16点阵汉字库文件
------
hz16.h
------
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<graphics.h>
int handle;
int openhzk()
{
handle=open("HZK16",0||5);
if(handle==-1)
{
cputs("error on open file!");
getch();
closegraph();
exit(1);
}
}
int puthz16(int x,int y,int z, int color,int m,int n,char * p)
{ unsigned int i,qu,wei,f=0;
int i1,i2,i3,i4,i5,rec,wordwi;
long relate;
char cbuf[32];
unsigned char tbuf[2];
settextstyle(SMALL_FONT,HORIZ_DIR,USER_CHAR_SIZE);
while((i=*p++)!=0)
{
if((i&128)==NULL){
setusercharsize(4*m,3,11*n,8);
tbuf[0]=i;
tbuf[1]=0;
setcolor(color);
outtextxy(x,y+8,tbuf);
setusercharsize(4,3,11,8);
x=x+8*m+z;
}
else{
if(i>=0xa1)
if(f==0)
{
qu=(i-0xa1)&0x07f;
f=1;
}
else
{
wei=(i-0xa1)&0x07f;
f=0;
rec=qu*94+wei;
relate=rec*32L;
lseek(handle,relate,SEEK_SET);
read(handle,cbuf,32);
for(i1=0;i1<16*m;i1=i1+m)
for(i4=0;i4<m;i4++)
for(i2=0;i2<2;i2++)
for(i3=0;i3<8;i3++)
if(getbit(cbuf[i1/m*2+i2],7-i3))
for(i5=0;i5<n;i5++)
putpixel(x+i2*8*n+i3+i5,y+i1+i4,color);
x=x+16+z;
}
}
}
return(x);
}
int getbit(unsigned char c,int n)
{
return((c>>n)&1);
}
-----
showbmp1.c
-----
#include "graphics.h"
#include "stdio.h"
int xs(int x,int y,char n[50])
{ int c1,c2=0,w1,ll,kuan,il,iw;
FILE *fp;
static int color[16]={0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15};
if ((fp=fopen(n,"rb"))==0)
{ printf("cannot open file\n");
return(0);}
fseek(fp,18,SEEK_SET);
fread(&kuan,4,1,fp);
w1=kuan;
fread(&kuan,4,1,fp);
ll=kuan;
fseek(fp,118,SEEK_SET);
for (il=0;il<ll;il++)
{ moveto(x,y+ll-il);
for(iw=0;iw<w1;iw++)
{ fread(&kuan,1,1,fp);
c1=(kuan & 0xf0) >>4;
if(c1!=c2 || iw==w1-1)
{ setcolor(color[c2]);
lineto(x+iw,y+ll-il);
c2=c1;}
iw++;
if(iw>=w1)continue;
c1=kuan & 0x0f;
if (c1!=c2 || iw==w1-1)
{ setcolor(color[c2]);
lineto(x+iw,y+ll-il);
c2=c1;
}}
for (iw=1;iw<(8-w1%8)%8;iw+=2)
fread(&kuan,1,1,fp);
} fclose(fp);
return (0);
}
-------
zfxl.c
------
#include"d:\tc\hz16.h"
#include"d:\tc\showbmp1.c"
#include<fcntl.h>
#include<dos.h>
#include<math.h>
#include<string.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<alloc.h>
#include<graphics.h>
#define ESC 27
#define leng 40
void ztu(int x1,int y1,int color,char *str);
void zou(int x1,int y1,int color,char *str);
void putout(int s);
char *t1[10]={"Q","W","E","R","T","Y","U","I","O","P"};
char *t2[10]={"A","S","D","F","G","H","J","K","L",";"};
char *t3[10]={"Z","X","C","V","B","N","M",",",".",""};
char *t4[30]={"Q","W","E","R","T","Y","U","I","O","P","A","S","D","
F","G","H","J","K","L",";","Z","X","C","V","B","N","M",",",".","
"};
char t5[31]="qwertyuiopasdfghjkl;zxcvbnm,./";
char *t6[10]={"左手小指","左手无名指","左手中指","左手食指","左手食指","右手食指
","右手食指","右手中指","右手无名指","右手小指"};
int keykey()
{int key;
while(bioskey(1)==0);
key=bioskey(0);
key=key&0xff ? key&0xff:key>>8;
return(key);
}
main()
{int time1,time2,time3;
int time11,time12,time13,time4;
union REGS r;
int s,i,tt,sc=0;
void far *bit;
int gd=DETECT,gm;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"");
setbkcolor(0);
system("hscplay zfxl.hsc");
clearviewport();
xs(60,50,"zfxl.dat");
for(i=0;i<10;i++)
{ ztu(80+i*42,60+40,15,t1[i]);
ztu(100+i*42,60*2+40,15,t2[i]);
ztu(120+i*42,60*3+40,15,t3[i]);
}
bit=malloc(imagesize(150,120,150+267,120+120));
getimage(150,120,267+150,240,bit);
xs(150,120,"zfxl.txt");
for(;;)
{if(keykey()==ESC) break;}
putimage(150,120,bit,COPY_PUT);
r.h.ah=0x02;
int86(0x1a,&r,&r);
time1=r.h.ch/16;
time2=r.h.cl/16;
time3=r.h.dh/16;
time11=r.h.ch%16;
time12=r.h.cl%16;
time13=r.h.dh%16;
randomize();
for(;;)
{ s=random(30);
zou(80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,1,t4[s]);
putout(s);
end:tt=keykey();
if((tt)==t5[s])
{ztu(80+(int)(s%10)*42+20*(int)(s/10),60*(int)(s/10+1)+40,15,t4[s]);
sc++;
}
else if((tt)==ESC)
{
r.h.ah=0x02;
int86(0x1a,&r,&r);
time1=r.h.ch/16-time1;
time2=r.h.cl/16-time2;
time3=r.h.dh/16-time3;
time11=r.h.ch%16-time11;
time12=r.h.cl%16-time12;
time13=r.h.dh%16-time13;
time4=(time1*10+time11)*360+(time2*10+time12)*60+time3*10+time13;
xs(150,120,"zfxl.sys");
gotoxy(30,11);
printf("%d",sc);
gotoxy(30,13);
printf("%d",time4);
gotoxy(30,15);
if (time4==0) time4=1;
printf("%d",sc*60/time4);
getch();
system("hscplay");
closegraph();
exit(0);}
else {printf("\007");
goto end;
}
}
}
void ztu(int x1,int y1,int color,char *str)
{
int x2,y2;
x2=x1+leng;y2=y1+leng;
setcolor(7);
setfillstyle(1,7);
bar3d(x1-1,y1-1,x2,y2,0,0);
setcolor(0);
line(x1,y2,x2,y2);
line(x2,y2,x2,y1);
setcolor(8);
line(x1+1,y2-1,x2-1,y2-1);
line(x2-1,y2-1,x2-1,y1-1);
setcolor(15);
line(x1,y1,x1,y2-1);
line(x1,y1,x2-1,y1);
setcolor(color);
openhzk();
puthz16(x1+12,y1+13,1,color,1,1,str);
close(handle);
}
void zou(int x1,int y1,int color,char *str)
{ int x2,y2;
x2=x1+leng;y2=y1+leng;
setcolor(15);
setfillstyle(1,15);
bar3d(x1,y1,x2,y2,0,0);
setcolor(7);
line(x1+1,y2-1,x2-1,y2-1);
line(x2-1,y2-1,x2-1,y1-1);
setcolor(8);
line(x1,y1,x1,y2);
line(x1,y1,x2,y1);
setcolor(0);
line(x1+1,y1+1,x1+1,y2-1);
line(x1+1,y1+1,x2-1,y1+1);
setcolor(color);
openhzk();
puthz16(x1+13,y1+13,0,color,1,1,str);
close(handle);
}
void putout(int s)
{int j;
j=s%10;
setcolor(15);
setfillstyle(1,15);
bar3d(140-10,329-25,250-10,346-25,0,0);
openhzk();
puthz16(144-6,331-25,2,1,1,1,t6[j]);
close(handle);
}
以上是全部代码,请最好下载rosesnow.heha.net/software/zfxl.zip源码
对于本文的意见,请希望讲下去及对文章难易程度的看法请回复一下
::∴★∵**☆.∴★∵**☆
.█████.☆.∵★∵∴☆
.█田█田█.*☆.∴★∵
.█田█田█.★∵∴☆.★∵∴
.█田█田█.同一个星空下★..**
.█田█田█.望著天空的星星雨**☆
.█████.你可会想起我是你的好朋友?
◢██□██◣.此刻我送予你這一句“愿我们友谊永固”~~~~~*^_^*
::∴★∵**☆.∴★∵**☆