| 游戏 自己写的 |
|
| 作者:翟明新 文章来源:自己 点击数: 更新时间:2006-10-9 |
|
|
自己写的贪吃蛇小游戏(c语言) 由于一时冲动,想写个小游戏,于是选择了贪吃蛇游戏,从中午写到晚上,大概花了六七个小时,做出了基本功能。(游戏中用w、s、a、d四个键控制方向,按esc退出,后来花了些时间写了些注释,写得很烂,估计除了我自己没人看的懂 ^_^ !)
#i nclude #i nclude #i nclude
#define length 20 #define TIMER 0x1c /*时间中断号为0x1c*/ int timer=0,rand_block_left,rand_block_top;
void interrupt (*oldhandler)(); /*声明旧中断*/
void interrupt newhandler() /*定义新中断*/ { timer++; oldhandler(); }
void settime_handler(void interrupt(*fun)()) /*定义设置中断函数*/ { oldhandler=getvect(TIMER); /*声明旧中断为时间中断*/ disable(); /*禁止中断*/ setvect(TIMER,fun); /*将系统中断替换为新中断*/ enable(); /*开启中断*/ }
void KillTimer() /*定义恢复旧中断函数*/ { disable(); setvect(TIMER,oldhandler); enable(); }
typedef struct block /*定义块结构体*/ { int left; /*左边界*/ int top; /*上边界*/ int right; /*右边界*/ int bottom; /*下边界*/ struct block *prior; /*前指针*/ struct block *next; /*后指针*/ }*blockd;
void init(blockd *head,blockd *end) /*初始化存放块的链表*/ { blockd p,q; int i;
p=*head=(blockd)malloc(sizeof(struct block)); p->next=0;
for(i=3;i>=0;i--) /*链表中放入四个块*/ { q=(blockd)malloc(sizeof(struct block)); q->left=10*(i); q->right=10*(i+1)-3; q->top=50; q->bottom=57; q->prior=p; q->next=0; p->next=q; p=q; }
*end=p; }
void print(blockd head) /*刷新屏幕函数*/ { int i; blockd p;
cleardevice(); /*清屏*/ p=head->next; while(p) /*依次打印每个块*/ { bar(p->left,p->top,p->right,p->bottom); p=p->next; } bar(rand_block_left,rand_block_top,rand_block_left+7,rand_block_top+7); /*打印出随机块*/ }
int check(blockd head) /*判断此时的状态,有三种状态:0表示越界或蛇头撞到自己,1表示正常,2表示蛇头吃到随机块了*/ { blockd p,q; p=head->next; q=p->next;
if(((p->left)==rand_block_left)&&((p->top)==rand_block_top)) return 2; /*判断蛇头是否吃到随机块*/
if((p->left<0)||(p->right>640)||(p->top<0)||(p->bottom>480)) return 0; /*判断是否越界*/
while(q) { if(((p->left)==(q->left))&&((p->top)==(q->top))) return 0; /*判断蛇头是否撞到自己*/ q=q->next; } return 1; }
void rand_block(blockd head) /*产生随机块*/ { blockd p; int i=1; while(i) { rand_block_left=rand()%64*10; rand_block_top=rand()%48*10; p=head->next; i=0; while(p) /*判断产生的随机块是否与快链表内的块重合*/ { if(((p->left)==rand_block_left)&&((p->top)==rand_block_top)) i=1; p=p->next; } } }
int renovate(int direction,blockd head,blockd *end) /*刷新块链表*/ { blockd p,q; int i;
p=(blockd)malloc(sizeof(struct block)); q=head->next;
switch(direction) /*根据方向在链表头增加一个块*/ { case 0:p->left=q->left+10;p->top=q->top;p->right=q->right+10;p->bottom=q->bottom;break; case 1:p->left=q->left;p->top=q->top+10;p->right=q->right;p->bottom=q->bottom+10;break; case 2:p->left=q->left-10;p->top=q->top;p->right=q->right-10;p->bottom=q->bottom;break; case 3:p->left=q->left;p->top=q->top-10;p->right=q->right;p->bottom=q->bottom-10;break; } p->next=q; q->prior=p; q=head; q->next=p; p->prior=q;
i=check(head); if(i==1) /*如果是正常情况则删除尾部一个块*/ { (*end)=(*end)->prior; free((*end)->next); (*end)->next=0; return 1; } else if(i==2) /*如果是吃到随机块了,则产生一个新随机块*/ { rand_block(head); return 1; } else return 0; /*失败*/ }
void main() { blockd head,end,p,q; int direction=0,i; int driver=VGA,mode=VGAHI; int key;
initgraph(&driver,&mode,\"c:\\\\TURBOC2\"); /*初始化图形工作环境*/ init(&head,&end); /*初始化块链表*/ settime_handler(newhandler); /*设置时间中断*/ srand(time(0)); /*设置随机输种子*/ rand_block(head); /*产生一个随机块*/ print(head); /*显示*/
while(1) { if(timer>2) /*判断是否进行两次时间中断了*/ { if(bioskey(1)) /*判断是否有按键按下*/ { key=bioskey(0); if(key==0x11b) break; /*如果按键为esc则推出*/ switch(key) /*根据按键改变方向*/ { case 8292:if(direction!=2) direction=0;break; case 8051:if(direction!=3) direction=1;break; case 7777:if(direction!=0) direction=2;break; case 4471:if(direction!=1) direction=3;break; } if(renovate(direction,head,&end)) /*如果刷新链表成功就刷新屏幕*/ print(head); else break; /*否则退出*/ } else /*如果没有输入的情况下*/ { if(renovate(direction,head,&end)) /*如果刷新链表成功就刷新屏幕*/ print(head); /*否则退出*/ else break; } timer=0; } } if(key!=0x11b) /*判断是否是按esc退出的还是失败推出的*/ { cleardevice(); printf(\"you failed!!\\npress esc to exit\"); while(getch()!=27); } KillTimer(); /*恢复时间中断*/ }
|