这个我需要声明一下 本来我给speaker本人发了邮件过去gfgh2d@tom.com 就是这个 不过估计他这个邮件已经收不到信了 我收到了系统退信 估计我暂时联系不上他本人 但是这个程序确实值得大家来学习 所以就转载了他的这个炸弹人程序 以下便是他的帖子原文
我的炸弹人游戏_第一部分(写得太长分成两部分了) /*游戏介绍: 此游戏一开始玩家可携带若干数量的地雷,每颗地雷被安放三秒后爆炸(当然你可以设定它的爆炸时间为更长或者更短些),地雷的爆炸范围每关都有初始设定, 爆炸时若有其他地雷在爆炸范围内则将被引爆造成连锁反应(杀敌的关键),地雷爆炸后的火焰对以下东西有杀伤效果: 玩家、怪物(即敌人)、泥土墙(即黑色方块)、其他地雷(即使得其他地雷引爆造成更大杀伤范围)。 每一关的泥土墙内都随机放置了若干奖励物品,当藏有奖励物品的泥土墙被炸开时奖励物品就出现了,此时玩家走到此格子上就可以加到奖励物品。奖励物品目前之设定了两种——布雷器、新型炸药(名字取得怎么样?哈哈哈)。每加一个布雷器(空心方框表示布雷器)可使玩家多布一颗雷(布雷数量越多则连锁反应范围越广,怪物越难逃脱,当然玩家被炸的几率也会增加);新型炸药(用空心环表示新型炸药)每多加一个则地雷爆炸威力多一格。 积分:屏幕右边显示积分最高的五人的分数与姓名。当玩家的退出游戏时积分超过五人中的任何一个则玩家就济身名人堂,并有幸签下他的名字(这一套是跟大型街机上学的,不要告诉我你不知道什么叫街机哦)。分数的依据有两个——根据耗时和按键数量(这样的积分方式还不完善,以后改进),耗时越少分数越高,按键越少分数也越高。 按键:空格键表示在玩家所在格子安置地雷; w,s,a,d分别表示上下左右移动方向; 按ESC键则立即退出(当然此时若你的分数超过名人堂内分数则会被要求写下你的名字并成为记录)。 目前能想到的说明就这么多,如果有什么疑问或者遇到什么bug请给我一只喵(mail)。 我的信箱是:writer6713764@tom.com 注:我装的是tc3.0,因此主函数中的initgraph中的路径可能不适合诸位使用,但是我不会设置这一项,所以烦请斑竹帮忙改一改吧! */
/************************************************************************ * * 文件名:BOMBMAN.c * * 文件描述:游戏炸弹人 * * 创建人: MR LIN, 2004年6月19日 * * 版本号:1.0 * * 修改记录: * * ************************************************************************/
#include<math.h> #include<string.h> #include<bios.h> #include<time.h> #include<graphics.h> #include<dos.h> #include<stdio.h> #include<stdlib.h> #include<conio.h> #define EXIT 100 /*退出*/ /*格子状态*/ #define EMPTY 0 /*空地*/ #define WALL 1 /*石头墙*/ #define MUD 2 /*泥土墙*/ #define FIRE 4 /*火焰*/ #define HERO 5 /*玩家*/ #define BOMB 6 /*地雷*/ #define BINDHB 7 /*玩家与地雷在同一格*/ #define MONSTER 8 /*怪物*/ #define FOOD_BOMB 9 /*布雷器,吃一个可多布一个雷*/ #define FOOD_POWER 10 /*新型炸药,吃一个可使地雷爆炸范围加一*/ #define BINDMFB 11 /*藏有布雷器的泥土墙*/ #define BINDMFP 12 /*藏有新型炸药的泥土墙*/ /*地雷状态*/ #define NOLAY 0 /*未放置状态*/ #define LAY 1 /*放置瞬间*/ #define BOMBING 2 /*地雷处于激发状态*/ /*怪物状态*/ #define STOP 0 /*怪物处于停止状态*/ #define CONSIDER 1 /*怪物处于思考状态*/ #define CLRM map[XMONSTER[i]][YMONSTER[i]]=EMPTY /*怪物移动后格子变为空白*/ #define PM locatprint(XMONSTER[i],YMONSTER[i]) /*刷新怪物格子*/ #define REPM map[XMONSTER[i]][YMONSTER[i]]=MONSTER /*怪物来到新的格子*/ /*怪物移动方向*/ #define EAST 0 /*东*/ #define SOUTH 1 /*南*/ #define WEST 2 /*西*/ #define NOTH 3 /*北*/ #define PH locatprint(X,Y) /*单格子显示*/ #define CLRP map[X][Y]=EMPTY /*清除格子*/ #define REP map[X][Y]=HERO /*玩家到达格子*/ #define LB map[X][Y]=BOMB /*地雷放置格子*/ #define ALIVE 0 /*玩家处于生存状态*/ #define DIE 1 /*玩家处于死亡状态*/ #define BOMBTIME 3 /*引爆时间*/ #define lt(a) (20*(a)+30) /*格子左上坐标*/ #define rb(a) (20*(a+1)+30) /*格子右下坐标*/ #define TODIE "you die!!!! press ESC to continue game!" /*显示玩家死亡游戏结束*/ #define TOWIN "you win!!!! press ESC to continue game!" /*显示玩家胜利,游戏结束*/ #define STAGETOPNUM 15 /*关卡总数*/ /*全局变量*/ long KEYNUM=0, /*记录玩家按键次数*/ delaytime=0, /*记录地雷爆炸时所延误时间以便游戏结束后计算总时间*/ famousscore[5]={0}; /*前五名最高分*/ char famousname[5][20]={"0"}; int map[21][21], /*地图*/ LIFENUM=3, /*玩家生命数量*/ NUM=1, /*地雷数量*/ RANGE=1, /*地雷爆炸范围*/ monster=0, /*当前怪物数量*/ FOOD_BOMBNUM=3, /*布雷器总数*/ FOOD_POWERNUM=3, /*新型炸药总数*/ mudnum=60, /*泥土墙数量*/ life=ALIVE, /*玩家状态(生存或者死亡)*/ X=1,Y=1, /*玩家位置坐标*/ XB[10]={-1},YB[10]={-1}, /*地雷位置坐标*/ XMONSTER[15],YMONSTER[15] /*怪物坐标*/ ,mcondition[10]={STOP} /*怪物状态*/ , MONSTERNUM=0 ; /*怪物数量*/ struct stage /*关卡信息*/ {int _mudnum; /*泥土墙数量*/ int _FOOD_BOMBNUM; /*布雷器数量*/ int _FOOD_POWERNUM; /*新型炸药数量*/ int _NUM; /*玩家开始时携带地雷数量*/ int _RANGE; /*开始时炸弹威力*/ int _MONSTERNUM; /*开始时怪物数量*/ float _considertime; /*怪物思考时间长短(时间越长越呆滞)*/ int _topkeypress; /*本关按键上限,超过此上限则本项分数为0*/ int _toptime; /*本关耗时上限,超过则本项为0分*/ } stages[STAGETOPNUM]={{50,5,5,4,4,5,3,200,300}, /*第一关*/ {50,4,4,3,3,5,3,200,300}, /*第二关*/ {50,4,3,3,3,5,2.5,400,400}, /*第三关*/ {50,3,3,3,2,8,2,600,600}, /*第四关*/ {100,0,0,10,10,10,2,600,600},/*第五关*/ {50,3,2,2,3,8,1.8,900,900}, /*第六关*/ {50,2,3,2,2,10,1.5,1000,1000}, /*第七关*/ {100,0,0,10,10,10,1.5,1000,1000},/*第八关*/ {50,2,2,2,2,10,0.8,1500,1500}, /*第九关*/ {40,2,2,2,1,10,0.5,2000,2000}, /*第十关*/ {100,0,0,10,10,10,0.5,2000,2000}, /*第十一关 {40,2,1,1,2,10,0.3,4000,4000}, /*第十二关 */ {40,1,1,1,1,10,0.2,10000,10000}, /*第十三关*/ {100,0,0,10,10,10,0.2,10000,10000},/*第十四关*/ {30,1,1,1,1,10,0.1,15000,15000}/*第十五关*/ }; void save(long totalscore) /*保存最高分*/ {FILE *fp; int i,j; void textprint(); if((fp=fopen("score","wb"))==NULL); else {for(i=0;i<=4;i++) {if(totalscore>famousscore[i]) {for(j=3;j>=i;j--) {famousscore[j+1]=famousscore[j]; strcpy(famousname[j+1],famousname[j]); } famousscore[i]=totalscore; textprint(10, 400,"PLEASE INPUT YOUR NAME:",2,WHITE,0,0); gets(famousname[i]); break; } } for(i=0;i<=4;i++) fwrite(&famousscore[i],sizeof(long),1,fp); for(i=0;i<=4;i++) fwrite(famousname[i],sizeof(famousname[i]),1,fp); fclose(fp); } } void load() /*读取最高分*/ {FILE *fp; int i; if((fp=fopen("score","rb"))==NULL); else {for(i=0;i<=4;i++) fread(&famousscore[i],sizeof(long),1,fp); for(i=0;i<=4;i++) fread(famousname[i],sizeof(famousname[i]),1,fp); fclose(fp); } }
char *numgochar(long x) /*把数字转化为字符串函数,用于记分*/ {char k,*a="0000000000"; int i,j=10; if(x==0) return("0"); for(i=0;x>=1;i++) {a[i]='0'+ (x % 10); x=x/10; } i--; for(j=0;j<=i/2;j++) {k=a[j]; a[j]=a[i-j]; a[i-j]=k; } a[i+1]='\0'; return(a); } void textprint(int x,int y,char *teexxt,int textsize,int color,int font,int direction) /*此函数用于在指定位置输出指定字符*/ {setcolor(color); settextstyle(font,direction,textsize); outtextxy(x,y,teexxt); } void locatprint(int i,int j) /*显示单格函数*/ {int n; if(map[i][j]==WALL) /*石头墙*/ {setfillstyle(SOLID_FILL,RED); bar(lt(j),lt(i),rb(j),rb(i)); setcolor(WHITE); line(lt(j),lt(i),lt(j)+20,lt(i)); line(lt(j),lt(i),lt(j),lt(i)+20); setcolor(BLACK); line(rb(j),rb(i),rb(j)-20,rb(i)); line(rb(j),rb(i),rb(j),rb(i)-20); } else if(map[i][j]==MUD||map[i][j]==BINDMFB||map[i][j]==BINDMFP) /*泥土墙*/ {setfillstyle(WIDE_DOT_FILL,BROWN); bar(lt(j),lt(i),rb(j),rb(i)); setcolor(WHITE); line(lt(j),lt(i),lt(j)+20,lt(i)); line(lt(j),lt(i),lt(j),lt(i)+20); setcolor(BLACK); line(rb(j),rb(i),rb(j)-20,rb(i)); line(rb(j),rb(i),rb(j),rb(i)-20); } else if(map[i][j]==BINDHB) /*玩家和地雷重叠时,即放雷瞬间*/ { setfillstyle(SOLID_FILL,BLACK); setcolor(BLACK); circle(lt(j)+10,lt(i)+10,9); floodfill(lt(j)+10,lt(i)+10,BLACK); setcolor(WHITE); arc(lt(j)+10,lt(i)+10,90,180,7); setfillstyle(SOLID_FILL,LIGHTRED); setcolor(LIGHTRED); circle(lt(j)+10,lt(i)+13,6); circle(lt(j)+10,lt(i)+4,3); floodfill(lt(j)+10,lt(i)+13,LIGHTRED); floodfill(lt(j)+10,lt(i)+4,LIGHTRED); setcolor(WHITE); arc(lt(j)+10,lt(i)+13,90,180,4); arc(lt(j)+10,lt(i)+4,90,180,2); } else if(map[i][j]==BOMB) /*地雷*/ { setfillstyle(SOLID_FILL,BLACK); setcolor(BLACK); circle(lt(j)+10,lt(i)+10,9); floodfill(lt(j)+10,lt(i)+10,BLACK); setcolor(WHITE); arc(lt(j)+10,lt(i)+10,90,180,7); } else if(map[i][j]==HERO) /*玩家*/ {setfillstyle(SOLID_FILL,LIGHTRED); setcolor(LIGHTRED); circle(lt(j)+10,lt(i)+13,6); circle(lt(j)+10,lt(i)+4,3); floodfill(lt(j)+10,lt(i)+13,LIGHTRED); floodfill(lt(j)+10,lt(i)+4,LIGHTRED); setcolor(WHITE); arc(lt(j)+10,lt(i)+13,90,180,4); arc(lt(j)+10,lt(i)+4,90,180,2); } else if(map[i][j]==EMPTY) /*空地*/ {setfillstyle(SOLID_FILL,GREEN); bar(lt(j)+1,lt(i)+1,rb(j)-1,rb(i)-1); } else if(map[i][j]==FIRE) {setfillstyle(BKSLASH_FILL,BLUE); bar(lt(j),lt(i),rb(j),rb(i)); } else if(map[i][j]==MONSTER) /*怪物*/ {setfillstyle(SOLID_FILL,BROWN); setcolor(BROWN); circle(lt(j)+10,lt(i)+10,9); floodfill(lt(j)+10,lt(i)+10,BROWN); setfillstyle(SOLID_FILL,BLACK); setcolor(BLACK); circle(lt(j)+6,lt(i)+6,2); circle(lt(j)+14,lt(i)+6,2); floodfill(lt(j)+6,lt(i)+6,BLACK); floodfill(lt(j)+14,lt(i)+6,BLACK); setfillstyle(SOLID_FILL,YELLOW); setcolor(YELLOW); circle(lt(j)+10,lt(i)+14,2); floodfill(lt(j)+10,lt(i)+14,YELLOW); setfillstyle(SOLID_FILL,WHITE); setcolor(WHITE); circle(lt(j)+6,lt(i)+6,1); circle(lt(j)+14,lt(i)+6,1); floodfill(lt(j)+6,lt(i)+6,WHITE); floodfill(lt(j)+14,lt(i)+6,WHITE); } else if(map[i][j]==FOOD_BOMB) /*布雷器*/ {for(n=1;n<=8;n++) {setcolor(n); circle(lt(j)+10,lt(i)+10,n); } } else if(map[i][j]==FOOD_POWER) /*新型炸药*/ {for(n=1;n<=8;n++) {setcolor(n); rectangle(lt(j)+10-n,lt(i)+10-n,rb(j)-10+n,rb(i)-10+n); } } } int comand(char c,int bcondition[]) /*判断玩家按键函数*/ {int t=0,i; KEYNUM++; if(c=='w'&&map[X-1][Y]!=WALL&&map[X-1][Y]!=MUD&&map[X-1][Y]!=BOMB&&map[X-1][Y]!=BINDMFB&&map[X-1][Y]!=BINDMFP) /*向上走*/ {if(map[X][Y]!=BOMB&&map[X-1][Y]!=MONSTER) {CLRP;PH;X--;REP;PH;return t;} if(map[X][Y]==BOMB&&map[X-1][Y]!=MONSTER) {CLRP;PH;LB;PH;X--;REP;PH;return t;}
if(map[X-1][Y]==MONSTER) {CLRP;PH;life=DIE;} } else if(c=='s'&&map[X+1][Y]!=WALL&&map[X+1][Y]!=MUD&&map[X+1][Y]!=BOMB&&map[X+1][Y]!=BINDMFB&&map[X+1][Y]!=BINDMFP) /*向下走*/ {if(map[X][Y]!=BOMB&&map[X+1][Y]!=MONSTER) {CLRP;PH;X++;REP;PH;return t;} if(map[X][Y]==BOMB&&map[X+1][Y]!=MONSTER) {CLRP;PH;LB;PH;X++;REP;PH;return t;} if(map[X+1][Y]==MONSTER) {CLRP;PH;life=DIE;} } else if(c=='d'&&map[X][Y+1]!=WALL&&map[X][Y+1]!=MUD&&map[X][Y+1]!=BOMB&&map[X][Y+1]!=BINDMFB&&map[X][Y+1]!=BINDMFP) /*向右走*/ {if(map[X][Y]!=BOMB&&map[X][Y+1]!=MONSTER) {CLRP;PH;Y++;REP;PH;return t;} if(map[X][Y]==BOMB&&map[X][Y+1]!=MONSTER) {CLRP;PH;LB;PH;Y++;REP;PH;return t;} if(map[X][Y+1]==MONSTER) {CLRP;PH;life=DIE;} } else if(c=='a'&&map[X][Y-1]!=WALL&&map[X][Y-1]!=MUD&&map[X][Y-1]!=BOMB&&map[X][Y-1]!=BINDMFB&&map[X][Y-1]!=BINDMFP) /*向左走*/ {if(map[X][Y]!=BOMB&&map[X][Y-1]!=MONSTER) {CLRP;PH;Y--;REP;PH;return t;} if(map[X][Y]==BOMB&&map[X][Y-1]!=MONSTER) {CLRP;PH;LB;PH;Y--;REP;PH;return t;} if(map[X][Y-1]==MONSTER) {CLRP;PH;life=DIE;} } else if(c==27) /*退出*/ t=EXIT; else if(c==' ') /*放雷*/ for(i=0;i<NUM;i++) if(bcondition[i]==NOLAY) {XB[i]=X;YB[i]=Y;map[X][Y]=BINDHB;PH;map[X][Y]=BOMB;bcondition[i]=LAY; break; } return t; }